refs/iterator: implement seeking for reftable iterators
Implement seeking of reftable iterators. As the low-level reftable iterators already support seeking this change is straight-forward. Two notes though: - We do not support seeking on reflog iterators. It is unclear what seeking would even look like in this context, as you typically would want to seek to a specific entry in the reflog for a specific ref. There is currently no use case for this, but if one arises in the future, we can still implement seeking at that later point. - We start to check whether `reftable_stack_init_ref_iterator()` is successful. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Mar 12, 2025 at 16:56 UTC
53de20c931faabdb6fa9a30d949266b2a7471497
1 file changed
+30
-5
refs/reftable-backend.c
+30
-5
@@ -547,7 +547,7 @@ struct reftable_ref_iterator {
547
struct reftable_ref_record ref;
548
struct object_id oid;
549
550
- const char *prefix;
550
+ char *prefix;
551
size_t prefix_len;
552
char **exclude_patterns;
553
size_t exclude_patterns_index;
@@ -718,6 +718,20 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
718
return ITER_OK;
719
}
720
721
+static int reftable_ref_iterator_seek(struct ref_iterator *ref_iterator,
722
+ const char *prefix)
723
+{
724
+ struct reftable_ref_iterator *iter =
725
+ (struct reftable_ref_iterator *)ref_iterator;
726
+
727
+ free(iter->prefix);
728
+ iter->prefix = xstrdup_or_null(prefix);
729
+ iter->prefix_len = prefix ? strlen(prefix) : 0;
730
+ iter->err = reftable_iterator_seek_ref(&iter->iter, prefix);
731
+
732
+ return iter->err;
733
+}
734
+
735
static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator,
736
struct object_id *peeled)
737
{
@@ -744,10 +758,12 @@ static void reftable_ref_iterator_release(struct ref_iterator *ref_iterator)
758
free(iter->exclude_patterns[i]);
759
free(iter->exclude_patterns);
760
}
761
+ free(iter->prefix);
762
}
763
764
static struct ref_iterator_vtable reftable_ref_iterator_vtable = {
765
.advance = reftable_ref_iterator_advance,
766
+ .seek = reftable_ref_iterator_seek,
767
.peel = reftable_ref_iterator_peel,
768
.release = reftable_ref_iterator_release,
769
};
@@ -806,8 +822,6 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
822
823
iter = xcalloc(1, sizeof(*iter));
824
base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable);
809
- iter->prefix = prefix;
810
- iter->prefix_len = prefix ? strlen(prefix) : 0;
825
iter->base.oid = &iter->oid;
826
iter->flags = flags;
827
iter->refs = refs;
@@ -821,8 +835,11 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
835
if (ret)
836
goto done;
837
824
- reftable_stack_init_ref_iterator(stack, &iter->iter);
825
- ret = reftable_iterator_seek_ref(&iter->iter, prefix);
838
+ ret = reftable_stack_init_ref_iterator(stack, &iter->iter);
839
+ if (ret)
840
+ goto done;
841
+
842
+ ret = reftable_ref_iterator_seek(&iter->base, prefix);
843
if (ret)
844
goto done;
845
@@ -2018,6 +2035,13 @@ static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator)
2035
return ITER_OK;
2036
}
2037
2038
+static int reftable_reflog_iterator_seek(struct ref_iterator *ref_iterator UNUSED,
2039
+ const char *prefix UNUSED)
2040
+{
2041
+ BUG("reftable reflog iterator cannot be seeked");
2042
+ return -1;
2043
+}
2044
+
2045
static int reftable_reflog_iterator_peel(struct ref_iterator *ref_iterator UNUSED,
2046
struct object_id *peeled UNUSED)
2047
{
@@ -2036,6 +2060,7 @@ static void reftable_reflog_iterator_release(struct ref_iterator *ref_iterator)
2060
2061
static struct ref_iterator_vtable reftable_reflog_iterator_vtable = {
2062
.advance = reftable_reflog_iterator_advance,
2063
+ .seek = reftable_reflog_iterator_seek,
2064
.peel = reftable_reflog_iterator_peel,
2065
.release = reftable_reflog_iterator_release,
2066
};