return reftable_get_be24(b->block_data.data + b->restart_off + 3 * idx);
}
-void block_iter_seek_start(struct block_iter *it, const struct reftable_block *block)
+void block_iter_init(struct block_iter *it, const struct reftable_block *block)
{
it->block = block;
+ block_iter_seek_start(it);
+}
+
+void block_iter_seek_start(struct block_iter *it)
+{
reftable_buf_reset(&it->last_key);
- it->next_off = block->header_off + 4;
+ it->next_off = it->block->header_off + 4;
}
struct restart_needle_less_args {
reftable_buf_release(&it->scratch);
}
-int block_iter_seek_key(struct block_iter *it, const struct reftable_block *block,
- struct reftable_buf *want)
+int block_iter_seek_key(struct block_iter *it, struct reftable_buf *want)
{
struct restart_needle_less_args args = {
.needle = *want,
- .block = block,
+ .block = it->block,
};
struct reftable_record rec;
int err = 0;
* restart point. While that works alright, we would end up scanning
* too many record.
*/
- i = binsearch(block->restart_count, &restart_needle_less, &args);
+ i = binsearch(it->block->restart_count, &restart_needle_less, &args);
if (args.error) {
err = REFTABLE_FORMAT_ERROR;
goto done;
* starting from the preceding restart point.
*/
if (i > 0)
- it->next_off = block_restart_offset(block, i - 1);
+ it->next_off = block_restart_offset(it->block, i - 1);
else
- it->next_off = block->header_off + 4;
- it->block = block;
+ it->next_off = it->block->header_off + 4;
- err = reftable_record_init(&rec, reftable_block_type(block));
+ err = reftable_record_init(&rec, reftable_block_type(it->block));
if (err < 0)
goto done;
.scratch = REFTABLE_BUF_INIT, \
}
-/* Position `it` at start of the block */
-void block_iter_seek_start(struct block_iter *it, const struct reftable_block *block);
+/*
+ * Initialize the block iterator with the given block. The iterator will be
+ * positioned at the first record contained in the block. The block must remain
+ * valid until the end of the iterator's lifetime. It is valid to re-initialize
+ * iterators multiple times.
+ */
+void block_iter_init(struct block_iter *it, const struct reftable_block *block);
+
+/* Position the initialized iterator at the first record of its block. */
+void block_iter_seek_start(struct block_iter *it);
-/* Position `it` to the `want` key in the block */
-int block_iter_seek_key(struct block_iter *it, const struct reftable_block *block,
- struct reftable_buf *want);
+/*
+ * Position the initialized iterator at the desired record key. It is not an
+ * error in case the record cannot be found. If so, a subsequent call to
+ * `block_iter_next()` will indicate that the iterator is exhausted.
+ */
+int block_iter_seek_key(struct block_iter *it, struct reftable_buf *want);
/* return < 0 for error, 0 for OK, > 0 for EOF. */
int block_iter_next(struct block_iter *it, struct reftable_record *rec);
ti->block_off = next_block_off;
ti->is_finished = 0;
- block_iter_seek_start(&ti->bi, &ti->block);
+ block_iter_init(&ti->bi, &ti->block);
return 0;
}
ti->typ = reftable_block_type(&ti->block);
ti->block_off = off;
- block_iter_seek_start(&ti->bi, &ti->block);
+ block_iter_init(&ti->bi, &ti->block);
ti->is_finished = 0;
return 0;
}
* the wanted key inside of it. If the block does not contain our key
* we know that the corresponding record does not exist.
*/
- err = block_iter_seek_key(&ti->bi, &ti->block, &want_key);
+ block_iter_init(&ti->bi, &ti->block);
+ err = block_iter_seek_key(&ti->bi, &want_key);
if (err < 0)
goto done;
err = 0;
if (err != 0)
goto done;
- err = block_iter_seek_key(&ti->bi, &ti->block, &want_index.u.idx.last_key);
+ block_iter_init(&ti->bi, &ti->block);
+
+ err = block_iter_seek_key(&ti->bi, &want_index.u.idx.last_key);
if (err < 0)
goto done;
block_source_from_buf(&source ,&block_data);
reftable_block_init(&block, &source, 0, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
- block_iter_seek_start(&it, &block);
+ block_iter_init(&it, &block);
for (i = 0; ; i++) {
ret = block_iter_next(&it, &rec);
}
for (i = 0; i < N; i++) {
- block_iter_reset(&it);
reftable_record_key(&recs[i], &want);
- ret = block_iter_seek_key(&it, &block, &want);
+ ret = block_iter_seek_key(&it, &want);
check_int(ret, ==, 0);
ret = block_iter_next(&it, &rec);
check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
want.len--;
- ret = block_iter_seek_key(&it, &block, &want);
+ ret = block_iter_seek_key(&it, &want);
check_int(ret, ==, 0);
ret = block_iter_next(&it, &rec);
block_source_from_buf(&source, &block_data);
reftable_block_init(&block, &source, 0, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
- block_iter_seek_start(&it, &block);
+ block_iter_init(&it, &block);
for (i = 0; ; i++) {
ret = block_iter_next(&it, &rec);
}
for (i = 0; i < N; i++) {
- block_iter_reset(&it);
reftable_buf_reset(&want);
check(!reftable_buf_addstr(&want, recs[i].u.log.refname));
- ret = block_iter_seek_key(&it, &block, &want);
+ ret = block_iter_seek_key(&it, &want);
check_int(ret, ==, 0);
ret = block_iter_next(&it, &rec);
check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
want.len--;
- ret = block_iter_seek_key(&it, &block, &want);
+ ret = block_iter_seek_key(&it, &want);
check_int(ret, ==, 0);
ret = block_iter_next(&it, &rec);
block_source_from_buf(&source, &block_data);
reftable_block_init(&block, &source, 0, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
- block_iter_seek_start(&it, &block);
+ block_iter_init(&it, &block);
for (i = 0; ; i++) {
ret = block_iter_next(&it, &rec);
}
for (i = 0; i < N; i++) {
- block_iter_reset(&it);
reftable_record_key(&recs[i], &want);
- ret = block_iter_seek_key(&it, &block, &want);
+ ret = block_iter_seek_key(&it, &want);
check_int(ret, ==, 0);
ret = block_iter_next(&it, &rec);
block_source_from_buf(&source, &block_data);
reftable_block_init(&block, &source, 0, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
- block_iter_seek_start(&it, &block);
+ block_iter_init(&it, &block);
for (i = 0; ; i++) {
ret = block_iter_next(&it, &rec);
}
for (i = 0; i < N; i++) {
- block_iter_reset(&it);
reftable_record_key(&recs[i], &want);
- ret = block_iter_seek_key(&it, &block, &want);
+ ret = block_iter_seek_key(&it, &want);
check_int(ret, ==, 0);
ret = block_iter_next(&it, &rec);
check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
want.len--;
- ret = block_iter_seek_key(&it, &block, &want);
+ ret = block_iter_seek_key(&it, &want);
check_int(ret, ==, 0);
ret = block_iter_next(&it, &rec);