]> git.ipfire.org Git - thirdparty/git.git/commitdiff
refs/iterator: implement seeking for reftable iterators
authorPatrick Steinhardt <ps@pks.im>
Wed, 12 Mar 2025 15:56:18 +0000 (16:56 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 12 Mar 2025 18:31:19 +0000 (11:31 -0700)
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>
refs/reftable-backend.c

index 2d5f4afe6b52f262fb1fec2ba1cc4ec629f805b4..c8f86da731f4b2649490197feabd417a5da08c4b 100644 (file)
@@ -547,7 +547,7 @@ struct reftable_ref_iterator {
        struct reftable_ref_record ref;
        struct object_id oid;
 
-       const char *prefix;
+       char *prefix;
        size_t prefix_len;
        char **exclude_patterns;
        size_t exclude_patterns_index;
@@ -718,6 +718,20 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
        return ITER_OK;
 }
 
+static int reftable_ref_iterator_seek(struct ref_iterator *ref_iterator,
+                                     const char *prefix)
+{
+       struct reftable_ref_iterator *iter =
+               (struct reftable_ref_iterator *)ref_iterator;
+
+       free(iter->prefix);
+       iter->prefix = xstrdup_or_null(prefix);
+       iter->prefix_len = prefix ? strlen(prefix) : 0;
+       iter->err = reftable_iterator_seek_ref(&iter->iter, prefix);
+
+       return iter->err;
+}
+
 static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator,
                                      struct object_id *peeled)
 {
@@ -744,10 +758,12 @@ static void reftable_ref_iterator_release(struct ref_iterator *ref_iterator)
                        free(iter->exclude_patterns[i]);
                free(iter->exclude_patterns);
        }
+       free(iter->prefix);
 }
 
 static struct ref_iterator_vtable reftable_ref_iterator_vtable = {
        .advance = reftable_ref_iterator_advance,
+       .seek = reftable_ref_iterator_seek,
        .peel = reftable_ref_iterator_peel,
        .release = reftable_ref_iterator_release,
 };
@@ -806,8 +822,6 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
 
        iter = xcalloc(1, sizeof(*iter));
        base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable);
-       iter->prefix = prefix;
-       iter->prefix_len = prefix ? strlen(prefix) : 0;
        iter->base.oid = &iter->oid;
        iter->flags = flags;
        iter->refs = refs;
@@ -821,8 +835,11 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
        if (ret)
                goto done;
 
-       reftable_stack_init_ref_iterator(stack, &iter->iter);
-       ret = reftable_iterator_seek_ref(&iter->iter, prefix);
+       ret = reftable_stack_init_ref_iterator(stack, &iter->iter);
+       if (ret)
+               goto done;
+
+       ret = reftable_ref_iterator_seek(&iter->base, prefix);
        if (ret)
                goto done;
 
@@ -2018,6 +2035,13 @@ static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator)
        return ITER_OK;
 }
 
+static int reftable_reflog_iterator_seek(struct ref_iterator *ref_iterator UNUSED,
+                                        const char *prefix UNUSED)
+{
+       BUG("reftable reflog iterator cannot be seeked");
+       return -1;
+}
+
 static int reftable_reflog_iterator_peel(struct ref_iterator *ref_iterator UNUSED,
                                         struct object_id *peeled UNUSED)
 {
@@ -2036,6 +2060,7 @@ static void reftable_reflog_iterator_release(struct ref_iterator *ref_iterator)
 
 static struct ref_iterator_vtable reftable_reflog_iterator_vtable = {
        .advance = reftable_reflog_iterator_advance,
+       .seek = reftable_reflog_iterator_seek,
        .peel = reftable_reflog_iterator_peel,
        .release = reftable_reflog_iterator_release,
 };