
In 67ce50ba26
(Merge branch 'ps/reftable-reusable-iterator', 2024-05-30)
we have refactored the interface of reftable iterators such that they
can be reused in theory. This patch series only landed the required
changes on the interface level, but didn't yet implement the actual
logic to make iterators reusable.
As it turns out almost all of the infrastructure already does support
re-seeking. The only exception is the table iterator, which does not
reset its `is_finished` bit. Do so and add a couple of tests that verify
that we can re-seek iterators.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
97 lines
2.4 KiB
C
97 lines
2.4 KiB
C
#include "test-lib.h"
|
|
#include "lib-reftable.h"
|
|
#include "reftable/blocksource.h"
|
|
#include "reftable/reader.h"
|
|
|
|
static int t_reader_seek_once(void)
|
|
{
|
|
struct reftable_ref_record records[] = {
|
|
{
|
|
.refname = (char *) "refs/heads/main",
|
|
.value_type = REFTABLE_REF_VAL1,
|
|
.value.val1 = { 42 },
|
|
},
|
|
};
|
|
struct reftable_block_source source = { 0 };
|
|
struct reftable_ref_record ref = { 0 };
|
|
struct reftable_iterator it = { 0 };
|
|
struct reftable_reader *reader;
|
|
struct strbuf buf = STRBUF_INIT;
|
|
int ret;
|
|
|
|
t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL);
|
|
block_source_from_strbuf(&source, &buf);
|
|
|
|
ret = reftable_reader_new(&reader, &source, "name");
|
|
check(!ret);
|
|
|
|
reftable_reader_init_ref_iterator(reader, &it);
|
|
ret = reftable_iterator_seek_ref(&it, "");
|
|
check(!ret);
|
|
ret = reftable_iterator_next_ref(&it, &ref);
|
|
check(!ret);
|
|
|
|
ret = reftable_ref_record_equal(&ref, &records[0], GIT_SHA1_RAWSZ);
|
|
check_int(ret, ==, 1);
|
|
|
|
ret = reftable_iterator_next_ref(&it, &ref);
|
|
check_int(ret, ==, 1);
|
|
|
|
reftable_ref_record_release(&ref);
|
|
reftable_iterator_destroy(&it);
|
|
reftable_reader_decref(reader);
|
|
strbuf_release(&buf);
|
|
return 0;
|
|
}
|
|
|
|
static int t_reader_reseek(void)
|
|
{
|
|
struct reftable_ref_record records[] = {
|
|
{
|
|
.refname = (char *) "refs/heads/main",
|
|
.value_type = REFTABLE_REF_VAL1,
|
|
.value.val1 = { 42 },
|
|
},
|
|
};
|
|
struct reftable_block_source source = { 0 };
|
|
struct reftable_ref_record ref = { 0 };
|
|
struct reftable_iterator it = { 0 };
|
|
struct reftable_reader *reader;
|
|
struct strbuf buf = STRBUF_INIT;
|
|
int ret;
|
|
|
|
t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL);
|
|
block_source_from_strbuf(&source, &buf);
|
|
|
|
ret = reftable_reader_new(&reader, &source, "name");
|
|
check(!ret);
|
|
|
|
reftable_reader_init_ref_iterator(reader, &it);
|
|
|
|
for (size_t i = 0; i < 5; i++) {
|
|
ret = reftable_iterator_seek_ref(&it, "");
|
|
check(!ret);
|
|
ret = reftable_iterator_next_ref(&it, &ref);
|
|
check(!ret);
|
|
|
|
ret = reftable_ref_record_equal(&ref, &records[0], GIT_SHA1_RAWSZ);
|
|
check_int(ret, ==, 1);
|
|
|
|
ret = reftable_iterator_next_ref(&it, &ref);
|
|
check_int(ret, ==, 1);
|
|
}
|
|
|
|
reftable_ref_record_release(&ref);
|
|
reftable_iterator_destroy(&it);
|
|
reftable_reader_decref(reader);
|
|
strbuf_release(&buf);
|
|
return 0;
|
|
}
|
|
|
|
int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
|
|
{
|
|
TEST(t_reader_seek_once(), "reader can seek once");
|
|
TEST(t_reader_reseek(), "reader can reseek multiple times");
|
|
return test_done();
|
|
}
|