Skip to content

Commit 6da48a5

Browse files
pks-tgitster
authored andcommitted
reftable/block: make block iterators reseekable
Refactor the block iterators so that initialization and seeking are different from one another. This makes the iterator trivially reseekable by storing the pointer to the block at initialization time, which we can then reuse on every seek. This refactoring prepares the code for exposing a `reftable_iterator` interface for blocks in a subsequent commit. Callsites are adjusted accordingly. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 156d79c commit 6da48a5

File tree

5 files changed

+48
-35
lines changed

5 files changed

+48
-35
lines changed

reftable/block.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -381,11 +381,16 @@ static uint32_t block_restart_offset(const struct reftable_block *b, size_t idx)
381381
return reftable_get_be24(b->block_data.data + b->restart_off + 3 * idx);
382382
}
383383

384-
void block_iter_seek_start(struct block_iter *it, const struct reftable_block *block)
384+
void block_iter_init(struct block_iter *it, const struct reftable_block *block)
385385
{
386386
it->block = block;
387+
block_iter_seek_start(it);
388+
}
389+
390+
void block_iter_seek_start(struct block_iter *it)
391+
{
387392
reftable_buf_reset(&it->last_key);
388-
it->next_off = block->header_off + 4;
393+
it->next_off = it->block->header_off + 4;
389394
}
390395

391396
struct restart_needle_less_args {
@@ -473,12 +478,11 @@ void block_iter_close(struct block_iter *it)
473478
reftable_buf_release(&it->scratch);
474479
}
475480

476-
int block_iter_seek_key(struct block_iter *it, const struct reftable_block *block,
477-
struct reftable_buf *want)
481+
int block_iter_seek_key(struct block_iter *it, struct reftable_buf *want)
478482
{
479483
struct restart_needle_less_args args = {
480484
.needle = *want,
481-
.block = block,
485+
.block = it->block,
482486
};
483487
struct reftable_record rec;
484488
int err = 0;
@@ -496,7 +500,7 @@ int block_iter_seek_key(struct block_iter *it, const struct reftable_block *bloc
496500
* restart point. While that works alright, we would end up scanning
497501
* too many record.
498502
*/
499-
i = binsearch(block->restart_count, &restart_needle_less, &args);
503+
i = binsearch(it->block->restart_count, &restart_needle_less, &args);
500504
if (args.error) {
501505
err = REFTABLE_FORMAT_ERROR;
502506
goto done;
@@ -521,12 +525,11 @@ int block_iter_seek_key(struct block_iter *it, const struct reftable_block *bloc
521525
* starting from the preceding restart point.
522526
*/
523527
if (i > 0)
524-
it->next_off = block_restart_offset(block, i - 1);
528+
it->next_off = block_restart_offset(it->block, i - 1);
525529
else
526-
it->next_off = block->header_off + 4;
527-
it->block = block;
530+
it->next_off = it->block->header_off + 4;
528531

529-
err = reftable_record_init(&rec, reftable_block_type(block));
532+
err = reftable_record_init(&rec, reftable_block_type(it->block));
530533
if (err < 0)
531534
goto done;
532535

reftable/block.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,23 @@ struct block_iter {
7979
.scratch = REFTABLE_BUF_INIT, \
8080
}
8181

82-
/* Position `it` at start of the block */
83-
void block_iter_seek_start(struct block_iter *it, const struct reftable_block *block);
82+
/*
83+
* Initialize the block iterator with the given block. The iterator will be
84+
* positioned at the first record contained in the block. The block must remain
85+
* valid until the end of the iterator's lifetime. It is valid to re-initialize
86+
* iterators multiple times.
87+
*/
88+
void block_iter_init(struct block_iter *it, const struct reftable_block *block);
89+
90+
/* Position the initialized iterator at the first record of its block. */
91+
void block_iter_seek_start(struct block_iter *it);
8492

85-
/* Position `it` to the `want` key in the block */
86-
int block_iter_seek_key(struct block_iter *it, const struct reftable_block *block,
87-
struct reftable_buf *want);
93+
/*
94+
* Position the initialized iterator at the desired record key. It is not an
95+
* error in case the record cannot be found. If so, a subsequent call to
96+
* `block_iter_next()` will indicate that the iterator is exhausted.
97+
*/
98+
int block_iter_seek_key(struct block_iter *it, struct reftable_buf *want);
8899

89100
/* return < 0 for error, 0 for OK, > 0 for EOF. */
90101
int block_iter_next(struct block_iter *it, struct reftable_record *rec);

reftable/iter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter *it)
139139
/* indexed block does not exist. */
140140
return REFTABLE_FORMAT_ERROR;
141141
}
142-
block_iter_seek_start(&it->cur, &it->block);
142+
block_iter_init(&it->cur, &it->block);
143143
return 0;
144144
}
145145

reftable/table.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ static int table_iter_next_block(struct table_iter *ti)
208208

209209
ti->block_off = next_block_off;
210210
ti->is_finished = 0;
211-
block_iter_seek_start(&ti->bi, &ti->block);
211+
block_iter_init(&ti->bi, &ti->block);
212212

213213
return 0;
214214
}
@@ -256,7 +256,7 @@ static int table_iter_seek_to(struct table_iter *ti, uint64_t off, uint8_t typ)
256256

