Skip to content

Commit

Permalink
dir: add path_matches_cone_mode_pattern_list()
Browse files Browse the repository at this point in the history
When matching against a generic pattern list, the 'basename' is
important for some patterns. However, it and the 'dtype' parameter are
irrelevant for cone mode sparse-checkout patterns. If we know that we
are working with cone mode patterns from the start, then we can speed up
the pattern check slightly by not computing the 'basename'.

In many existing consumers, the 'basename' is already known from
context, but some new consumers we compute this on-demand. A future
change will add more calls that do not have the 'basename' from context
and would need to compute it for many cache entries in a tight loop.
Avoid this problem by creating the new
path_matches_cone_mode_pattern_list() method.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
  • Loading branch information
derrickstolee authored and dscho committed Jun 17, 2022
1 parent e016679 commit 5ff0dd6
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 34 deletions.
78 changes: 44 additions & 34 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1400,46 +1400,16 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname
return res;
}

/*
* Scan the list of patterns to determine if the ordered list
* of patterns matches on 'pathname'.
*
* Return 1 for a match, 0 for not matched and -1 for undecided.
*/
enum pattern_match_result path_matches_pattern_list(
enum pattern_match_result path_matches_cone_mode_pattern_list(
const char *pathname, int pathlen,
const char *basename, int *dtype,
struct pattern_list *pl,
struct index_state *istate)
struct pattern_list *pl)
{
struct path_pattern *pattern;
struct strbuf parent_pathname = STRBUF_INIT;
int result = NOT_MATCHED;
size_t slash_pos;

/*
* The virtual file system data is used to prevent git from traversing
* any part of the tree that is not in the virtual file system. Return
* 1 to exclude the entry if it is not found in the virtual file system,
* else fall through to the regular excludes logic as it may further exclude.
*/
if (*dtype == DT_UNKNOWN)
*dtype = resolve_dtype(DT_UNKNOWN, istate, pathname, pathlen);
if (is_excluded_from_virtualfilesystem(pathname, pathlen, *dtype) > 0)
return 1;

if (!pl->use_cone_patterns) {
pattern = last_matching_pattern_from_list(pathname, pathlen, basename,
dtype, pl, istate);
if (pattern) {
if (pattern->flags & PATTERN_FLAG_NEGATIVE)
return NOT_MATCHED;
else
return MATCHED;
}

return UNDECIDED;
}
if (!pl->use_cone_patterns)
BUG("path_matches_cone_mode_pattern_list requires cone mode patterns");

if (pl->full_cone)
return MATCHED;
Expand Down Expand Up @@ -1492,6 +1462,46 @@ enum pattern_match_result path_matches_pattern_list(
return result;
}

/*
* Scan the list of patterns to determine if the ordered list
* of patterns matches on 'pathname'.
*
* Return 1 for a match, 0 for not matched and -1 for undecided.
*/
enum pattern_match_result path_matches_pattern_list(
const char *pathname, int pathlen,
const char *basename, int *dtype,
struct pattern_list *pl,
struct index_state *istate)
{
/*
* The virtual file system data is used to prevent git from traversing
* any part of the tree that is not in the virtual file system. Return
* 1 to exclude the entry if it is not found in the virtual file system,
* else fall through to the regular excludes logic as it may further exclude.
*/
if (*dtype == DT_UNKNOWN)
*dtype = resolve_dtype(DT_UNKNOWN, istate, pathname, pathlen);
if (is_excluded_from_virtualfilesystem(pathname, pathlen, *dtype) > 0)
return 1;

if (!pl->use_cone_patterns) {
struct path_pattern *pattern = last_matching_pattern_from_list(
pathname, pathlen, basename,
dtype, pl, istate);
if (pattern) {
if (pattern->flags & PATTERN_FLAG_NEGATIVE)
return NOT_MATCHED;
else
return MATCHED;
}

return UNDECIDED;
}

return path_matches_cone_mode_pattern_list(pathname, pathlen, pl);
}

int init_sparse_checkout_patterns(struct index_state *istate)
{
if (!core_apply_sparse_checkout)
Expand Down
9 changes: 9 additions & 0 deletions dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,15 @@ enum pattern_match_result {
MATCHED_RECURSIVE = 2,
};

/*
* Test if a given path is contained in the given pattern list.
*
* The given pattern list _must_ use cone mode patterns.
*/
enum pattern_match_result path_matches_cone_mode_pattern_list(
const char *pathname, int pathlen,
struct pattern_list *pl);

/*
* Scan the list of patterns to determine if the ordered list
* of patterns matches on 'pathname'.
Expand Down

0 comments on commit 5ff0dd6

Please sign in to comment.