diff options
author | Michael Haggerty <mhagger@alum.mit.edu> | 2017-04-16 08:41:39 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-04-17 06:32:46 +0200 |
commit | 059ae35a4871428f49500a22fd0b3eb6e1b424c3 (patch) | |
tree | 4adad905d2ba47efd2a9274a9219ad21dec21c9c /refs/ref-cache.c | |
parent | get_loose_ref_cache(): new function (diff) | |
download | git-059ae35a4871428f49500a22fd0b3eb6e1b424c3.tar.xz git-059ae35a4871428f49500a22fd0b3eb6e1b424c3.zip |
cache_ref_iterator_begin(): make function smarter
Change `cache_ref_iterator_begin()` to take two new arguments:
* `prefix` -- to iterate only over references with the specified
prefix.
* `prime_dir` -- to "prime" (i.e., pre-load) the cache before starting
the iteration.
The new functionality makes it possible for
`files_ref_iterator_begin()` to be made more ignorant of the internals
of `ref_cache`, and `find_containing_dir()` and `prime_ref_dir()` to
be made private.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs/ref-cache.c')
-rw-r--r-- | refs/ref-cache.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/refs/ref-cache.c b/refs/ref-cache.c index 38d4c31985..b3a30350d7 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -177,8 +177,17 @@ static struct ref_dir *search_for_subdir(struct ref_dir *dir, return get_ref_dir(entry); } -struct ref_dir *find_containing_dir(struct ref_dir *dir, - const char *refname, int mkdir) +/* + * If refname is a reference name, find the ref_dir within the dir + * tree that should hold refname. If refname is a directory name + * (i.e., it ends in '/'), then return that ref_dir itself. dir must + * represent the top-level directory and must already be complete. + * Sort ref_dirs and recurse into subdirectories as necessary. If + * mkdir is set, then create any missing directories; otherwise, + * return NULL if the desired directory cannot be found. + */ +static struct ref_dir *find_containing_dir(struct ref_dir *dir, + const char *refname, int mkdir) { const char *slash; for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) { @@ -328,7 +337,11 @@ int do_for_each_entry_in_dir(struct ref_dir *dir, return 0; } -void prime_ref_dir(struct ref_dir *dir) +/* + * Load all of the refs from `dir` (recursively) into our in-memory + * cache. + */ +static void prime_ref_dir(struct ref_dir *dir) { /* * The hard work of loading loose refs is done by get_ref_dir(), so we @@ -494,12 +507,25 @@ static struct ref_iterator_vtable cache_ref_iterator_vtable = { cache_ref_iterator_abort }; -struct ref_iterator *cache_ref_iterator_begin(struct ref_dir *dir) +struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache, + const char *prefix, + int prime_dir) { + struct ref_dir *dir; struct cache_ref_iterator *iter; struct ref_iterator *ref_iterator; struct cache_ref_iterator_level *level; + dir = get_ref_dir(cache->root); + if (prefix && *prefix) + dir = find_containing_dir(dir, prefix, 0); + if (!dir) + /* There's nothing to iterate over. */ + return empty_ref_iterator_begin(); + + if (prime_dir) + prime_ref_dir(dir); + iter = xcalloc(1, sizeof(*iter)); ref_iterator = &iter->base; base_ref_iterator_init(ref_iterator, &cache_ref_iterator_vtable); @@ -510,5 +536,9 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_dir *dir) level->index = -1; level->dir = dir; + if (prefix && *prefix) + ref_iterator = prefix_ref_iterator_begin(ref_iterator, + prefix, 0); + return ref_iterator; } |