reftable/merged: handle allocation failures in merged_table_init_iter()

Handle allocation failures in `merged_table_init_iter()`. While at it,
merge `merged_iter_init()` into the function. It only has a single
caller and merging them makes it easier to handle allocation failures
consistently.

This change also requires us to adapt `reftable_stack_init_*_iterator()`
to bubble up the new error codes of `merged_table_iter_init()`. Adapt
callsites accordingly.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Patrick Steinhardt
2024-10-02 12:55:54 +02:00
committed by Junio C Hamano
parent 74d1c18757
commit 802c0646ac
9 changed files with 131 additions and 64 deletions

View File

@@ -30,22 +30,6 @@ struct merged_iter {
ssize_t advance_index;
};
static void merged_iter_init(struct merged_iter *mi,
struct reftable_merged_table *mt,
uint8_t typ)
{
memset(mi, 0, sizeof(*mi));
mi->advance_index = -1;
mi->suppress_deletions = mt->suppress_deletions;
REFTABLE_CALLOC_ARRAY(mi->subiters, mt->readers_len);
for (size_t i = 0; i < mt->readers_len; i++) {
reftable_record_init(&mi->subiters[i].rec, typ);
reader_init_iter(mt->readers[i], &mi->subiters[i].iter, typ);
}
mi->subiters_len = mt->readers_len;
}
static void merged_iter_close(void *p)
{
struct merged_iter *mi = p;
@@ -244,25 +228,61 @@ reftable_merged_table_min_update_index(struct reftable_merged_table *mt)
return mt->min;
}
void merged_table_init_iter(struct reftable_merged_table *mt,
struct reftable_iterator *it,
uint8_t typ)
int merged_table_init_iter(struct reftable_merged_table *mt,
struct reftable_iterator *it,
uint8_t typ)
{
struct merged_iter *mi = reftable_malloc(sizeof(*mi));
merged_iter_init(mi, mt, typ);
struct merged_subiter *subiters;
struct merged_iter *mi = NULL;
int ret;
REFTABLE_CALLOC_ARRAY(subiters, mt->readers_len);
if (!subiters) {
ret = REFTABLE_OUT_OF_MEMORY_ERROR;
goto out;
}
for (size_t i = 0; i < mt->readers_len; i++) {
reftable_record_init(&subiters[i].rec, typ);
reader_init_iter(mt->readers[i], &subiters[i].iter, typ);
}
REFTABLE_CALLOC_ARRAY(mi, 1);
if (!mi) {
ret = REFTABLE_OUT_OF_MEMORY_ERROR;
goto out;
}
mi->advance_index = -1;
mi->suppress_deletions = mt->suppress_deletions;
mi->subiters = subiters;
mi->subiters_len = mt->readers_len;
iterator_from_merged_iter(it, mi);
ret = 0;
out:
if (ret < 0) {
for (size_t i = 0; subiters && i < mt->readers_len; i++) {
reftable_iterator_destroy(&subiters[i].iter);
reftable_record_release(&subiters[i].rec);
}
reftable_free(subiters);
reftable_free(mi);
}
return ret;
}
void reftable_merged_table_init_ref_iterator(struct reftable_merged_table *mt,
struct reftable_iterator *it)
int reftable_merged_table_init_ref_iterator(struct reftable_merged_table *mt,
struct reftable_iterator *it)
{
merged_table_init_iter(mt, it, BLOCK_TYPE_REF);
return merged_table_init_iter(mt, it, BLOCK_TYPE_REF);
}
void reftable_merged_table_init_log_iterator(struct reftable_merged_table *mt,
struct reftable_iterator *it)
int reftable_merged_table_init_log_iterator(struct reftable_merged_table *mt,
struct reftable_iterator *it)
{
merged_table_init_iter(mt, it, BLOCK_TYPE_LOG);
return merged_table_init_iter(mt, it, BLOCK_TYPE_LOG);
}
uint32_t reftable_merged_table_hash_id(struct reftable_merged_table *mt)