Skip to content

Commit 9821d90

Browse files
pks-tgitster
authored andcommitted
refs/iterator: implement seeking for merged iterators
Implement seeking on merged iterators. The implementation is rather straight forward, with the only exception that we must not deallocate the underlying iterators once they have been exhausted. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 82c39c6 commit 9821d90

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

refs/iterator.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ int is_empty_ref_iterator(struct ref_iterator *ref_iterator)
9696
struct merge_ref_iterator {
9797
struct ref_iterator base;
9898

99-
struct ref_iterator *iter0, *iter1;
99+
struct ref_iterator *iter0, *iter0_owned;
100+
struct ref_iterator *iter1, *iter1_owned;
100101

101102
ref_iterator_select_fn *select;
102103
void *cb_data;
@@ -160,13 +161,11 @@ static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator)
160161
if (!iter->current) {
161162
/* Initialize: advance both iterators to their first entries */
162163
if ((ok = ref_iterator_advance(iter->iter0)) != ITER_OK) {
163-
ref_iterator_free(iter->iter0);
164164
iter->iter0 = NULL;
165165
if (ok == ITER_ERROR)
166166
goto error;
167167
}
168168
if ((ok = ref_iterator_advance(iter->iter1)) != ITER_OK) {
169-
ref_iterator_free(iter->iter1);
170169
iter->iter1 = NULL;
171170
if (ok == ITER_ERROR)
172171
goto error;
@@ -177,7 +176,6 @@ static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator)
177176
* entry:
178177
*/
179178
if ((ok = ref_iterator_advance(*iter->current)) != ITER_OK) {
180-
ref_iterator_free(*iter->current);
181179
*iter->current = NULL;
182180
if (ok == ITER_ERROR)
183181
goto error;
@@ -206,7 +204,6 @@ static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator)
206204

207205
if (selection & ITER_SKIP_SECONDARY) {
208206
if ((ok = ref_iterator_advance(*secondary)) != ITER_OK) {
209-
ref_iterator_free(*secondary);
210207
*secondary = NULL;
211208
if (ok == ITER_ERROR)
212209
goto error;
@@ -226,6 +223,28 @@ static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator)
226223
return ITER_ERROR;
227224
}
228225

226+
static int merge_ref_iterator_seek(struct ref_iterator *ref_iterator,
227+
const char *prefix)
228+
{
229+
struct merge_ref_iterator *iter =
230+
(struct merge_ref_iterator *)ref_iterator;
231+
int ret;
232+
233+
iter->current = NULL;
234+
iter->iter0 = iter->iter0_owned;
235+
iter->iter1 = iter->iter1_owned;
236+
237+
ret = ref_iterator_seek(iter->iter0, prefix);
238+
if (ret < 0)
239+
return ret;
240+
241+
ret = ref_iterator_seek(iter->iter1, prefix);
242+
if (ret < 0)
243+
return ret;
244+
245+
return 0;
246+
}
247+
229248
static int merge_ref_iterator_peel(struct ref_iterator *ref_iterator,
230249
struct object_id *peeled)
231250
{
@@ -242,12 +261,13 @@ static void merge_ref_iterator_release(struct ref_iterator *ref_iterator)
242261
{
243262
struct merge_ref_iterator *iter =
244263
(struct merge_ref_iterator *)ref_iterator;
245-
ref_iterator_free(iter->iter0);
246-
ref_iterator_free(iter->iter1);
264+
ref_iterator_free(iter->iter0_owned);
265+
ref_iterator_free(iter->iter1_owned);
247266
}
248267

249268
static struct ref_iterator_vtable merge_ref_iterator_vtable = {
250269
.advance = merge_ref_iterator_advance,
270+
.seek = merge_ref_iterator_seek,
251271
.peel = merge_ref_iterator_peel,
252272
.release = merge_ref_iterator_release,
253273
};
@@ -268,8 +288,8 @@ struct ref_iterator *merge_ref_iterator_begin(
268288
*/
269289

270290
base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable);
271-
iter->iter0 = iter0;
272-
iter->iter1 = iter1;
291+
iter->iter0 = iter->iter0_owned = iter0;
292+
iter->iter1 = iter->iter1_owned = iter1;
273293
iter->select = select;
274294
iter->cb_data = cb_data;
275295
iter->current = NULL;

0 commit comments

Comments
 (0)