257257
ti->typ = reftable_block_type(&ti->block);
258258
ti->block_off = off;
259-
block_iter_seek_start(&ti->bi, &ti->block);
259+
block_iter_init(&ti->bi, &ti->block);
260260
ti->is_finished = 0;
261261
return 0;
262262
}
@@ -349,7 +349,8 @@ static int table_iter_seek_linear(struct table_iter *ti,
349349
* the wanted key inside of it. If the block does not contain our key
350350
* we know that the corresponding record does not exist.
351351
*/
352-
err = block_iter_seek_key(&ti->bi, &ti->block, &want_key);
352+
block_iter_init(&ti->bi, &ti->block);
353+
err = block_iter_seek_key(&ti->bi, &want_key);
353354
if (err < 0)
354355
goto done;
355356
err = 0;
@@ -417,7 +418,9 @@ static int table_iter_seek_indexed(struct table_iter *ti,
417418
if (err != 0)
418419
goto done;
419420

420-
err = block_iter_seek_key(&ti->bi, &ti->block, &want_index.u.idx.last_key);
421+
block_iter_init(&ti->bi, &ti->block);
422+
423+
err = block_iter_seek_key(&ti->bi, &want_index.u.idx.last_key);
421424
if (err < 0)
422425
goto done;
423426

t/unit-tests/t-reftable-block.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static void t_ref_block_read_write(void)
6666
block_source_from_buf(&source ,&block_data);
6767
reftable_block_init(&block, &source, 0, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
6868

69-
block_iter_seek_start(&it, &block);
69+
block_iter_init(&it, &block);
7070

7171
for (i = 0; ; i++) {
7272
ret = block_iter_next(&it, &rec);
@@ -79,10 +79,9 @@ static void t_ref_block_read_write(void)
7979
}
8080

8181
for (i = 0; i < N; i++) {
82-
block_iter_reset(&it);
8382
reftable_record_key(&recs[i], &want);
8483

85-
ret = block_iter_seek_key(&it, &block, &want);
84+
ret = block_iter_seek_key(&it, &want);
8685
check_int(ret, ==, 0);
8786

8887
ret = block_iter_next(&it, &rec);
@@ -91,7 +90,7 @@ static void t_ref_block_read_write(void)
9190
check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
9291

9392
want.len--;
94-
ret = block_iter_seek_key(&it, &block, &want);
93+
ret = block_iter_seek_key(&it, &want);
9594
check_int(ret, ==, 0);
9695

9796
ret = block_iter_next(&it, &rec);
@@ -156,7 +155,7 @@ static void t_log_block_read_write(void)
156155
block_source_from_buf(&source, &block_data);
157156
reftable_block_init(&block, &source, 0, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
158157

159-
block_iter_seek_start(&it, &block);
158+
block_iter_init(&it, &block);
160159

161160
for (i = 0; ; i++) {
162161
ret = block_iter_next(&it, &rec);
@@ -169,11 +168,10 @@ static void t_log_block_read_write(void)
169168
}
170169

171170
for (i = 0; i < N; i++) {
172-
block_iter_reset(&it);
173171
reftable_buf_reset(&want);
174172
check(!reftable_buf_addstr(&want, recs[i].u.log.refname));
175173

176-
ret = block_iter_seek_key(&it, &block, &want);
174+
ret = block_iter_seek_key(&it, &want);
177175
check_int(ret, ==, 0);
178176

179177
ret = block_iter_next(&it, &rec);
@@ -182,7 +180,7 @@ static void t_log_block_read_write(void)
182180
check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
183181

184182
want.len--;
185-
ret = block_iter_seek_key(&it, &block, &want);
183+
ret = block_iter_seek_key(&it, &want);
186184
check_int(ret, ==, 0);
187185

188186
ret = block_iter_next(&it, &rec);
@@ -249,7 +247,7 @@ static void t_obj_block_read_write(void)
249247
block_source_from_buf(&source, &block_data);
250248
reftable_block_init(&block, &source, 0, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
251249

252-
block_iter_seek_start(&it, &block);
250+
block_iter_init(&it, &block);
253251

254252
for (i = 0; ; i++) {
255253
ret = block_iter_next(&it, &rec);
@@ -262,10 +260,9 @@ static void t_obj_block_read_write(void)
262260
}
263261

264262
for (i = 0; i < N; i++) {
265-
block_iter_reset(&it);
266263
reftable_record_key(&recs[i], &want);
267264

268-
ret = block_iter_seek_key(&it, &block, &want);
265+
ret = block_iter_seek_key(&it, &want);
269266
check_int(ret, ==, 0);
270267

271268
ret = block_iter_next(&it, &rec);
@@ -334,7 +331,7 @@ static void t_index_block_read_write(void)
334331
block_source_from_buf(&source, &block_data);
335332
reftable_block_init(&block, &source, 0, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
336333

337-
block_iter_seek_start(&it, &block);
334+
block_iter_init(&it, &block);
338335

339336
for (i = 0; ; i++) {
340337
ret = block_iter_next(&it, &rec);
@@ -347,10 +344,9 @@ static void t_index_block_read_write(void)
347344
}
348345

349346
for (i = 0; i < N; i++) {
350-
block_iter_reset(&it);
351347
reftable_record_key(&recs[i], &want);
352348

353-
ret = block_iter_seek_key(&it, &block, &want);
349+
ret = block_iter_seek_key(&it, &want);
354350
check_int(ret, ==, 0);
355351

356352
ret = block_iter_next(&it, &rec);
@@ -359,7 +355,7 @@ static void t_index_block_read_write(void)
359355
check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
360356

361357
want.len--;
362-
ret = block_iter_seek_key(&it, &block, &want);
358+
ret = block_iter_seek_key(&it, &want);
363359
check_int(ret, ==, 0);
364360

365361
ret = block_iter_next(&it, &rec);

0 commit comments

Comments
 (0)