2 * Generic reference iterator infrastructure. See refs-internal.h for
3 * documentation about the design and use of reference iterators.
8 #include "refs/refs-internal.h"
11 int ref_iterator_advance(struct ref_iterator *ref_iterator)
13 return ref_iterator->vtable->advance(ref_iterator);
16 int ref_iterator_peel(struct ref_iterator *ref_iterator,
17 struct object_id *peeled)
19 return ref_iterator->vtable->peel(ref_iterator, peeled);
22 int ref_iterator_abort(struct ref_iterator *ref_iterator)
24 return ref_iterator->vtable->abort(ref_iterator);
27 void base_ref_iterator_init(struct ref_iterator *iter,
28 struct ref_iterator_vtable *vtable)
30 iter->vtable = vtable;
36 void base_ref_iterator_free(struct ref_iterator *iter)
38 /* Help make use-after-free bugs fail quickly: */
43 struct empty_ref_iterator {
44 struct ref_iterator base;
47 static int empty_ref_iterator_advance(struct ref_iterator *ref_iterator)
49 return ref_iterator_abort(ref_iterator);
52 static int empty_ref_iterator_peel(struct ref_iterator *ref_iterator,
53 struct object_id *peeled)
55 die("BUG: peel called for empty iterator");
58 static int empty_ref_iterator_abort(struct ref_iterator *ref_iterator)
60 base_ref_iterator_free(ref_iterator);
64 static struct ref_iterator_vtable empty_ref_iterator_vtable = {
65 empty_ref_iterator_advance,
66 empty_ref_iterator_peel,
67 empty_ref_iterator_abort
70 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;
75 base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable);
79 int is_empty_ref_iterator(struct ref_iterator *ref_iterator)
81 return ref_iterator->vtable == &empty_ref_iterator_vtable;
84 struct merge_ref_iterator {
85 struct ref_iterator base;
87 struct ref_iterator *iter0, *iter1;
89 ref_iterator_select_fn *select;
93 * A pointer to iter0 or iter1 (whichever is supplying the
94 * current value), or NULL if advance has not yet been called.
96 struct ref_iterator **current;
99 static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator)
101 struct merge_ref_iterator *iter =
102 (struct merge_ref_iterator *)ref_iterator;
105 if (!iter->current) {
106 /* Initialize: advance both iterators to their first entries */
107 if ((ok = ref_iterator_advance(iter->iter0)) != ITER_OK) {
109 if (ok == ITER_ERROR)
112 if ((ok = ref_iterator_advance(iter->iter1)) != ITER_OK) {
114 if (ok == ITER_ERROR)
119 * Advance the current iterator past the just-used
122 if ((ok = ref_iterator_advance(*iter->current)) != ITER_OK) {
123 *iter->current = NULL;
124 if (ok == ITER_ERROR)
129 /* Loop until we find an entry that we can yield. */
131 struct ref_iterator **secondary;
132 enum iterator_selection selection =
133 iter->select(iter->iter0, iter->iter1, iter->cb_data);
135 if (selection == ITER_SELECT_DONE) {
136 return ref_iterator_abort(ref_iterator);
137 } else if (selection == ITER_SELECT_ERROR) {
138 ref_iterator_abort(ref_iterator);
142 if ((selection & ITER_CURRENT_SELECTION_MASK) == 0) {
143 iter->current = &iter->iter0;
144 secondary = &iter->iter1;
146 iter->current = &iter->iter1;
147 secondary = &iter->iter0;
150 if (selection & ITER_SKIP_SECONDARY) {
151 if ((ok = ref_iterator_advance(*secondary)) != ITER_OK) {
153 if (ok == ITER_ERROR)
158 if (selection & ITER_YIELD_CURRENT) {
159 iter->base.refname = (*iter->current)->refname;
160 iter->base.oid = (*iter->current)->oid;
161 iter->base.flags = (*iter->current)->flags;
167 ref_iterator_abort(ref_iterator);
171 static int merge_ref_iterator_peel(struct ref_iterator *ref_iterator,
172 struct object_id *peeled)
174 struct merge_ref_iterator *iter =
175 (struct merge_ref_iterator *)ref_iterator;
177 if (!iter->current) {
178 die("BUG: peel called before advance for merge iterator");
180 return ref_iterator_peel(*iter->current, peeled);
183 static int merge_ref_iterator_abort(struct ref_iterator *ref_iterator)
185 struct merge_ref_iterator *iter =
186 (struct merge_ref_iterator *)ref_iterator;
190 if (ref_iterator_abort(iter->iter0) != ITER_DONE)
194 if (ref_iterator_abort(iter->iter1) != ITER_DONE)
197 base_ref_iterator_free(ref_iterator);
201 static struct ref_iterator_vtable merge_ref_iterator_vtable = {
202 merge_ref_iterator_advance,
203 merge_ref_iterator_peel,
204 merge_ref_iterator_abort
207 struct ref_iterator *merge_ref_iterator_begin(
208 struct ref_iterator *iter0, struct ref_iterator *iter1,
209 ref_iterator_select_fn *select, void *cb_data)
211 struct merge_ref_iterator *iter = xcalloc(1, sizeof(*iter));
212 struct ref_iterator *ref_iterator = &iter->base;
215 * We can't do the same kind of is_empty_ref_iterator()-style
216 * optimization here as overlay_ref_iterator_begin() does,
217 * because we don't know the semantics of the select function.
218 * It might, for example, implement "intersect" by passing
219 * references through only if they exist in both iterators.
222 base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable);
225 iter->select = select;
226 iter->cb_data = cb_data;
227 iter->current = NULL;
232 * A ref_iterator_select_fn that overlays the items from front on top
233 * of those from back (like loose refs over packed refs). See
234 * overlay_ref_iterator_begin().
236 static enum iterator_selection overlay_iterator_select(
237 struct ref_iterator *front, struct ref_iterator *back,
243 return front ? ITER_SELECT_0 : ITER_SELECT_DONE;
245 return ITER_SELECT_1;
247 cmp = strcmp(front->refname, back->refname);
250 return ITER_SELECT_0;
252 return ITER_SELECT_1;
254 return ITER_SELECT_0_SKIP_1;
257 struct ref_iterator *overlay_ref_iterator_begin(
258 struct ref_iterator *front, struct ref_iterator *back)
261 * Optimization: if one of the iterators is empty, return the
262 * other one rather than incurring the overhead of wrapping
265 if (is_empty_ref_iterator(front)) {
266 ref_iterator_abort(front);
268 } else if (is_empty_ref_iterator(back)) {
269 ref_iterator_abort(back);
273 return merge_ref_iterator_begin(front, back,
274 overlay_iterator_select, NULL);
277 struct prefix_ref_iterator {
278 struct ref_iterator base;
280 struct ref_iterator *iter0;
285 static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator)
287 struct prefix_ref_iterator *iter =
288 (struct prefix_ref_iterator *)ref_iterator;
291 while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) {
292 if (!starts_with(iter->iter0->refname, iter->prefix))
297 * It is nonsense to trim off characters that
298 * you haven't already checked for via a
299 * prefix check, whether via this
300 * `prefix_ref_iterator` or upstream in
301 * `iter0`). So if there wouldn't be at least
302 * one character left in the refname after
303 * trimming, report it as a bug:
305 if (strlen(iter->iter0->refname) <= iter->trim)
306 die("BUG: attempt to trim too many characters");
307 iter->base.refname = iter->iter0->refname + iter->trim;
309 iter->base.refname = iter->iter0->refname;
312 iter->base.oid = iter->iter0->oid;
313 iter->base.flags = iter->iter0->flags;
318 if (ref_iterator_abort(ref_iterator) != ITER_DONE)
323 static int prefix_ref_iterator_peel(struct ref_iterator *ref_iterator,
324 struct object_id *peeled)
326 struct prefix_ref_iterator *iter =
327 (struct prefix_ref_iterator *)ref_iterator;
329 return ref_iterator_peel(iter->iter0, peeled);
332 static int prefix_ref_iterator_abort(struct ref_iterator *ref_iterator)
334 struct prefix_ref_iterator *iter =
335 (struct prefix_ref_iterator *)ref_iterator;
339 ok = ref_iterator_abort(iter->iter0);
341 base_ref_iterator_free(ref_iterator);
345 static struct ref_iterator_vtable prefix_ref_iterator_vtable = {
346 prefix_ref_iterator_advance,
347 prefix_ref_iterator_peel,
348 prefix_ref_iterator_abort
351 struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
355 struct prefix_ref_iterator *iter;
356 struct ref_iterator *ref_iterator;
358 if (!*prefix && !trim)
359 return iter0; /* optimization: no need to wrap iterator */
361 iter = xcalloc(1, sizeof(*iter));
362 ref_iterator = &iter->base;
364 base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable);
367 iter->prefix = xstrdup(prefix);
373 struct ref_iterator *current_ref_iter = NULL;
375 int do_for_each_ref_iterator(struct ref_iterator *iter,
376 each_ref_fn fn, void *cb_data)
379 struct ref_iterator *old_ref_iter = current_ref_iter;
381 current_ref_iter = iter;
382 while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
383 retval = fn(iter->refname, iter->oid, iter->flags, cb_data);
386 * If ref_iterator_abort() returns ITER_ERROR,
387 * we ignore that error in deference to the
388 * callback function's return value.
390 ref_iterator_abort(iter);
396 current_ref_iter = old_ref_iter;
397 if (ok == ITER_ERROR)