]> git.ipfire.org Git - thirdparty/git.git/commitdiff
cache-tree: implement cache_tree_find_path()
authorDerrick Stolee <dstolee@microsoft.com>
Mon, 23 May 2022 13:48:41 +0000 (13:48 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 23 May 2022 18:08:21 +0000 (11:08 -0700)
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>
cache-tree.c
cache-tree.h

index 6752f69d515e12f7bd8c98ac2e27548b68da46d5..f42db920d1092d5c992b63abfed4e0ea922e1bde 100644 (file)
@@ -100,6 +100,33 @@ struct cache_tree_sub *cache_tree_sub(struct cache_tree *it, const char *path)
        return find_subtree(it, path, pathlen, 1);
 }
 
+struct cache_tree *cache_tree_find_path(struct cache_tree *it, const char *path)
+{
+       const char *slash;
+       int namelen;
+       struct cache_tree_sub it_sub = {
+               .cache_tree = it,
+       };
+       struct cache_tree_sub *down = &it_sub;
+
+       while (down) {
+               slash = strchrnul(path, '/');
+               namelen = slash - path;
+               down->cache_tree->entry_count = -1;
+               if (!*slash) {
+                       int pos;
+                       pos = cache_tree_subtree_pos(down->cache_tree, path, namelen);
+                       if (0 <= pos)
+                               return down->cache_tree->down[pos]->cache_tree;
+                       return NULL;
+               }
+               down = find_subtree(it, path, namelen, 0);
+               path = slash + 1;
+       }
+
+       return NULL;
+}
+
 static int do_invalidate_path(struct cache_tree *it, const char *path)
 {
        /* a/b/c
index 8efeccebfc9f0bf8c9cfda1aa4ac531108b52650..f75f8e74dcdb86131d90a83b7d8ebd9861839fd2 100644 (file)
@@ -29,6 +29,8 @@ struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *);
 
 int cache_tree_subtree_pos(struct cache_tree *it, const char *path, int pathlen);
 
+struct cache_tree *cache_tree_find_path(struct cache_tree *it, const char *path);
+
 void cache_tree_write(struct strbuf *, struct cache_tree *root);
 struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);