Commit 1fa17b5c92cb92a2785fba403b87525169b205c0

Russell Belfer 2014-03-14T22:01:30

Minor tree cache speedups While I was looking at the conflict cleanup code, I looked over at the tree cache code, since we clear the tree cache for each entry that gets removed and there is some redundancy there. I made some small tweaks to avoid extra calls to strchr and strlen in a few circumstances.

diff --git a/src/tree-cache.c b/src/tree-cache.c
index 1d39971..49afd6e 100644
--- a/src/tree-cache.c
+++ b/src/tree-cache.c
@@ -7,23 +7,16 @@
 
 #include "tree-cache.h"
 
-static git_tree_cache *find_child(const git_tree_cache *tree, const char *path)
+static git_tree_cache *find_child(
+	const git_tree_cache *tree, const char *path, const char *end)
 {
-	size_t i, dirlen;
-	const char *end;
-
-	end = strchr(path, '/');
-	if (end == NULL) {
-		end = strrchr(path, '\0');
-	}
-
-	dirlen = end - path;
+	size_t i, dirlen = end ? (size_t)(end - path) : strlen(path);
 
 	for (i = 0; i < tree->children_count; ++i) {
-		const char *childname = tree->children[i]->name;
+		git_tree_cache *child = tree->children[i];
 
-		if (strlen(childname) == dirlen && !memcmp(path, childname, dirlen))
-			return tree->children[i];
+		if (child->namelen == dirlen && !memcmp(path, child->name, dirlen))
+			return child;
 	}
 
 	return NULL;
@@ -44,7 +37,7 @@ void git_tree_cache_invalidate_path(git_tree_cache *tree, const char *path)
 		if (end == NULL) /* End of path */
 			break;
 
-		tree = find_child(tree, ptr);
+		tree = find_child(tree, ptr, end);
 		if (tree == NULL) /* We don't have that tree */
 			return;
 
@@ -64,10 +57,9 @@ const git_tree_cache *git_tree_cache_get(const git_tree_cache *tree, const char 
 	while (1) {
 		end = strchr(ptr, '/');
 
-		tree = find_child(tree, ptr);
-		if (tree == NULL) { /* Can't find it */
+		tree = find_child(tree, ptr, end);
+		if (tree == NULL) /* Can't find it */
 			return NULL;
-		}
 
 		if (end == NULL || *end + 1 == '\0')
 			return tree;
@@ -100,6 +92,7 @@ static int read_tree_internal(git_tree_cache **out,
 	tree->parent = parent;
 
 	/* NUL-terminated tree name */
+	tree->namelen = name_len;
 	memcpy(tree->name, name_start, name_len);
 	tree->name[name_len] = '\0';
 
diff --git a/src/tree-cache.h b/src/tree-cache.h
index 805483a..90c82db 100644
--- a/src/tree-cache.h
+++ b/src/tree-cache.h
@@ -18,6 +18,7 @@ struct git_tree_cache {
 
 	ssize_t entries;
 	git_oid oid;
+	size_t namelen;
 	char name[GIT_FLEX_ARRAY];
 };