cache-tree: implement cache_tree_find_path()

Given a 'struct cache_tree', it may be beneficial to navigate directly to a node within that corresponds to a given path name. Create cache_tree_find_path() for this function. It returns NULL when no such path exists. The implementation is adapted from do_invalidate_path() which does a similar search but also modifies the nodes it finds along the way. The method could be implemented simply using tail-recursion, but this while loop does the same thing. This new method is not currently used, but will be in an upcoming change. Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed May 23, 2022 at 13:48 UTC 080ab56a46ad65068201a768a04464341117fe81
2 files changed +29
cache-tree.c
+27
@@ -100,6 +100,33 @@ struct cache_tree_sub *cache_tree_sub(struct cache_tree *it, const char *path)
100 return find_subtree(it, path, pathlen, 1);
101 }
102
103 +struct cache_tree *cache_tree_find_path(struct cache_tree *it, const char *path)
104 +{
105 + const char *slash;
106 + int namelen;
107 + struct cache_tree_sub it_sub = {
108 + .cache_tree = it,
109 + };
110 + struct cache_tree_sub *down = &it_sub;
111 +
112 + while (down) {
113 + slash = strchrnul(path, '/');
114 + namelen = slash - path;
115 + down->cache_tree->entry_count = -1;
116 + if (!*slash) {
117 + int pos;
118 + pos = cache_tree_subtree_pos(down->cache_tree, path, namelen);
119 + if (0 <= pos)
120 + return down->cache_tree->down[pos]->cache_tree;
121 + return NULL;
122 + }
123 + down = find_subtree(it, path, namelen, 0);
124 + path = slash + 1;
125 + }
126 +
127 + return NULL;
128 +}
129 +
130 static int do_invalidate_path(struct cache_tree *it, const char *path)
131 {
132 /* a/b/c
cache-tree.h
+2
@@ -29,6 +29,8 @@ struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *);
29
30 int cache_tree_subtree_pos(struct cache_tree *it, const char *path, int pathlen);
31
32 +struct cache_tree *cache_tree_find_path(struct cache_tree *it, const char *path);
33 +
34 void cache_tree_write(struct strbuf *, struct cache_tree *root);
35 struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
36