refs: always treat iterators as ordered

In the preceding commit we have converted the reflog iterator of the "files" backend to be ordered, which was the only remaining ref iterator that wasn't ordered. Refactor the ref iterator infrastructure so that we always assume iterators to be ordered, thus simplifying the code. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Feb 21, 2024 at 13:37 UTC 5e01d838412d6679c40c929bbb2591669ae393d4
8 files changed +20 -50
refs.c
-4
@@ -1594,10 +1594,6 @@ struct ref_iterator *refs_ref_iterator_begin(
1594 if (trim)
1595 iter = prefix_ref_iterator_begin(iter, "", trim);
1596
1597 - /* Sanity check for subclasses: */
1598 - if (!iter->ordered)
1599 - BUG("reference iterator is not ordered");
1600 -
1597 return iter;
1598 }
1599
refs/debug.c
+1 -2
@@ -181,7 +181,6 @@ static int debug_ref_iterator_advance(struct ref_iterator *ref_iterator)
181 trace_printf_key(&trace_refs, "iterator_advance: %s (0)\n",
182 diter->iter->refname);
183
184 - diter->base.ordered = diter->iter->ordered;
184 diter->base.refname = diter->iter->refname;
185 diter->base.oid = diter->iter->oid;
186 diter->base.flags = diter->iter->flags;
@@ -222,7 +221,7 @@ debug_ref_iterator_begin(struct ref_store *ref_store, const char *prefix,
221 drefs->refs->be->iterator_begin(drefs->refs, prefix,
222 exclude_patterns, flags);
223 struct debug_ref_iterator *diter = xcalloc(1, sizeof(*diter));
225 - base_ref_iterator_init(&diter->base, &debug_ref_iterator_vtable, 1);
224 + base_ref_iterator_init(&diter->base, &debug_ref_iterator_vtable);
225 diter->iter = res;
226 trace_printf_key(&trace_refs, "ref_iterator_begin: \"%s\" (0x%x)\n",
227 prefix, flags);
refs/files-backend.c
+3 -4
@@ -879,8 +879,7 @@ static struct ref_iterator *files_ref_iterator_begin(
879
880 CALLOC_ARRAY(iter, 1);
881 ref_iterator = &iter->base;
882 - base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable,
883 - overlay_iter->ordered);
882 + base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable);
883 iter->iter0 = overlay_iter;
884 iter->repo = ref_store->repo;
885 iter->flags = flags;
@@ -2202,7 +2201,7 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store,
2201 CALLOC_ARRAY(iter, 1);
2202 ref_iterator = &iter->base;
2203
2205 - base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable, 1);
2204 + base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable);
2205 iter->dir_iterator = diter;
2206 iter->ref_store = ref_store;
2207 strbuf_release(&sb);
@@ -2220,7 +2219,7 @@ static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_st
2219 return reflog_iterator_begin(ref_store, refs->gitcommondir);
2220 } else {
2221 return merge_ref_iterator_begin(
2223 - 1, reflog_iterator_begin(ref_store, refs->base.gitdir),
2222 + reflog_iterator_begin(ref_store, refs->base.gitdir),
2223 reflog_iterator_begin(ref_store, refs->gitcommondir),
2224 ref_iterator_select, refs);
2225 }
refs/iterator.c
+8 -18
@@ -25,11 +25,9 @@ int ref_iterator_abort(struct ref_iterator *ref_iterator)
25 }
26
27 void base_ref_iterator_init(struct ref_iterator *iter,
28 - struct ref_iterator_vtable *vtable,
29 - int ordered)
28 + struct ref_iterator_vtable *vtable)
29 {
30 iter->vtable = vtable;
32 - iter->ordered = !!ordered;
31 iter->refname = NULL;
32 iter->oid = NULL;
33 iter->flags = 0;
@@ -74,7 +72,7 @@ struct ref_iterator *empty_ref_iterator_begin(void)
72 struct empty_ref_iterator *iter = xcalloc(1, sizeof(*iter));
73 struct ref_iterator *ref_iterator = &iter->base;
74
77 - base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable, 1);
75 + base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable);
76 return ref_iterator;
77 }
78
@@ -250,7 +248,6 @@ static struct ref_iterator_vtable merge_ref_iterator_vtable = {
248 };
249
250 struct ref_iterator *merge_ref_iterator_begin(
253 - int ordered,
251 struct ref_iterator *iter0, struct ref_iterator *iter1,
252 ref_iterator_select_fn *select, void *cb_data)
253 {
@@ -265,7 +262,7 @@ struct ref_iterator *merge_ref_iterator_begin(
262 * references through only if they exist in both iterators.
263 */
264
268 - base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable, ordered);
265 + base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable);
266 iter->iter0 = iter0;
267 iter->iter1 = iter1;
268 iter->select = select;
@@ -314,12 +311,9 @@ struct ref_iterator *overlay_ref_iterator_begin(
311 } else if (is_empty_ref_iterator(back)) {
312 ref_iterator_abort(back);
313 return front;
317 - } else if (!front->ordered || !back->ordered) {
318 - BUG("overlay_ref_iterator requires ordered inputs");
314 }
315
321 - return merge_ref_iterator_begin(1, front, back,
322 - overlay_iterator_select, NULL);
316 + return merge_ref_iterator_begin(front, back, overlay_iterator_select, NULL);
317 }
318
319 struct prefix_ref_iterator {
@@ -358,16 +352,12 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator)
352
353 if (cmp > 0) {
354 /*
361 - * If the source iterator is ordered, then we
355 + * As the source iterator is ordered, we
356 * can stop the iteration as soon as we see a
357 * refname that comes after the prefix:
358 */
365 - if (iter->iter0->ordered) {
366 - ok = ref_iterator_abort(iter->iter0);
367 - break;
368 - } else {
369 - continue;
370 - }
359 + ok = ref_iterator_abort(iter->iter0);
360 + break;
361 }
362
363 if (iter->trim) {
@@ -439,7 +429,7 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
429 CALLOC_ARRAY(iter, 1);
430 ref_iterator = &iter->base;
431
442 - base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable, iter0->ordered);
432 + base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable);
433
434 iter->iter0 = iter0;
435 iter->prefix = xstrdup(prefix);
refs/packed-backend.c
+1 -1
@@ -1111,7 +1111,7 @@ static struct ref_iterator *packed_ref_iterator_begin(
1111
1112 CALLOC_ARRAY(iter, 1);
1113 ref_iterator = &iter->base;
1114 - base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable, 1);
1114 + base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable);
1115
1116 if (exclude_patterns)
1117 populate_excluded_jump_list(iter, snapshot, exclude_patterns);
refs/ref-cache.c
+1 -1
@@ -486,7 +486,7 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache,
486
487 CALLOC_ARRAY(iter, 1);
488 ref_iterator = &iter->base;
489 - base_ref_iterator_init(ref_iterator, &cache_ref_iterator_vtable, 1);
489 + base_ref_iterator_init(ref_iterator, &cache_ref_iterator_vtable);
490 ALLOC_GROW(iter->levels, 10, iter->levels_alloc);
491
492 iter->levels_nr = 1;
refs/refs-internal.h
+2 -16
@@ -312,13 +312,6 @@ enum do_for_each_ref_flags {
312 */
313 struct ref_iterator {
314 struct ref_iterator_vtable *vtable;
315 -
316 - /*
317 - * Does this `ref_iterator` iterate over references in order
318 - * by refname?
319 - */
320 - unsigned int ordered : 1;
321 -
315 const char *refname;
316 const struct object_id *oid;
317 unsigned int flags;
@@ -399,11 +392,9 @@ enum iterator_selection ref_iterator_select(struct ref_iterator *iter_worktree,
392 * Iterate over the entries from iter0 and iter1, with the values
393 * interleaved as directed by the select function. The iterator takes
394 * ownership of iter0 and iter1 and frees them when the iteration is
402 - * over. A derived class should set `ordered` to 1 or 0 based on
403 - * whether it generates its output in order by reference name.
395 + * over.
396 */
397 struct ref_iterator *merge_ref_iterator_begin(
406 - int ordered,
398 struct ref_iterator *iter0, struct ref_iterator *iter1,
399 ref_iterator_select_fn *select, void *cb_data);
400
@@ -432,8 +423,6 @@ struct ref_iterator *overlay_ref_iterator_begin(
423 * As an convenience to callers, if prefix is the empty string and
424 * trim is zero, this function returns iter0 directly, without
425 * wrapping it.
435 - *
436 - * The resulting ref_iterator is ordered if iter0 is.
426 */
427 struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
428 const char *prefix,
@@ -444,14 +433,11 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
433 /*
434 * Base class constructor for ref_iterators. Initialize the
435 * ref_iterator part of iter, setting its vtable pointer as specified.
447 - * `ordered` should be set to 1 if the iterator will iterate over
448 - * references in order by refname; otherwise it should be set to 0.
436 * This is meant to be called only by the initializers of derived
437 * classes.
438 */
439 void base_ref_iterator_init(struct ref_iterator *iter,
453 - struct ref_iterator_vtable *vtable,
454 - int ordered);
440 + struct ref_iterator_vtable *vtable);
441
442 /*
443 * Base class destructor for ref_iterators. Destroy the ref_iterator
refs/reftable-backend.c
+4 -4
@@ -479,7 +479,7 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
479 int ret;
480
481 iter = xcalloc(1, sizeof(*iter));
482 - base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable, 1);
482 + base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable);
483 iter->prefix = prefix;
484 iter->base.oid = &iter->oid;
485 iter->flags = flags;
@@ -532,7 +532,7 @@ static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_sto
532 * single iterator.
533 */
534 worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix, flags);
535 - return merge_ref_iterator_begin(1, &worktree_iter->base, &main_iter->base,
535 + return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base,
536 ref_iterator_select, NULL);
537 }
538
@@ -1680,7 +1680,7 @@ static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftabl
1680 int ret;
1681
1682 iter = xcalloc(1, sizeof(*iter));
1683 - base_ref_iterator_init(&iter->base, &reftable_reflog_iterator_vtable, 1);
1683 + base_ref_iterator_init(&iter->base, &reftable_reflog_iterator_vtable);
1684 iter->refs = refs;
1685 iter->base.oid = &iter->oid;
1686
@@ -1715,7 +1715,7 @@ static struct ref_iterator *reftable_be_reflog_iterator_begin(struct ref_store *
1715
1716 worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_stack);
1717
1718 - return merge_ref_iterator_begin(1, &worktree_iter->base, &main_iter->base,
1718 + return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base,
1719 ref_iterator_select, NULL);
1720 }
1721