Skip to content

Commit 67ce50b

Browse files
committed
Merge branch 'ps/reftable-reusable-iterator'
Code clean-up to make the reftable iterator closer to be reusable. * ps/reftable-reusable-iterator: reftable/merged: adapt interface to allow reuse of iterators reftable/stack: provide convenience functions to create iterators reftable/reader: adapt interface to allow reuse of iterators reftable/generic: adapt interface to allow reuse of iterators reftable/generic: move seeking of records into the iterator reftable/merged: simplify indices for subiterators reftable/merged: split up initialization and seeking of records reftable/reader: set up the reader when initializing table iterator reftable/reader: inline `reader_seek_internal()` reftable/reader: separate concerns of table iter and reftable reader reftable/reader: unify indexed and linear seeking reftable/reader: avoid copying index iterator reftable/block: use `size_t` to track restart point index
2 parents 23528d3 + 369b841 commit 67ce50b

16 files changed

+381
-364
lines changed

refs/reftable-backend.c

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "../reftable/reftable-record.h"
1717
#include "../reftable/reftable-error.h"
1818
#include "../reftable/reftable-iterator.h"
19-
#include "../reftable/reftable-merged.h"
2019
#include "../setup.h"
2120
#include "../strmap.h"
2221
#include "parse.h"
@@ -502,7 +501,6 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
502501
const char *prefix,
503502
int flags)
504503
{
505-
struct reftable_merged_table *merged_table;
506504
struct reftable_ref_iterator *iter;
507505
int ret;
508506

@@ -522,9 +520,8 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
522520
if (ret)
523521
goto done;
524522

525-
merged_table = reftable_stack_merged_table(stack);
526-
527-
ret = reftable_merged_table_seek_ref(merged_table, &iter->iter, prefix);
523+
reftable_stack_init_ref_iterator(stack, &iter->iter);
524+
ret = reftable_iterator_seek_ref(&iter->iter, prefix);
528525
if (ret)
529526
goto done;
530527

@@ -1052,8 +1049,6 @@ static int transaction_update_cmp(const void *a, const void *b)
10521049
static int write_transaction_table(struct reftable_writer *writer, void *cb_data)
10531050
{
10541051
struct write_transaction_table_arg *arg = cb_data;
1055-
struct reftable_merged_table *mt =
1056-
reftable_stack_merged_table(arg->stack);
10571052
uint64_t ts = reftable_stack_next_update_index(arg->stack);
10581053
struct reftable_log_record *logs = NULL;
10591054
struct ident_split committer_ident = {0};
@@ -1090,6 +1085,8 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
10901085
struct reftable_log_record log = {0};
10911086
struct reftable_iterator it = {0};
10921087

1088+
reftable_stack_init_log_iterator(arg->stack, &it);
1089+
10931090
/*
10941091
* When deleting refs we also delete all reflog entries
10951092
* with them. While it is not strictly required to
@@ -1099,7 +1096,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
10991096
* Unfortunately, we have no better way than to delete
11001097
* all reflog entries one by one.
11011098
*/
1102-
ret = reftable_merged_table_seek_log(mt, &it, u->refname);
1099+
ret = reftable_iterator_seek_log(&it, u->refname);
11031100
while (ret == 0) {
11041101
struct reftable_log_record *tombstone;
11051102

@@ -1317,7 +1314,6 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
13171314
{
13181315
struct write_copy_arg *arg = cb_data;
13191316
uint64_t deletion_ts, creation_ts;
1320-
struct reftable_merged_table *mt = reftable_stack_merged_table(arg->stack);
13211317
struct reftable_ref_record old_ref = {0}, refs[2] = {0};
13221318
struct reftable_log_record old_log = {0}, *logs = NULL;
13231319
struct reftable_iterator it = {0};
@@ -1451,7 +1447,8 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
14511447
* copy over all log entries from the old reflog. Last but not least,
14521448
* when renaming we also have to delete all the old reflog entries.
14531449
*/
1454-
ret = reftable_merged_table_seek_log(mt, &it, arg->oldname);
1450+
reftable_stack_init_log_iterator(arg->stack, &it);
1451+
ret = reftable_iterator_seek_log(&it, arg->oldname);
14551452
if (ret < 0)
14561453
goto done;
14571454

@@ -1657,7 +1654,6 @@ static struct ref_iterator_vtable reftable_reflog_iterator_vtable = {
16571654
static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftable_ref_store *refs,
16581655
struct reftable_stack *stack)
16591656
{
1660-
struct reftable_merged_table *merged_table;
16611657
struct reftable_reflog_iterator *iter;
16621658
int ret;
16631659

@@ -1674,9 +1670,8 @@ static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftabl
16741670
if (ret < 0)
16751671
goto done;
16761672

1677-
merged_table = reftable_stack_merged_table(stack);
1678-
1679-
ret = reftable_merged_table_seek_log(merged_table, &iter->iter, "");
1673+
reftable_stack_init_log_iterator(stack, &iter->iter);
1674+
ret = reftable_iterator_seek_log(&iter->iter, "");
16801675
if (ret < 0)
16811676
goto done;
16821677

@@ -1734,16 +1729,15 @@ static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store,
17341729
struct reftable_ref_store *refs =
17351730
reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent_reverse");
17361731
struct reftable_stack *stack = stack_for(refs, refname, &refname);
1737-
struct reftable_merged_table *mt = NULL;
17381732
struct reftable_log_record log = {0};
17391733
struct reftable_iterator it = {0};
17401734
int ret;
17411735

17421736
if (refs->err < 0)
17431737
return refs->err;
17441738

1745-
mt = reftable_stack_merged_table(stack);
1746-
ret = reftable_merged_table_seek_log(mt, &it, refname);
1739+
reftable_stack_init_log_iterator(stack, &it);
1740+
ret = reftable_iterator_seek_log(&it, refname);
17471741
while (!ret) {
17481742
ret = reftable_iterator_next_log(&it, &log);
17491743
if (ret < 0)
@@ -1771,7 +1765,6 @@ static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store,
17711765
struct reftable_ref_store *refs =
17721766
reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent");
17731767
struct reftable_stack *stack = stack_for(refs, refname, &refname);
1774-
struct reftable_merged_table *mt = NULL;
17751768
struct reftable_log_record *logs = NULL;
17761769
struct reftable_iterator it = {0};
17771770
size_t logs_alloc = 0, logs_nr = 0, i;
@@ -1780,8 +1773,8 @@ static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store,
17801773
if (refs->err < 0)
17811774
return refs->err;
17821775

1783-
mt = reftable_stack_merged_table(stack);
1784-
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);
17851778
while (!ret) {
17861779
struct reftable_log_record log = {0};
17871780

@@ -1818,7 +1811,6 @@ static int reftable_be_reflog_exists(struct ref_store *ref_store,
18181811
struct reftable_ref_store *refs =
18191812
reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_exists");
18201813
struct reftable_stack *stack = stack_for(refs, refname, &refname);
1821-
struct reftable_merged_table *mt = reftable_stack_merged_table(stack);
18221814
struct reftable_log_record log = {0};
18231815
struct reftable_iterator it = {0};
18241816
int ret;
@@ -1831,7 +1823,8 @@ static int reftable_be_reflog_exists(struct ref_store *ref_store,
18311823
if (ret < 0)
18321824
goto done;
18331825

1834-
ret = reftable_merged_table_seek_log(mt, &it, refname);
1826+
reftable_stack_init_log_iterator(stack, &it);
1827+
ret = reftable_iterator_seek_log(&it, refname);
18351828
if (ret < 0)
18361829
goto done;
18371830

@@ -1929,21 +1922,21 @@ struct write_reflog_delete_arg {
19291922
static int write_reflog_delete_table(struct reftable_writer *writer, void *cb_data)
19301923
{
19311924
struct write_reflog_delete_arg *arg = cb_data;
1932-
struct reftable_merged_table *mt =
1933-
reftable_stack_merged_table(arg->stack);
19341925
struct reftable_log_record log = {0}, tombstone = {0};
19351926
struct reftable_iterator it = {0};
19361927
uint64_t ts = reftable_stack_next_update_index(arg->stack);
19371928
int ret;
19381929

19391930
reftable_writer_set_limits(writer, ts, ts);
19401931

1932+
reftable_stack_init_log_iterator(arg->stack, &it);
1933+
19411934
/*
19421935
* In order to delete a table we need to delete all reflog entries one
19431936
* by one. This is inefficient, but the reftable format does not have a
19441937
* better marker right now.
19451938
*/
1946-
ret = reftable_merged_table_seek_log(mt, &it, arg->refname);
1939+
ret = reftable_iterator_seek_log(&it, arg->refname);
19471940
while (ret == 0) {
19481941
ret = reftable_iterator_next_log(&it, &log);
19491942
if (ret < 0)
@@ -2079,7 +2072,6 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
20792072
struct reftable_ref_store *refs =
20802073
reftable_be_downcast(ref_store, REF_STORE_WRITE, "reflog_expire");
20812074
struct reftable_stack *stack = stack_for(refs, refname, &refname);
2082-
struct reftable_merged_table *mt = reftable_stack_merged_table(stack);
20832075
struct reftable_log_record *logs = NULL;
20842076
struct reftable_log_record *rewritten = NULL;
20852077
struct reftable_ref_record ref_record = {0};
@@ -2098,7 +2090,9 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
20982090
if (ret < 0)
20992091
goto done;
21002092

2101-
ret = reftable_merged_table_seek_log(mt, &it, refname);
2093+
reftable_stack_init_log_iterator(stack, &it);
2094+
2095+
ret = reftable_iterator_seek_log(&it, refname);
21022096
if (ret < 0)
21032097
goto done;
21042098

reftable/block.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ int block_reader_first_key(const struct block_reader *br, struct strbuf *key)
326326
return 0;
327327
}
328328

329-
static uint32_t block_reader_restart_offset(const struct block_reader *br, int i)
329+
static uint32_t block_reader_restart_offset(const struct block_reader *br, size_t idx)
330330
{
331-
return get_be24(br->restart_bytes + 3 * i);
331+
return get_be24(br->restart_bytes + 3 * idx);
332332
}
333333

334334
void block_iter_seek_start(struct block_iter *it, const struct block_reader *br)

reftable/generic.c

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,66 @@ license that can be found in the LICENSE file or at
1212
#include "reftable-iterator.h"
1313
#include "reftable-generic.h"
1414

15-
int reftable_table_seek_ref(struct reftable_table *tab,
16-
struct reftable_iterator *it, const char *name)
15+
void table_init_iter(struct reftable_table *tab,
16+
struct reftable_iterator *it,
17+
uint8_t typ)
1718
{
18-
struct reftable_record rec = { .type = BLOCK_TYPE_REF,
19-
.u.ref = {
20-
.refname = (char *)name,
21-
} };
22-
return tab->ops->seek_record(tab->table_arg, it, &rec);
19+
20+
tab->ops->init_iter(tab->table_arg, it, typ);
21+
}
22+
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,
40+
.u.ref = {
41+
.refname = (char *)name,
42+
},
43+
};
44+
return it->ops->seek(it->iter_arg, &want);
45+
}
46+
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,
54+
.update_index = update_index,
55+
},
56+
};
57+
return it->ops->seek(it->iter_arg, &want);
2358
}
2459

25-
int reftable_table_seek_log(struct reftable_table *tab,
26-
struct reftable_iterator *it, const char *name)
60+
int reftable_iterator_seek_log(struct reftable_iterator *it,
61+
const char *name)
2762
{
28-
struct reftable_record rec = { .type = BLOCK_TYPE_LOG,
29-
.u.log = {
30-
.refname = (char *)name,
31-
.update_index = ~((uint64_t)0),
32-
} };
33-
return tab->ops->seek_record(tab->table_arg, it, &rec);
63+
return reftable_iterator_seek_log_at(it, name, ~((uint64_t) 0));
3464
}
3565

3666
int reftable_table_read_ref(struct reftable_table *tab, const char *name,
3767
struct reftable_ref_record *ref)
3868
{
3969
struct reftable_iterator it = { NULL };
40-
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);
4175
if (err)
4276
goto done;
4377

@@ -62,10 +96,13 @@ int reftable_table_print(struct reftable_table *tab) {
6296
struct reftable_ref_record ref = { NULL };
6397
struct reftable_log_record log = { NULL };
6498
uint32_t hash_id = reftable_table_hash_id(tab);
65-
int err = reftable_table_seek_ref(tab, &it, "");
66-
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)
67105
return err;
68-
}
69106

70107
while (1) {
71108
err = reftable_iterator_next_ref(&it, &ref);
@@ -80,10 +117,12 @@ int reftable_table_print(struct reftable_table *tab) {
80117
reftable_iterator_destroy(&it);
81118
reftable_ref_record_release(&ref);
82119

83-
err = reftable_table_seek_log(tab, &it, "");
84-
if (err < 0) {
120+
reftable_table_init_log_iter(tab, &it);
121+
122+
err = reftable_iterator_seek_log(&it, "");
123+
if (err < 0)
85124
return err;
86-
}
125+
87126
while (1) {
88127
err = reftable_iterator_next_log(&it, &log);
89128
if (err > 0) {
@@ -152,11 +191,21 @@ int reftable_iterator_next_log(struct reftable_iterator *it,
152191
return err;
153192
}
154193

194+
int iterator_seek(struct reftable_iterator *it, struct reftable_record *want)
195+
{
196+
return it->ops->seek(it->iter_arg, want);
197+
}
198+
155199
int iterator_next(struct reftable_iterator *it, struct reftable_record *rec)
156200
{
157201
return it->ops->next(it->iter_arg, rec);
158202
}
159203

204+
static int empty_iterator_seek(void *arg, struct reftable_record *want)
205+
{
206+
return 0;
207+
}
208+
160209
static int empty_iterator_next(void *arg, struct reftable_record *rec)
161210
{
162211
return 1;
@@ -167,6 +216,7 @@ static void empty_iterator_close(void *arg)
167216
}
168217

169218
static struct reftable_iterator_vtable empty_vtable = {
219+
.seek = &empty_iterator_seek,
170220
.next = &empty_iterator_next,
171221
.close = &empty_iterator_close,
172222
};

reftable/generic.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,24 @@ license that can be found in the LICENSE file or at
1414

1515
/* generic interface to reftables */
1616
struct reftable_table_vtable {
17-
int (*seek_record)(void *tab, struct reftable_iterator *it,
18-
struct reftable_record *);
17+
void (*init_iter)(void *tab, struct reftable_iterator *it, uint8_t typ);
1918
uint32_t (*hash_id)(void *tab);
2019
uint64_t (*min_update_index)(void *tab);
2120
uint64_t (*max_update_index)(void *tab);
2221
};
2322

23+
void table_init_iter(struct reftable_table *tab,
24+
struct reftable_iterator *it,
25+
uint8_t typ);
26+
2427
struct reftable_iterator_vtable {
28+
int (*seek)(void *iter_arg, struct reftable_record *want);
2529
int (*next)(void *iter_arg, struct reftable_record *rec);
2630
void (*close)(void *iter_arg);
2731
};
2832

2933
void iterator_set_empty(struct reftable_iterator *it);
34+
int iterator_seek(struct reftable_iterator *it, struct reftable_record *want);
3035
int iterator_next(struct reftable_iterator *it, struct reftable_record *rec);
3136

3237
#endif

0 commit comments

Comments
 (0)