reftable/generic: adapt interface to allow reuse of iterators
Refactor the interfaces exposed by `struct reftable_table` and `struct reftable_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
d76f0d3f57184e05eeabbe7bb382ae87149f0dd9
4 files changed
+68
-22
reftable/generic.c
+39
-14
@@ -20,8 +20,20 @@ void table_init_iter(struct reftable_table *tab,
20
tab->ops->init_iter(tab->table_arg, it, typ);
21
}
22
23
-int reftable_table_seek_ref(struct reftable_table *tab,
24
- struct reftable_iterator *it, const char *name)
23
+void reftable_table_init_ref_iter(struct reftable_table *tab,
24
+ struct reftable_iterator *it)
25
+{
26
+ table_init_iter(tab, it, BLOCK_TYPE_REF);
27
+}
28
+
29
+void reftable_table_init_log_iter(struct reftable_table *tab,
30
+ struct reftable_iterator *it)
31
+{
32
+ table_init_iter(tab, it, BLOCK_TYPE_LOG);
33
+}
34
+
35
+int reftable_iterator_seek_ref(struct reftable_iterator *it,
36
+ const char *name)
37
{
38
struct reftable_record want = {
39
.type = BLOCK_TYPE_REF,
@@ -29,29 +41,37 @@ int reftable_table_seek_ref(struct reftable_table *tab,
41
.refname = (char *)name,
42
},
43
};
32
- table_init_iter(tab, it, BLOCK_TYPE_REF);
44
return it->ops->seek(it->iter_arg, &want);
45
}
46
36
-int reftable_table_seek_log(struct reftable_table *tab,
37
- struct reftable_iterator *it, const char *name)
47
+int reftable_iterator_seek_log_at(struct reftable_iterator *it,
48
+ const char *name, uint64_t update_index)
49
{
50
struct reftable_record want = {
51
.type = BLOCK_TYPE_LOG,
52
.u.log = {
53
.refname = (char *)name,
43
- .update_index = ~((uint64_t)0),
54
+ .update_index = update_index,
55
},
56
};
46
- table_init_iter(tab, it, BLOCK_TYPE_LOG);
57
return it->ops->seek(it->iter_arg, &want);
58
}
59
60
+int reftable_iterator_seek_log(struct reftable_iterator *it,
61
+ const char *name)
62
+{
63
+ return reftable_iterator_seek_log_at(it, name, ~((uint64_t) 0));
64
+}
65
+
66
int reftable_table_read_ref(struct reftable_table *tab, const char *name,
67
struct reftable_ref_record *ref)
68
{
69
struct reftable_iterator it = { NULL };
54
- int err = reftable_table_seek_ref(tab, &it, name);
70
+ int err;
71
+
72
+ reftable_table_init_ref_iter(tab, &it);
73
+
74
+ err = reftable_iterator_seek_ref(&it, name);
75
if (err)
76
goto done;
77
@@ -76,10 +96,13 @@ int reftable_table_print(struct reftable_table *tab) {
96
struct reftable_ref_record ref = { NULL };
97
struct reftable_log_record log = { NULL };
98
uint32_t hash_id = reftable_table_hash_id(tab);
79
- int err = reftable_table_seek_ref(tab, &it, "");
80
- if (err < 0) {
99
+ int err;
100
+
101
+ reftable_table_init_ref_iter(tab, &it);
102
+
103
+ err = reftable_iterator_seek_ref(&it, "");
104
+ if (err < 0)
105
return err;
82
- }
106
107
while (1) {
108
err = reftable_iterator_next_ref(&it, &ref);
@@ -94,10 +117,12 @@ int reftable_table_print(struct reftable_table *tab) {
117
reftable_iterator_destroy(&it);
118
reftable_ref_record_release(&ref);
119
97
- err = reftable_table_seek_log(tab, &it, "");
98
- if (err < 0) {
120
+ reftable_table_init_log_iter(tab, &it);
121
+
122
+ err = reftable_iterator_seek_log(&it, "");
123
+ if (err < 0)
124
return err;
100
- }
125
+
126
while (1) {
127
err = reftable_iterator_next_log(&it, &log);
128
if (err > 0) {
reftable/iter.c
+4
-4
@@ -45,11 +45,11 @@ static int filtering_ref_iterator_next(void *iter_arg,
45
if (fri->double_check) {
46
struct reftable_iterator it = { NULL };
47
48
- err = reftable_table_seek_ref(&fri->tab, &it,
49
- ref->refname);
50
- if (err == 0) {
48
+ reftable_table_init_ref_iter(&fri->tab, &it);
49
+
50
+ err = reftable_iterator_seek_ref(&it, ref->refname);
51
+ if (err == 0)
52
err = reftable_iterator_next_ref(&it, ref);
52
- }
53
54
reftable_iterator_destroy(&it);
55
reftable/reftable-generic.h
+4
-4
@@ -21,11 +21,11 @@ struct reftable_table {
21
void *table_arg;
22
};
23
24
-int reftable_table_seek_log(struct reftable_table *tab,
25
- struct reftable_iterator *it, const char *name);
24
+void reftable_table_init_ref_iter(struct reftable_table *tab,
25
+ struct reftable_iterator *it);
26
27
-int reftable_table_seek_ref(struct reftable_table *tab,
28
- struct reftable_iterator *it, const char *name);
27
+void reftable_table_init_log_iter(struct reftable_table *tab,
28
+ struct reftable_iterator *it);
29
30
/* returns the hash ID from a generic reftable_table */
31
uint32_t reftable_table_hash_id(struct reftable_table *tab);
reftable/reftable-iterator.h
+21
@@ -21,12 +21,33 @@ struct reftable_iterator {
21
void *iter_arg;
22
};
23
24
+/*
25
+ * Position the iterator at the ref record with given name such that the next
26
+ * call to `next_ref()` would yield the record.
27
+ */
28
+int reftable_iterator_seek_ref(struct reftable_iterator *it,
29
+ const char *name);
30
+
31
/* reads the next reftable_ref_record. Returns < 0 for error, 0 for OK and > 0:
32
* end of iteration.
33
*/
34
int reftable_iterator_next_ref(struct reftable_iterator *it,
35
struct reftable_ref_record *ref);
36
37
+/*
38
+ * Position the iterator at the log record with given name and update index
39
+ * such that the next call to `next_log()` would yield the record.
40
+ */
41
+int reftable_iterator_seek_log_at(struct reftable_iterator *it,
42
+ const char *name, uint64_t update_index);
43
+
44
+/*
45
+ * Position the iterator at the newest log record with given name such that the
46
+ * next call to `next_log()` would yield the record.
47
+ */
48
+int reftable_iterator_seek_log(struct reftable_iterator *it,
49
+ const char *name);
50
+
51
/* reads the next reftable_log_record. Returns < 0 for error, 0 for OK and > 0:
52
* end of iteration.
53
*/