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>
This commit is contained in:

committed by
Junio C Hamano

parent
6f22780017
commit
5e01d83841
4
refs.c
4
refs.c
@ -1594,10 +1594,6 @@ struct ref_iterator *refs_ref_iterator_begin(
|
|||||||
if (trim)
|
if (trim)
|
||||||
iter = prefix_ref_iterator_begin(iter, "", trim);
|
iter = prefix_ref_iterator_begin(iter, "", trim);
|
||||||
|
|
||||||
/* Sanity check for subclasses: */
|
|
||||||
if (!iter->ordered)
|
|
||||||
BUG("reference iterator is not ordered");
|
|
||||||
|
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,6 @@ static int debug_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
|||||||
trace_printf_key(&trace_refs, "iterator_advance: %s (0)\n",
|
trace_printf_key(&trace_refs, "iterator_advance: %s (0)\n",
|
||||||
diter->iter->refname);
|
diter->iter->refname);
|
||||||
|
|
||||||
diter->base.ordered = diter->iter->ordered;
|
|
||||||
diter->base.refname = diter->iter->refname;
|
diter->base.refname = diter->iter->refname;
|
||||||
diter->base.oid = diter->iter->oid;
|
diter->base.oid = diter->iter->oid;
|
||||||
diter->base.flags = diter->iter->flags;
|
diter->base.flags = diter->iter->flags;
|
||||||
@ -222,7 +221,7 @@ debug_ref_iterator_begin(struct ref_store *ref_store, const char *prefix,
|
|||||||
drefs->refs->be->iterator_begin(drefs->refs, prefix,
|
drefs->refs->be->iterator_begin(drefs->refs, prefix,
|
||||||
exclude_patterns, flags);
|
exclude_patterns, flags);
|
||||||
struct debug_ref_iterator *diter = xcalloc(1, sizeof(*diter));
|
struct debug_ref_iterator *diter = xcalloc(1, sizeof(*diter));
|
||||||
base_ref_iterator_init(&diter->base, &debug_ref_iterator_vtable, 1);
|
base_ref_iterator_init(&diter->base, &debug_ref_iterator_vtable);
|
||||||
diter->iter = res;
|
diter->iter = res;
|
||||||
trace_printf_key(&trace_refs, "ref_iterator_begin: \"%s\" (0x%x)\n",
|
trace_printf_key(&trace_refs, "ref_iterator_begin: \"%s\" (0x%x)\n",
|
||||||
prefix, flags);
|
prefix, flags);
|
||||||
|
@ -879,8 +879,7 @@ static struct ref_iterator *files_ref_iterator_begin(
|
|||||||
|
|
||||||
CALLOC_ARRAY(iter, 1);
|
CALLOC_ARRAY(iter, 1);
|
||||||
ref_iterator = &iter->base;
|
ref_iterator = &iter->base;
|
||||||
base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable,
|
base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable);
|
||||||
overlay_iter->ordered);
|
|
||||||
iter->iter0 = overlay_iter;
|
iter->iter0 = overlay_iter;
|
||||||
iter->repo = ref_store->repo;
|
iter->repo = ref_store->repo;
|
||||||
iter->flags = flags;
|
iter->flags = flags;
|
||||||
@ -2202,7 +2201,7 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store,
|
|||||||
CALLOC_ARRAY(iter, 1);
|
CALLOC_ARRAY(iter, 1);
|
||||||
ref_iterator = &iter->base;
|
ref_iterator = &iter->base;
|
||||||
|
|
||||||
base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable, 1);
|
base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable);
|
||||||
iter->dir_iterator = diter;
|
iter->dir_iterator = diter;
|
||||||
iter->ref_store = ref_store;
|
iter->ref_store = ref_store;
|
||||||
strbuf_release(&sb);
|
strbuf_release(&sb);
|
||||||
@ -2220,7 +2219,7 @@ static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_st
|
|||||||
return reflog_iterator_begin(ref_store, refs->gitcommondir);
|
return reflog_iterator_begin(ref_store, refs->gitcommondir);
|
||||||
} else {
|
} else {
|
||||||
return merge_ref_iterator_begin(
|
return merge_ref_iterator_begin(
|
||||||
1, reflog_iterator_begin(ref_store, refs->base.gitdir),
|
reflog_iterator_begin(ref_store, refs->base.gitdir),
|
||||||
reflog_iterator_begin(ref_store, refs->gitcommondir),
|
reflog_iterator_begin(ref_store, refs->gitcommondir),
|
||||||
ref_iterator_select, refs);
|
ref_iterator_select, refs);
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,9 @@ int ref_iterator_abort(struct ref_iterator *ref_iterator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void base_ref_iterator_init(struct ref_iterator *iter,
|
void base_ref_iterator_init(struct ref_iterator *iter,
|
||||||
struct ref_iterator_vtable *vtable,
|
struct ref_iterator_vtable *vtable)
|
||||||
int ordered)
|
|
||||||
{
|
{
|
||||||
iter->vtable = vtable;
|
iter->vtable = vtable;
|
||||||
iter->ordered = !!ordered;
|
|
||||||
iter->refname = NULL;
|
iter->refname = NULL;
|
||||||
iter->oid = NULL;
|
iter->oid = NULL;
|
||||||
iter->flags = 0;
|
iter->flags = 0;
|
||||||
@ -74,7 +72,7 @@ struct ref_iterator *empty_ref_iterator_begin(void)
|
|||||||
struct empty_ref_iterator *iter = xcalloc(1, sizeof(*iter));
|
struct empty_ref_iterator *iter = xcalloc(1, sizeof(*iter));
|
||||||
struct ref_iterator *ref_iterator = &iter->base;
|
struct ref_iterator *ref_iterator = &iter->base;
|
||||||
|
|
||||||
base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable, 1);
|
base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable);
|
||||||
return ref_iterator;
|
return ref_iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +248,6 @@ static struct ref_iterator_vtable merge_ref_iterator_vtable = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ref_iterator *merge_ref_iterator_begin(
|
struct ref_iterator *merge_ref_iterator_begin(
|
||||||
int ordered,
|
|
||||||
struct ref_iterator *iter0, struct ref_iterator *iter1,
|
struct ref_iterator *iter0, struct ref_iterator *iter1,
|
||||||
ref_iterator_select_fn *select, void *cb_data)
|
ref_iterator_select_fn *select, void *cb_data)
|
||||||
{
|
{
|
||||||
@ -265,7 +262,7 @@ struct ref_iterator *merge_ref_iterator_begin(
|
|||||||
* references through only if they exist in both iterators.
|
* references through only if they exist in both iterators.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable, ordered);
|
base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable);
|
||||||
iter->iter0 = iter0;
|
iter->iter0 = iter0;
|
||||||
iter->iter1 = iter1;
|
iter->iter1 = iter1;
|
||||||
iter->select = select;
|
iter->select = select;
|
||||||
@ -314,12 +311,9 @@ struct ref_iterator *overlay_ref_iterator_begin(
|
|||||||
} else if (is_empty_ref_iterator(back)) {
|
} else if (is_empty_ref_iterator(back)) {
|
||||||
ref_iterator_abort(back);
|
ref_iterator_abort(back);
|
||||||
return front;
|
return front;
|
||||||
} else if (!front->ordered || !back->ordered) {
|
|
||||||
BUG("overlay_ref_iterator requires ordered inputs");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return merge_ref_iterator_begin(1, front, back,
|
return merge_ref_iterator_begin(front, back, overlay_iterator_select, NULL);
|
||||||
overlay_iterator_select, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct prefix_ref_iterator {
|
struct prefix_ref_iterator {
|
||||||
@ -358,16 +352,12 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
|||||||
|
|
||||||
if (cmp > 0) {
|
if (cmp > 0) {
|
||||||
/*
|
/*
|
||||||
* If the source iterator is ordered, then we
|
* As the source iterator is ordered, we
|
||||||
* can stop the iteration as soon as we see a
|
* can stop the iteration as soon as we see a
|
||||||
* refname that comes after the prefix:
|
* refname that comes after the prefix:
|
||||||
*/
|
*/
|
||||||
if (iter->iter0->ordered) {
|
|
||||||
ok = ref_iterator_abort(iter->iter0);
|
ok = ref_iterator_abort(iter->iter0);
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iter->trim) {
|
if (iter->trim) {
|
||||||
@ -439,7 +429,7 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
|
|||||||
CALLOC_ARRAY(iter, 1);
|
CALLOC_ARRAY(iter, 1);
|
||||||
ref_iterator = &iter->base;
|
ref_iterator = &iter->base;
|
||||||
|
|
||||||
base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable, iter0->ordered);
|
base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable);
|
||||||
|
|
||||||
iter->iter0 = iter0;
|
iter->iter0 = iter0;
|
||||||
iter->prefix = xstrdup(prefix);
|
iter->prefix = xstrdup(prefix);
|
||||||
|
@ -1111,7 +1111,7 @@ static struct ref_iterator *packed_ref_iterator_begin(
|
|||||||
|
|
||||||
CALLOC_ARRAY(iter, 1);
|
CALLOC_ARRAY(iter, 1);
|
||||||
ref_iterator = &iter->base;
|
ref_iterator = &iter->base;
|
||||||
base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable, 1);
|
base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable);
|
||||||
|
|
||||||
if (exclude_patterns)
|
if (exclude_patterns)
|
||||||
populate_excluded_jump_list(iter, snapshot, exclude_patterns);
|
populate_excluded_jump_list(iter, snapshot, exclude_patterns);
|
||||||
|
@ -486,7 +486,7 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache,
|
|||||||
|
|
||||||
CALLOC_ARRAY(iter, 1);
|
CALLOC_ARRAY(iter, 1);
|
||||||
ref_iterator = &iter->base;
|
ref_iterator = &iter->base;
|
||||||
base_ref_iterator_init(ref_iterator, &cache_ref_iterator_vtable, 1);
|
base_ref_iterator_init(ref_iterator, &cache_ref_iterator_vtable);
|
||||||
ALLOC_GROW(iter->levels, 10, iter->levels_alloc);
|
ALLOC_GROW(iter->levels, 10, iter->levels_alloc);
|
||||||
|
|
||||||
iter->levels_nr = 1;
|
iter->levels_nr = 1;
|
||||||
|
@ -312,13 +312,6 @@ enum do_for_each_ref_flags {
|
|||||||
*/
|
*/
|
||||||
struct ref_iterator {
|
struct ref_iterator {
|
||||||
struct ref_iterator_vtable *vtable;
|
struct ref_iterator_vtable *vtable;
|
||||||
|
|
||||||
/*
|
|
||||||
* Does this `ref_iterator` iterate over references in order
|
|
||||||
* by refname?
|
|
||||||
*/
|
|
||||||
unsigned int ordered : 1;
|
|
||||||
|
|
||||||
const char *refname;
|
const char *refname;
|
||||||
const struct object_id *oid;
|
const struct object_id *oid;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
@ -399,11 +392,9 @@ enum iterator_selection ref_iterator_select(struct ref_iterator *iter_worktree,
|
|||||||
* Iterate over the entries from iter0 and iter1, with the values
|
* Iterate over the entries from iter0 and iter1, with the values
|
||||||
* interleaved as directed by the select function. The iterator takes
|
* interleaved as directed by the select function. The iterator takes
|
||||||
* ownership of iter0 and iter1 and frees them when the iteration is
|
* ownership of iter0 and iter1 and frees them when the iteration is
|
||||||
* over. A derived class should set `ordered` to 1 or 0 based on
|
* over.
|
||||||
* whether it generates its output in order by reference name.
|
|
||||||
*/
|
*/
|
||||||
struct ref_iterator *merge_ref_iterator_begin(
|
struct ref_iterator *merge_ref_iterator_begin(
|
||||||
int ordered,
|
|
||||||
struct ref_iterator *iter0, struct ref_iterator *iter1,
|
struct ref_iterator *iter0, struct ref_iterator *iter1,
|
||||||
ref_iterator_select_fn *select, void *cb_data);
|
ref_iterator_select_fn *select, void *cb_data);
|
||||||
|
|
||||||
@ -432,8 +423,6 @@ struct ref_iterator *overlay_ref_iterator_begin(
|
|||||||
* As an convenience to callers, if prefix is the empty string and
|
* As an convenience to callers, if prefix is the empty string and
|
||||||
* trim is zero, this function returns iter0 directly, without
|
* trim is zero, this function returns iter0 directly, without
|
||||||
* wrapping it.
|
* wrapping it.
|
||||||
*
|
|
||||||
* The resulting ref_iterator is ordered if iter0 is.
|
|
||||||
*/
|
*/
|
||||||
struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
|
struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
|
||||||
const char *prefix,
|
const char *prefix,
|
||||||
@ -444,14 +433,11 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
|
|||||||
/*
|
/*
|
||||||
* Base class constructor for ref_iterators. Initialize the
|
* Base class constructor for ref_iterators. Initialize the
|
||||||
* ref_iterator part of iter, setting its vtable pointer as specified.
|
* ref_iterator part of iter, setting its vtable pointer as specified.
|
||||||
* `ordered` should be set to 1 if the iterator will iterate over
|
|
||||||
* references in order by refname; otherwise it should be set to 0.
|
|
||||||
* This is meant to be called only by the initializers of derived
|
* This is meant to be called only by the initializers of derived
|
||||||
* classes.
|
* classes.
|
||||||
*/
|
*/
|
||||||
void base_ref_iterator_init(struct ref_iterator *iter,
|
void base_ref_iterator_init(struct ref_iterator *iter,
|
||||||
struct ref_iterator_vtable *vtable,
|
struct ref_iterator_vtable *vtable);
|
||||||
int ordered);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Base class destructor for ref_iterators. Destroy the ref_iterator
|
* Base class destructor for ref_iterators. Destroy the ref_iterator
|
||||||
|
@ -479,7 +479,7 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
iter = xcalloc(1, sizeof(*iter));
|
iter = xcalloc(1, sizeof(*iter));
|
||||||
base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable, 1);
|
base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable);
|
||||||
iter->prefix = prefix;
|
iter->prefix = prefix;
|
||||||
iter->base.oid = &iter->oid;
|
iter->base.oid = &iter->oid;
|
||||||
iter->flags = flags;
|
iter->flags = flags;
|
||||||
@ -532,7 +532,7 @@ static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_sto
|
|||||||
* single iterator.
|
* single iterator.
|
||||||
*/
|
*/
|
||||||
worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix, flags);
|
worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix, flags);
|
||||||
return merge_ref_iterator_begin(1, &worktree_iter->base, &main_iter->base,
|
return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base,
|
||||||
ref_iterator_select, NULL);
|
ref_iterator_select, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1680,7 +1680,7 @@ static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftabl
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
iter = xcalloc(1, sizeof(*iter));
|
iter = xcalloc(1, sizeof(*iter));
|
||||||
base_ref_iterator_init(&iter->base, &reftable_reflog_iterator_vtable, 1);
|
base_ref_iterator_init(&iter->base, &reftable_reflog_iterator_vtable);
|
||||||
iter->refs = refs;
|
iter->refs = refs;
|
||||||
iter->base.oid = &iter->oid;
|
iter->base.oid = &iter->oid;
|
||||||
|
|
||||||
@ -1715,7 +1715,7 @@ static struct ref_iterator *reftable_be_reflog_iterator_begin(struct ref_store *
|
|||||||
|
|
||||||
worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_stack);
|
worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_stack);
|
||||||
|
|
||||||
return merge_ref_iterator_begin(1, &worktree_iter->base, &main_iter->base,
|
return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base,
|
||||||
ref_iterator_select, NULL);
|
ref_iterator_select, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user