reftable/stack: provide convenience functions to create iterators
There exist a bunch of call sites in the reftable backend that want to create iterators for a reftable stack. This is rather convoluted right now, where you always have to go via the merged table. And it is about to become even more convoluted when we split up iterator initialization and seeking in the next commit. Introduce convenience functions that allow the caller to create an iterator from a reftable stack directly without going through the merged table. Adapt callers accordingly. 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
08efe69212fc158fb17294fc3396fa9d048d2285
5 files changed
+63
-30
refs/reftable-backend.c
+21
-27
@@ -15,7 +15,6 @@
15
#include "../reftable/reftable-record.h"
16
#include "../reftable/reftable-error.h"
17
#include "../reftable/reftable-iterator.h"
18
-#include "../reftable/reftable-merged.h"
18
#include "../setup.h"
19
#include "../strmap.h"
20
#include "parse.h"
@@ -462,7 +461,6 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
461
const char *prefix,
462
int flags)
463
{
465
- struct reftable_merged_table *merged_table;
464
struct reftable_ref_iterator *iter;
465
int ret;
466
@@ -482,9 +480,8 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
480
if (ret)
481
goto done;
482
485
- merged_table = reftable_stack_merged_table(stack);
486
-
487
- ret = reftable_merged_table_seek_ref(merged_table, &iter->iter, prefix);
483
+ reftable_stack_init_ref_iterator(stack, &iter->iter);
484
+ ret = reftable_iterator_seek_ref(&iter->iter, prefix);
485
if (ret)
486
goto done;
487
@@ -1015,8 +1012,6 @@ static int transaction_update_cmp(const void *a, const void *b)
1012
static int write_transaction_table(struct reftable_writer *writer, void *cb_data)
1013
{
1014
struct write_transaction_table_arg *arg = cb_data;
1018
- struct reftable_merged_table *mt =
1019
- reftable_stack_merged_table(arg->stack);
1015
uint64_t ts = reftable_stack_next_update_index(arg->stack);
1016
struct reftable_log_record *logs = NULL;
1017
struct ident_split committer_ident = {0};
@@ -1051,6 +1046,8 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
1046
struct reftable_log_record log = {0};
1047
struct reftable_iterator it = {0};
1048
1049
+ reftable_stack_init_log_iterator(arg->stack, &it);
1050
+
1051
/*
1052
* When deleting refs we also delete all reflog entries
1053
* with them. While it is not strictly required to
@@ -1060,7 +1057,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
1057
* Unfortunately, we have no better way than to delete
1058
* all reflog entries one by one.
1059
*/
1063
- ret = reftable_merged_table_seek_log(mt, &it, u->refname);
1060
+ ret = reftable_iterator_seek_log(&it, u->refname);
1061
while (ret == 0) {
1062
struct reftable_log_record *tombstone;
1063
@@ -1354,7 +1351,6 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
1351
{
1352
struct write_copy_arg *arg = cb_data;
1353
uint64_t deletion_ts, creation_ts;
1357
- struct reftable_merged_table *mt = reftable_stack_merged_table(arg->stack);
1354
struct reftable_ref_record old_ref = {0}, refs[2] = {0};
1355
struct reftable_log_record old_log = {0}, *logs = NULL;
1356
struct reftable_iterator it = {0};
@@ -1488,7 +1484,8 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
1484
* copy over all log entries from the old reflog. Last but not least,
1485
* when renaming we also have to delete all the old reflog entries.
1486
*/
1491
- ret = reftable_merged_table_seek_log(mt, &it, arg->oldname);
1487
+ reftable_stack_init_log_iterator(arg->stack, &it);
1488
+ ret = reftable_iterator_seek_log(&it, arg->oldname);
1489
if (ret < 0)
1490
goto done;
1491
@@ -1694,7 +1691,6 @@ static struct ref_iterator_vtable reftable_reflog_iterator_vtable = {
1691
static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftable_ref_store *refs,
1692
struct reftable_stack *stack)
1693
{
1697
- struct reftable_merged_table *merged_table;
1694
struct reftable_reflog_iterator *iter;
1695
int ret;
1696
@@ -1711,9 +1707,8 @@ static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftabl
1707
if (ret < 0)
1708
goto done;
1709
1714
- merged_table = reftable_stack_merged_table(stack);
1715
-
1716
- ret = reftable_merged_table_seek_log(merged_table, &iter->iter, "");
1710
+ reftable_stack_init_log_iterator(stack, &iter->iter);
1711
+ ret = reftable_iterator_seek_log(&iter->iter, "");
1712
if (ret < 0)
1713
goto done;
1714
@@ -1771,7 +1766,6 @@ static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store,
1766
struct reftable_ref_store *refs =
1767
reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent_reverse");
1768
struct reftable_stack *stack = stack_for(refs, refname, &refname);
1774
- struct reftable_merged_table *mt = NULL;
1769
struct reftable_log_record log = {0};
1770
struct reftable_iterator it = {0};
1771
int ret;
@@ -1779,8 +1773,8 @@ static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store,
1773
if (refs->err < 0)
1774
return refs->err;
1775
1782
- mt = reftable_stack_merged_table(stack);
1783
- ret = reftable_merged_table_seek_log(mt, &it, refname);
1776
+ reftable_stack_init_log_iterator(stack, &it);
1777
+ ret = reftable_iterator_seek_log(&it, refname);
1778
while (!ret) {
1779
ret = reftable_iterator_next_log(&it, &log);
1780
if (ret < 0)
@@ -1808,7 +1802,6 @@ static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store,
1802
struct reftable_ref_store *refs =
1803
reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent");
1804
struct reftable_stack *stack = stack_for(refs, refname, &refname);
1811
- struct reftable_merged_table *mt = NULL;
1805
struct reftable_log_record *logs = NULL;
1806
struct reftable_iterator it = {0};
1807
size_t logs_alloc = 0, logs_nr = 0, i;
@@ -1817,8 +1810,8 @@ static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store,
1810
if (refs->err < 0)
1811
return refs->err;
1812
1820
- mt = reftable_stack_merged_table(stack);
1821
- ret = reftable_merged_table_seek_log(mt, &it, refname);
1813
+ reftable_stack_init_log_iterator(stack, &it);
1814
+ ret = reftable_iterator_seek_log(&it, refname);
1815
while (!ret) {
1816
struct reftable_log_record log = {0};
1817
@@ -1855,7 +1848,6 @@ static int reftable_be_reflog_exists(struct ref_store *ref_store,
1848
struct reftable_ref_store *refs =
1849
reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_exists");
1850
struct reftable_stack *stack = stack_for(refs, refname, &refname);
1858
- struct reftable_merged_table *mt = reftable_stack_merged_table(stack);
1851
struct reftable_log_record log = {0};
1852
struct reftable_iterator it = {0};
1853
int ret;
@@ -1868,7 +1860,8 @@ static int reftable_be_reflog_exists(struct ref_store *ref_store,
1860
if (ret < 0)
1861
goto done;
1862
1871
- ret = reftable_merged_table_seek_log(mt, &it, refname);
1863
+ reftable_stack_init_log_iterator(stack, &it);
1864
+ ret = reftable_iterator_seek_log(&it, refname);
1865
if (ret < 0)
1866
goto done;
1867
@@ -1966,8 +1959,6 @@ struct write_reflog_delete_arg {
1959
static int write_reflog_delete_table(struct reftable_writer *writer, void *cb_data)
1960
{
1961
struct write_reflog_delete_arg *arg = cb_data;
1969
- struct reftable_merged_table *mt =
1970
- reftable_stack_merged_table(arg->stack);
1962
struct reftable_log_record log = {0}, tombstone = {0};
1963
struct reftable_iterator it = {0};
1964
uint64_t ts = reftable_stack_next_update_index(arg->stack);
@@ -1975,12 +1966,14 @@ static int write_reflog_delete_table(struct reftable_writer *writer, void *cb_da
1966
1967
reftable_writer_set_limits(writer, ts, ts);
1968
1969
+ reftable_stack_init_log_iterator(arg->stack, &it);
1970
+
1971
/*
1972
* In order to delete a table we need to delete all reflog entries one
1973
* by one. This is inefficient, but the reftable format does not have a
1974
* better marker right now.
1975
*/
1983
- ret = reftable_merged_table_seek_log(mt, &it, arg->refname);
1976
+ ret = reftable_iterator_seek_log(&it, arg->refname);
1977
while (ret == 0) {
1978
ret = reftable_iterator_next_log(&it, &log);
1979
if (ret < 0)
@@ -2116,7 +2109,6 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
2109
struct reftable_ref_store *refs =
2110
reftable_be_downcast(ref_store, REF_STORE_WRITE, "reflog_expire");
2111
struct reftable_stack *stack = stack_for(refs, refname, &refname);
2119
- struct reftable_merged_table *mt = reftable_stack_merged_table(stack);
2112
struct reftable_log_record *logs = NULL;
2113
struct reftable_log_record *rewritten = NULL;
2114
struct reftable_ref_record ref_record = {0};
@@ -2135,7 +2127,9 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
2127
if (ret < 0)
2128
goto done;
2129
2138
- ret = reftable_merged_table_seek_log(mt, &it, refname);
2130
+ reftable_stack_init_log_iterator(stack, &it);
2131
+
2132
+ ret = reftable_iterator_seek_log(&it, refname);
2133
if (ret < 0)
2134
goto done;
2135
reftable/merged.c
+3
-3
@@ -253,9 +253,9 @@ reftable_merged_table_min_update_index(struct reftable_merged_table *mt)
253
return mt->min;
254
}
255
256
-static void merged_table_init_iter(struct reftable_merged_table *mt,
257
- struct reftable_iterator *it,
258
- uint8_t typ)
256
+void merged_table_init_iter(struct reftable_merged_table *mt,
257
+ struct reftable_iterator *it,
258
+ uint8_t typ)
259
{
260
struct merged_iter *mi = reftable_malloc(sizeof(*mi));
261
merged_iter_init(mi, mt, typ);
reftable/merged.h
+6
@@ -26,4 +26,10 @@ struct reftable_merged_table {
26
27
void merged_table_release(struct reftable_merged_table *mt);
28
29
+struct reftable_iterator;
30
+
31
+void merged_table_init_iter(struct reftable_merged_table *mt,
32
+ struct reftable_iterator *it,
33
+ uint8_t typ);
34
+
35
#endif
reftable/reftable-stack.h
+18
@@ -66,6 +66,24 @@ int reftable_stack_add(struct reftable_stack *st,
66
void *write_arg),
67
void *write_arg);
68
69
+struct reftable_iterator;
70
+
71
+/*
72
+ * Initialize an iterator for the merged tables contained in the stack that can
73
+ * be used to iterate through refs. The iterator is valid until the next reload
74
+ * or write.
75
+ */
76
+void reftable_stack_init_ref_iterator(struct reftable_stack *st,
77
+ struct reftable_iterator *it);
78
+
79
+/*
80
+ * Initialize an iterator for the merged tables contained in the stack that can
81
+ * be used to iterate through logs. The iterator is valid until the next reload
82
+ * or write.
83
+ */
84
+void reftable_stack_init_log_iterator(struct reftable_stack *st,
85
+ struct reftable_iterator *it);
86
+
87
/* returns the merged_table for seeking. This table is valid until the
88
* next write or reload, and should not be closed or deleted.
89
*/
reftable/stack.c
+15
@@ -10,6 +10,7 @@ https://developers.google.com/open-source/licenses/bsd
10
11
#include "../write-or-die.h"
12
#include "system.h"
13
+#include "constants.h"
14
#include "merged.h"
15
#include "reader.h"
16
#include "reftable-error.h"
@@ -130,6 +131,20 @@ int read_lines(const char *filename, char ***namesp)
131
return err;
132
}
133
134
+void reftable_stack_init_ref_iterator(struct reftable_stack *st,
135
+ struct reftable_iterator *it)
136
+{
137
+ merged_table_init_iter(reftable_stack_merged_table(st),
138
+ it, BLOCK_TYPE_REF);
139
+}
140
+
141
+void reftable_stack_init_log_iterator(struct reftable_stack *st,
142
+ struct reftable_iterator *it)
143
+{
144
+ merged_table_init_iter(reftable_stack_merged_table(st),
145
+ it, BLOCK_TYPE_LOG);
146
+}
147
+
148
struct reftable_merged_table *
149
reftable_stack_merged_table(struct reftable_stack *st)
150
{