reftable/reader: adapt interface to allow reuse of iterators
Refactor the interfaces exposed by `struct reftable_reader` and `struct table_iterator` such that they support iterator reuse. This is done by separating initialization of the iterator and seeking on it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
May 13, 2024 at 10:47 UTC
0e7be2b3ea444fc5375e76e42d81b1e1d3d4971f
3 files changed
+35
-76
reftable/reader.c
+4
-27
@@ -621,39 +621,16 @@ static void reader_init_iter(struct reftable_reader *r,
621
}
622
}
623
624
-int reftable_reader_seek_ref(struct reftable_reader *r,
625
- struct reftable_iterator *it, const char *name)
624
+void reftable_reader_init_ref_iterator(struct reftable_reader *r,
625
+ struct reftable_iterator *it)
626
{
627
- struct reftable_record rec = {
628
- .type = BLOCK_TYPE_REF,
629
- .u.ref = {
630
- .refname = (char *)name,
631
- },
632
- };
627
reader_init_iter(r, it, BLOCK_TYPE_REF);
634
- return iterator_seek(it, &rec);
628
}
629
637
-int reftable_reader_seek_log_at(struct reftable_reader *r,
638
- struct reftable_iterator *it, const char *name,
639
- uint64_t update_index)
630
+void reftable_reader_init_log_iterator(struct reftable_reader *r,
631
+ struct reftable_iterator *it)
632
{
641
- struct reftable_record rec = {
642
- .type = BLOCK_TYPE_LOG,
643
- .u.log = {
644
- .refname = (char *)name,
645
- .update_index = update_index,
646
- },
647
- };
633
reader_init_iter(r, it, BLOCK_TYPE_LOG);
649
- return iterator_seek(it, &rec);
650
-}
651
-
652
-int reftable_reader_seek_log(struct reftable_reader *r,
653
- struct reftable_iterator *it, const char *name)
654
-{
655
- uint64_t max = ~((uint64_t)0);
656
- return reftable_reader_seek_log_at(r, it, name, max);
634
}
635
636
void reader_close(struct reftable_reader *r)
reftable/readwrite_test.c
+24
-11
@@ -239,7 +239,9 @@ static void test_log_write_read(void)
239
err = init_reader(&rd, &source, "file.log");
240
EXPECT_ERR(err);
241
242
- err = reftable_reader_seek_ref(&rd, &it, names[N - 1]);
242
+ reftable_reader_init_ref_iterator(&rd, &it);
243
+
244
+ err = reftable_iterator_seek_ref(&it, names[N - 1]);
245
EXPECT_ERR(err);
246
247
err = reftable_iterator_next_ref(&it, &ref);
@@ -252,7 +254,9 @@ static void test_log_write_read(void)
254
reftable_iterator_destroy(&it);
255
reftable_ref_record_release(&ref);
256
255
- err = reftable_reader_seek_log(&rd, &it, "");
257
+ reftable_reader_init_log_iterator(&rd, &it);
258
+
259
+ err = reftable_iterator_seek_log(&it, "");
260
EXPECT_ERR(err);
261
262
i = 0;
@@ -330,7 +334,8 @@ static void test_log_zlib_corruption(void)
334
err = init_reader(&rd, &source, "file.log");
335
EXPECT_ERR(err);
336
333
- err = reftable_reader_seek_log(&rd, &it, "refname");
337
+ reftable_reader_init_log_iterator(&rd, &it);
338
+ err = reftable_iterator_seek_log(&it, "refname");
339
EXPECT(err == REFTABLE_ZLIB_ERROR);
340
341
reftable_iterator_destroy(&it);
@@ -358,7 +363,8 @@ static void test_table_read_write_sequential(void)
363
err = init_reader(&rd, &source, "file.ref");
364
EXPECT_ERR(err);
365
361
- err = reftable_reader_seek_ref(&rd, &it, "");
366
+ reftable_reader_init_ref_iterator(&rd, &it);
367
+ err = reftable_iterator_seek_ref(&it, "");
368
EXPECT_ERR(err);
369
370
while (1) {
@@ -412,7 +418,8 @@ static void test_table_read_api(void)
418
err = init_reader(&rd, &source, "file.ref");
419
EXPECT_ERR(err);
420
415
- err = reftable_reader_seek_ref(&rd, &it, names[0]);
421
+ reftable_reader_init_ref_iterator(&rd, &it);
422
+ err = reftable_iterator_seek_ref(&it, names[0]);
423
EXPECT_ERR(err);
424
425
err = reftable_iterator_next_log(&it, &log);
@@ -457,7 +464,8 @@ static void test_table_read_write_seek(int index, int hash_id)
464
}
465
466
for (i = 1; i < N; i++) {
460
- int err = reftable_reader_seek_ref(&rd, &it, names[i]);
467
+ reftable_reader_init_ref_iterator(&rd, &it);
468
+ err = reftable_iterator_seek_ref(&it, names[i]);
469
EXPECT_ERR(err);
470
err = reftable_iterator_next_ref(&it, &ref);
471
EXPECT_ERR(err);
@@ -472,7 +480,8 @@ static void test_table_read_write_seek(int index, int hash_id)
480
strbuf_addstr(&pastLast, names[N - 1]);
481
strbuf_addstr(&pastLast, "/");
482
475
- err = reftable_reader_seek_ref(&rd, &it, pastLast.buf);
483
+ reftable_reader_init_ref_iterator(&rd, &it);
484
+ err = reftable_iterator_seek_ref(&it, pastLast.buf);
485
if (err == 0) {
486
struct reftable_ref_record ref = { NULL };
487
int err = reftable_iterator_next_ref(&it, &ref);
@@ -576,7 +585,8 @@ static void test_table_refs_for(int indexed)
585
rd.obj_offsets.is_present = 0;
586
}
587
579
- err = reftable_reader_seek_ref(&rd, &it, "");
588
+ reftable_reader_init_ref_iterator(&rd, &it);
589
+ err = reftable_iterator_seek_ref(&it, "");
590
EXPECT_ERR(err);
591
reftable_iterator_destroy(&it);
592
@@ -639,7 +649,8 @@ static void test_write_empty_table(void)
649
err = reftable_new_reader(&rd, &source, "filename");
650
EXPECT_ERR(err);
651
642
- err = reftable_reader_seek_ref(rd, &it, "");
652
+ reftable_reader_init_ref_iterator(rd, &it);
653
+ err = reftable_iterator_seek_ref(&it, "");
654
EXPECT_ERR(err);
655
656
err = reftable_iterator_next_ref(&it, &rec);
@@ -846,7 +857,8 @@ static void test_write_multiple_indices(void)
857
* Seeking the log uses the log index now. In case there is any
858
* confusion regarding indices we would notice here.
859
*/
849
- err = reftable_reader_seek_log(reader, &it, "");
860
+ reftable_reader_init_log_iterator(reader, &it);
861
+ err = reftable_iterator_seek_log(&it, "");
862
EXPECT_ERR(err);
863
864
reftable_iterator_destroy(&it);
@@ -901,7 +913,8 @@ static void test_write_multi_level_index(void)
913
/*
914
* Seeking the last ref should work as expected.
915
*/
904
- err = reftable_reader_seek_ref(reader, &it, "refs/heads/199");
916
+ reftable_reader_init_ref_iterator(reader, &it);
917
+ err = reftable_iterator_seek_ref(&it, "refs/heads/199");
918
EXPECT_ERR(err);
919
920
reftable_iterator_destroy(&it);
reftable/reftable-reader.h
+7
-38
@@ -36,48 +36,17 @@ struct reftable_table;
36
int reftable_new_reader(struct reftable_reader **pp,
37
struct reftable_block_source *src, const char *name);
38
39
-/* reftable_reader_seek_ref returns an iterator where 'name' would be inserted
40
- in the table. To seek to the start of the table, use name = "".
41
-
42
- example:
43
-
44
- struct reftable_reader *r = NULL;
45
- int err = reftable_new_reader(&r, &src, "filename");
46
- if (err < 0) { ... }
47
- struct reftable_iterator it = {0};
48
- err = reftable_reader_seek_ref(r, &it, "refs/heads/master");
49
- if (err < 0) { ... }
50
- struct reftable_ref_record ref = {0};
51
- while (1) {
52
- err = reftable_iterator_next_ref(&it, &ref);
53
- if (err > 0) {
54
- break;
55
- }
56
- if (err < 0) {
57
- ..error handling..
58
- }
59
- ..found..
60
- }
61
- reftable_iterator_destroy(&it);
62
- reftable_ref_record_release(&ref);
63
-*/
64
-int reftable_reader_seek_ref(struct reftable_reader *r,
65
- struct reftable_iterator *it, const char *name);
39
+/* Initialize a reftable iterator for reading refs. */
40
+void reftable_reader_init_ref_iterator(struct reftable_reader *r,
41
+ struct reftable_iterator *it);
42
+
43
+/* Initialize a reftable iterator for reading logs. */
44
+void reftable_reader_init_log_iterator(struct reftable_reader *r,
45
+ struct reftable_iterator *it);
46
47
/* returns the hash ID used in this table. */
48
uint32_t reftable_reader_hash_id(struct reftable_reader *r);
49
70
-/* seek to logs for the given name, older than update_index. To seek to the
71
- start of the table, use name = "".
72
-*/
73
-int reftable_reader_seek_log_at(struct reftable_reader *r,
74
- struct reftable_iterator *it, const char *name,
75
- uint64_t update_index);
76
-
77
-/* seek to newest log entry for given name. */
78
-int reftable_reader_seek_log(struct reftable_reader *r,
79
- struct reftable_iterator *it, const char *name);
80
-
50
/* closes and deallocates a reader. */
51
void reftable_reader_free(struct reftable_reader *);
52