reftable/reader: avoid copying index iterator
When doing an indexed seek we need to walk down the multi-level index until we finally hit a record of the desired indexed type. This loop performs a copy of the index iterator on every iteration, which is both hard to understand and completely unnecessary. Refactor the code so that we use a single iterator to walk down the indices, only. Note that while this should improve performance, the improvement is negligible in all but the most unreasonable repositories. This is because the effect is only really noticeable when we have to walk down many levels of indices, which is not something that a repository would typically have. So the motivation for this change is really only about readability. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
d537ce6b9e
commit
9a59b65dba
@ -510,13 +510,11 @@ static int reader_seek_indexed(struct reftable_reader *r,
|
|||||||
.type = BLOCK_TYPE_INDEX,
|
.type = BLOCK_TYPE_INDEX,
|
||||||
.u.idx = { .last_key = STRBUF_INIT },
|
.u.idx = { .last_key = STRBUF_INIT },
|
||||||
};
|
};
|
||||||
struct table_iter index_iter = TABLE_ITER_INIT;
|
struct table_iter ti = TABLE_ITER_INIT, *malloced;
|
||||||
struct table_iter empty = TABLE_ITER_INIT;
|
|
||||||
struct table_iter next = TABLE_ITER_INIT;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
reftable_record_key(rec, &want_index.u.idx.last_key);
|
reftable_record_key(rec, &want_index.u.idx.last_key);
|
||||||
err = reader_start(r, &index_iter, reftable_record_type(rec), 1);
|
err = reader_start(r, &ti, reftable_record_type(rec), 1);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@ -526,7 +524,7 @@ static int reader_seek_indexed(struct reftable_reader *r,
|
|||||||
* highest layer that identifies the relevant index block as well as
|
* highest layer that identifies the relevant index block as well as
|
||||||
* the record inside that block that corresponds to our wanted key.
|
* the record inside that block that corresponds to our wanted key.
|
||||||
*/
|
*/
|
||||||
err = reader_seek_linear(&index_iter, &want_index);
|
err = reader_seek_linear(&ti, &want_index);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@ -552,44 +550,36 @@ static int reader_seek_indexed(struct reftable_reader *r,
|
|||||||
* all levels of the index only to find out that the key does
|
* all levels of the index only to find out that the key does
|
||||||
* not exist.
|
* not exist.
|
||||||
*/
|
*/
|
||||||
err = table_iter_next(&index_iter, &index_result);
|
err = table_iter_next(&ti, &index_result);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
err = reader_table_iter_at(r, &next, index_result.u.idx.offset,
|
err = reader_table_iter_at(r, &ti, index_result.u.idx.offset, 0);
|
||||||
0);
|
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
err = block_iter_seek_key(&next.bi, &next.br, &want_index.u.idx.last_key);
|
err = block_iter_seek_key(&ti.bi, &ti.br, &want_index.u.idx.last_key);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (next.typ == reftable_record_type(rec)) {
|
if (ti.typ == reftable_record_type(rec)) {
|
||||||
err = 0;
|
err = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next.typ != BLOCK_TYPE_INDEX) {
|
if (ti.typ != BLOCK_TYPE_INDEX) {
|
||||||
err = REFTABLE_FORMAT_ERROR;
|
err = REFTABLE_FORMAT_ERROR;
|
||||||
break;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
table_iter_close(&index_iter);
|
|
||||||
index_iter = next;
|
|
||||||
next = empty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == 0) {
|
REFTABLE_ALLOC_ARRAY(malloced, 1);
|
||||||
struct table_iter *malloced = reftable_calloc(1, sizeof(*malloced));
|
*malloced = ti;
|
||||||
*malloced = next;
|
iterator_from_table_iter(it, malloced);
|
||||||
next = empty;
|
|
||||||
iterator_from_table_iter(it, malloced);
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
table_iter_close(&next);
|
if (err)
|
||||||
table_iter_close(&index_iter);
|
table_iter_close(&ti);
|
||||||
reftable_record_release(&want_index);
|
reftable_record_release(&want_index);
|
||||||
reftable_record_release(&index_result);
|
reftable_record_release(&index_result);
|
||||||
return err;
|
return err;
|
||||||
|
Reference in New Issue
Block a user