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>
Michael Haggerty committed
Apr 16, 2017 at 08:41 UTC
059ae35a4871428f49500a22fd0b3eb6e1b424c3
3 files changed
+56
-53
refs/files-backend.c
+13
-31
@@ -1082,7 +1082,6 @@ static struct ref_iterator *files_ref_iterator_begin(
1082
const char *prefix, unsigned int flags)
1083
{
1084
struct files_ref_store *refs;
1085
- struct ref_dir *loose_dir, *packed_dir;
1085
struct ref_iterator *loose_iter, *packed_iter;
1086
struct files_ref_iterator *iter;
1087
struct ref_iterator *ref_iterator;
@@ -1106,41 +1105,24 @@ static struct ref_iterator *files_ref_iterator_begin(
1105
* condition if loose refs are migrated to the packed-refs
1106
* file by a simultaneous process, but our in-memory view is
1107
* 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.
1117
*/
1118
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);
1121
1122
iter->packed_ref_cache = get_packed_ref_cache(refs);
1123
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);
1126
1127
iter->iter0 = overlay_ref_iterator_begin(loose_iter, packed_iter);
1128
iter->flags = flags;
refs/ref-cache.c
+34
-4
@@ -177,8 +177,17 @@ static struct ref_dir *search_for_subdir(struct ref_dir *dir,
177
return get_ref_dir(entry);
178
}
179
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)
191
{
192
const char *slash;
193
for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {
@@ -328,7 +337,11 @@ int do_for_each_entry_in_dir(struct ref_dir *dir,
337
return 0;
338
}
339
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)
345
{
346
/*
347
* 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 = {
507
cache_ref_iterator_abort
508
};
509
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)
513
{
514
+ struct ref_dir *dir;
515
struct cache_ref_iterator *iter;
516
struct ref_iterator *ref_iterator;
517
struct cache_ref_iterator_level *level;
518
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
+
529
iter = xcalloc(1, sizeof(*iter));
530
ref_iterator = &iter->base;
531
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)
536
level->index = -1;
537
level->dir = dir;
538
539
+ if (prefix && *prefix)
540
+ ref_iterator = prefix_ref_iterator_begin(ref_iterator,
541
+ prefix, 0);
542
+
543
return ref_iterator;
544
}
refs/ref-cache.h
+9
-18
@@ -234,18 +234,6 @@ int remove_entry_from_dir(struct ref_dir *dir, const char *refname);
234
*/
235
int add_ref_entry(struct ref_dir *dir, struct ref_entry *ref);
236
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
-
237
/*
238
* Find the value entry with the given name in dir, sorting ref_dirs
239
* and recursing into subdirectories as necessary. If the name is not
@@ -253,7 +241,15 @@ struct ref_dir *find_containing_dir(struct ref_dir *dir,
241
*/
242
struct ref_entry *find_ref_entry(struct ref_dir *dir, const char *refname);
243
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);
253
254
typedef int each_ref_entry_fn(struct ref_entry *entry, void *cb_data);
255
@@ -279,9 +275,4 @@ int do_for_each_entry_in_dir(struct ref_dir *dir,
275
*/
276
enum peel_status peel_entry(struct ref_entry *entry, int repeel);
277
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
-
278
#endif /* REFS_REF_CACHE_H */