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