Skip to content

Commit 97b9575

Browse files
committed
dir: add path_matches_cone_mode_pattern_list()
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 <[email protected]>
1 parent d80627e commit 97b9575

File tree

2 files changed

+53
-34
lines changed

2 files changed

+53
-34
lines changed

dir.c

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,46 +1402,16 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname
14021402
return res;
14031403
}
14041404

1405-
/*
1406-
* Scan the list of patterns to determine if the ordered list
1407-
* of patterns matches on 'pathname'.
1408-
*
1409-
* Return 1 for a match, 0 for not matched and -1 for undecided.
1410-
*/
1411-
enum pattern_match_result path_matches_pattern_list(
1405+
enum pattern_match_result path_matches_cone_mode_pattern_list(
14121406
const char *pathname, int pathlen,
1413-
const char *basename, int *dtype,
1414-
struct pattern_list *pl,
1415-
struct index_state *istate)
1407+
struct pattern_list *pl)
14161408
{
1417-
struct path_pattern *pattern;
14181409
struct strbuf parent_pathname = STRBUF_INIT;
14191410
int result = NOT_MATCHED;
14201411
size_t slash_pos;
14211412

1422-
/*
1423-
* The virtual file system data is used to prevent git from traversing
1424-
* any part of the tree that is not in the virtual file system. Return
1425-
* 1 to exclude the entry if it is not found in the virtual file system,
1426-
* else fall through to the regular excludes logic as it may further exclude.
1427-
*/
1428-
if (*dtype == DT_UNKNOWN)
1429-
*dtype = resolve_dtype(DT_UNKNOWN, istate, pathname, pathlen);
1430-
if (is_excluded_from_virtualfilesystem(pathname, pathlen, *dtype) > 0)
1431-
return 1;
1432-
1433-
if (!pl->use_cone_patterns) {
1434-
pattern = last_matching_pattern_from_list(pathname, pathlen, basename,
1435-
dtype, pl, istate);
1436-
if (pattern) {
1437-
if (pattern->flags & PATTERN_FLAG_NEGATIVE)
1438-
return NOT_MATCHED;
1439-
else
1440-
return MATCHED;
1441-
}
1442-
1443-
return UNDECIDED;
1444-
}
1413+
if (!pl->use_cone_patterns)
1414+
BUG("path_matches_cone_mode_pattern_list requires cone mode patterns");
14451415

14461416
if (pl->full_cone)
14471417
return MATCHED;
@@ -1494,6 +1464,46 @@ enum pattern_match_result path_matches_pattern_list(
14941464
return result;
14951465
}
14961466

1467+
/*
1468+
* Scan the list of patterns to determine if the ordered list
1469+
* of patterns matches on 'pathname'.
1470+
*
1471+
* Return 1 for a match, 0 for not matched and -1 for undecided.
1472+
*/
1473+
enum pattern_match_result path_matches_pattern_list(
1474+
const char *pathname, int pathlen,
1475+
const char *basename, int *dtype,
1476+
struct pattern_list *pl,
1477+
struct index_state *istate)
1478+
{
1479+
/*
1480+
* The virtual file system data is used to prevent git from traversing
1481+
* any part of the tree that is not in the virtual file system. Return
1482+
* 1 to exclude the entry if it is not found in the virtual file system,
1483+
* else fall through to the regular excludes logic as it may further exclude.
1484+
*/
1485+
if (*dtype == DT_UNKNOWN)
1486+
*dtype = resolve_dtype(DT_UNKNOWN, istate, pathname, pathlen);
1487+
if (is_excluded_from_virtualfilesystem(pathname, pathlen, *dtype) > 0)
1488+
return 1;
1489+
1490+
if (!pl->use_cone_patterns) {
1491+
struct path_pattern *pattern = last_matching_pattern_from_list(
1492+
pathname, pathlen, basename,
1493+
dtype, pl, istate);
1494+
if (pattern) {
1495+
if (pattern->flags & PATTERN_FLAG_NEGATIVE)
1496+
return NOT_MATCHED;
1497+
else
1498+
return MATCHED;
1499+
}
1500+
1501+
return UNDECIDED;
1502+
}
1503+
1504+
return path_matches_cone_mode_pattern_list(pathname, pathlen, pl);
1505+
}
1506+
14971507
int init_sparse_checkout_patterns(struct index_state *istate)
14981508
{
14991509
if (!core_apply_sparse_checkout ||

dir.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,15 @@ enum pattern_match_result {
383383
MATCHED_RECURSIVE = 2,
384384
};
385385

386+
/*
387+
* Test if a given path is contained in the given pattern list.
388+
*
389+
* The given pattern list _must_ use cone mode patterns.
390+
*/
391+
enum pattern_match_result path_matches_cone_mode_pattern_list(
392+
const char *pathname, int pathlen,
393+
struct pattern_list *pl);
394+
386395
/*
387396
* Scan the list of patterns to determine if the ordered list
388397
* of patterns matches on 'pathname'.

0 commit comments

Comments
 (0)