Skip to content

Commit 059ae35

Browse files
mhaggergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a714b19 commit 059ae35

File tree

3 files changed

+56
-53
lines changed

3 files changed

+56
-53
lines changed

refs/files-backend.c

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,6 @@ static struct ref_iterator *files_ref_iterator_begin(
10821082
const char *prefix, unsigned int flags)
10831083
{
10841084
struct files_ref_store *refs;
1085-
struct ref_dir *loose_dir, *packed_dir;
10861085
struct ref_iterator *loose_iter, *packed_iter;
10871086
struct files_ref_iterator *iter;
10881087
struct ref_iterator *ref_iterator;
@@ -1106,41 +1105,24 @@ static struct ref_iterator *files_ref_iterator_begin(
11061105
* condition if loose refs are migrated to the packed-refs
11071106
* file by a simultaneous process, but our in-memory view is
11081107
* from before the migration. We ensure this as follows:
1109-
* First, we call prime_ref_dir(), which pre-reads the loose
1110-
* references for the subtree into the cache. (If they've
1111-
* already been read, that's OK; we only need to guarantee
1112-
* that they're read before the packed refs, not *how much*
1113-
* before.) After that, we call get_packed_ref_cache(), which
1114-
* internally checks whether the packed-ref cache is up to
1115-
* date with what is on disk, and re-reads it if not.
1108+
* First, we call start the loose refs iteration with its
1109+
* `prime_ref` argument set to true. This causes the loose
1110+
* references in the subtree to be pre-read into the cache.
1111+
* (If they've already been read, that's OK; we only need to
1112+
* guarantee that they're read before the packed refs, not
1113+
* *how much* before.) After that, we call
1114+
* get_packed_ref_cache(), which internally checks whether the
1115+
* packed-ref cache is up to date with what is on disk, and
1116+
* re-reads it if not.
11161117
*/
11171118

1118-
loose_dir = get_loose_ref_dir(refs);
1119-
1120-
if (prefix && *prefix)
1121-
loose_dir = find_containing_dir(loose_dir, prefix, 0);
1122-
1123-
if (loose_dir) {
1124-
prime_ref_dir(loose_dir);
1125-
loose_iter = cache_ref_iterator_begin(loose_dir);
1126-
} else {
1127-
/* There's nothing to iterate over. */
1128-
loose_iter = empty_ref_iterator_begin();
1129-
}
1119+
loose_iter = cache_ref_iterator_begin(get_loose_ref_cache(refs),
1120+
prefix, 1);
11301121

11311122
iter->packed_ref_cache = get_packed_ref_cache(refs);
11321123
acquire_packed_ref_cache(iter->packed_ref_cache);
1133-
packed_dir = get_packed_ref_dir(iter->packed_ref_cache);
1134-
1135-
if (prefix && *prefix)
1136-
packed_dir = find_containing_dir(packed_dir, prefix, 0);
1137-
1138-
if (packed_dir) {
1139-
packed_iter = cache_ref_iterator_begin(packed_dir);
1140-
} else {
1141-
/* There's nothing to iterate over. */
1142-
packed_iter = empty_ref_iterator_begin();
1143-
}
1124+
packed_iter = cache_ref_iterator_begin(iter->packed_ref_cache->cache,
1125+
prefix, 0);
11441126

11451127
iter->iter0 = overlay_ref_iterator_begin(loose_iter, packed_iter);
11461128
iter->flags = flags;

refs/ref-cache.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,17 @@ static struct ref_dir *search_for_subdir(struct ref_dir *dir,
177177
return get_ref_dir(entry);
178178
}
179179

180-
struct ref_dir *find_containing_dir(struct ref_dir *dir,
181-
const char *refname, int mkdir)
180+
/*
181+
* If refname is a reference name, find the ref_dir within the dir
182+
* tree that should hold refname. If refname is a directory name
183+
* (i.e., it ends in '/'), then return that ref_dir itself. dir must
184+
* represent the top-level directory and must already be complete.
185+
* Sort ref_dirs and recurse into subdirectories as necessary. If
186+
* mkdir is set, then create any missing directories; otherwise,
187+
* return NULL if the desired directory cannot be found.
188+
*/
189+
static struct ref_dir *find_containing_dir(struct ref_dir *dir,
190+
const char *refname, int mkdir)
182191
{
183192
const char *slash;
184193
for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {
@@ -328,7 +337,11 @@ int do_for_each_entry_in_dir(struct ref_dir *dir,
328337
return 0;
329338
}
330339

331-
void prime_ref_dir(struct ref_dir *dir)
340+
/*
341+
* Load all of the refs from `dir` (recursively) into our in-memory
342+
* cache.
343+
*/
344+
static void prime_ref_dir(struct ref_dir *dir)
332345
{
333346
/*
334347
* 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 = {
494507
cache_ref_iterator_abort
495508
};
496509

497-
struct ref_iterator *cache_ref_iterator_begin(struct ref_dir *dir)
510+
struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache,
511+
const char *prefix,
512+
int prime_dir)
498513
{
514+
struct ref_dir *dir;
499515
struct cache_ref_iterator *iter;
500516
struct ref_iterator *ref_iterator;
501517
struct cache_ref_iterator_level *level;
502518

519+
dir = get_ref_dir(cache->root);
520+
if (prefix && *prefix)
521+
dir = find_containing_dir(dir, prefix, 0);
522+
if (!dir)
523+
/* There's nothing to iterate over. */
524+
return empty_ref_iterator_begin();
525+
526+
if (prime_dir)
527+
prime_ref_dir(dir);
528+
503529
iter = xcalloc(1, sizeof(*iter));
504530
ref_iterator = &iter->base;
505531
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)
510536
level->index = -1;
511537
level->dir = dir;
512538

539+
if (prefix && *prefix)
540+
ref_iterator = prefix_ref_iterator_begin(ref_iterator,
541+
prefix, 0);
542+
513543
return ref_iterator;
514544
}

refs/ref-cache.h

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -234,26 +234,22 @@ int remove_entry_from_dir(struct ref_dir *dir, const char *refname);
234234
*/
235235
int add_ref_entry(struct ref_dir *dir, struct ref_entry *ref);
236236

237-
/*
238-
* If refname is a reference name, find the ref_dir within the dir
239-
* tree that should hold refname. If refname is a directory name
240-
* (i.e., it ends in '/'), then return that ref_dir itself. dir must
241-
* represent the top-level directory and must already be complete.
242-
* Sort ref_dirs and recurse into subdirectories as necessary. If
243-
* mkdir is set, then create any missing directories; otherwise,
244-
* return NULL if the desired directory cannot be found.
245-
*/
246-
struct ref_dir *find_containing_dir(struct ref_dir *dir,
247-
const char *refname, int mkdir);
248-
249237
/*
250238
* Find the value entry with the given name in dir, sorting ref_dirs
251239
* and recursing into subdirectories as necessary. If the name is not
252240
* found or it corresponds to a directory entry, return NULL.
253241
*/
254242
struct ref_entry *find_ref_entry(struct ref_dir *dir, const char *refname);
255243

256-
struct ref_iterator *cache_ref_iterator_begin(struct ref_dir *dir);
244+
/*
245+
* Start iterating over references in `cache`. If `prefix` is
246+
* specified, only include references whose names start with that
247+
* prefix. If `prime_dir` is true, then fill any incomplete
248+
* directories before beginning the iteration.
249+
*/
250+
struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache,
251+
const char *prefix,
252+
int prime_dir);
257253

258254
typedef int each_ref_entry_fn(struct ref_entry *entry, void *cb_data);
259255

@@ -279,9 +275,4 @@ int do_for_each_entry_in_dir(struct ref_dir *dir,
279275
*/
280276
enum peel_status peel_entry(struct ref_entry *entry, int repeel);
281277

282-
/*
283-
* Load all of the refs from `dir` into our in-memory cache.
284-
*/
285-
void prime_ref_dir(struct ref_dir *dir);
286-
287278
#endif /* REFS_REF_CACHE_H */

0 commit comments

Comments
 (0)