summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2007-03-21 12:34:46 -0700
committerJunio C Hamano <junkio@cox.net>2007-03-22 00:34:39 -0700
commitccc744abbb27d3766175aee971991bc0f1fd4f00 (patch)
treea02363594bfc0356104b695f8f69009a8db7ee0f
parent7d2f667b12334cea68087eb7da717efd7b3d80f6 (diff)
downloadgit-ccc744abbb27d3766175aee971991bc0f1fd4f00.tar.gz
tree-diff: avoid strncmp()
If we already know that some of the pathspecs can match later entries in the tree we are looking at, we do not have to do more expensive strncmp() upfront before comparing the length of the match pattern and the path, as a path longer than the match pattern will not match it, and a path shorter than the match pattern will match only if the path is a directory-component wise prefix of the match pattern. Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r--tree-diff.c60
1 files changed, 37 insertions, 23 deletions
diff --git a/tree-diff.c b/tree-diff.c
index 35af569fb8..15fd665fb8 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -93,7 +93,7 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int
for (i = 0; i < opt->nr_paths; i++) {
const char *match = opt->paths[i];
int matchlen = opt->pathlens[i];
- int m;
+ int m = -1; /* signals that we haven't called strncmp() */
if (baselen >= matchlen) {
/* If it doesn't match, move along... */
@@ -111,29 +111,36 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int
match += baselen;
matchlen -= baselen;
- /*
- * Does match sort strictly earlier than path with their
- * common parts?
- */
- m = strncmp(match, path,
- (matchlen < pathlen) ? matchlen : pathlen);
- if (m < 0)
- continue;
+ if (never_interesting) {
+ /*
+ * We have not seen any match that sorts later
+ * than the current path.
+ */
+
+ /*
+ * Does match sort strictly earlier than path
+ * with their common parts?
+ */
+ m = strncmp(match, path,
+ (matchlen < pathlen) ? matchlen : pathlen);
+ if (m < 0)
+ continue;
- /*
- * If we come here even once, that means there is at
- * least one pathspec that would sort equal to or
- * later than the path we are currently looking at.
- * In other words, if we have never reached this point
- * after iterating all pathspecs, it means all
- * pathspecs are either outside of base, or inside the
- * base but sorts strictly earlier than the current
- * one. In either case, they will never match the
- * subsequent entries. In such a case, we initialized
- * the variable to -1 and that is what will be
- * returned, allowing the caller to terminate early.
- */
- never_interesting = 0;
+ /*
+ * If we come here even once, that means there is at
+ * least one pathspec that would sort equal to or
+ * later than the path we are currently looking at.
+ * In other words, if we have never reached this point
+ * after iterating all pathspecs, it means all
+ * pathspecs are either outside of base, or inside the
+ * base but sorts strictly earlier than the current
+ * one. In either case, they will never match the
+ * subsequent entries. In such a case, we initialized
+ * the variable to -1 and that is what will be
+ * returned, allowing the caller to terminate early.
+ */
+ never_interesting = 0;
+ }
if (pathlen > matchlen)
continue;
@@ -145,6 +152,13 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int
continue;
}
+ if (m == -1)
+ /*
+ * we cheated and did not do strncmp(), so we do
+ * that here.
+ */
+ m = strncmp(match, path, pathlen);
+
/*
* If common part matched earlier then it is a hit,
* because we rejected the case where path is not a