summaryrefslogtreecommitdiff
path: root/reftable/stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'reftable/stack.c')
-rw-r--r--reftable/stack.c61
1 files changed, 47 insertions, 14 deletions
diff --git a/reftable/stack.c b/reftable/stack.c
index 65d89820bd..1c9f21dfe1 100644
--- a/reftable/stack.c
+++ b/reftable/stack.c
@@ -1626,7 +1626,8 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n,
return seg;
}
-static uint64_t *stack_table_sizes_for_compaction(struct reftable_stack *st)
+static int stack_segments_for_compaction(struct reftable_stack *st,
+ struct segment *seg)
{
int version = (st->opts.hash_id == REFTABLE_HASH_SHA1) ? 1 : 2;
int overhead = header_size(version) - 1;
@@ -1634,31 +1635,63 @@ static uint64_t *stack_table_sizes_for_compaction(struct reftable_stack *st)
REFTABLE_CALLOC_ARRAY(sizes, st->merged->tables_len);
if (!sizes)
- return NULL;
+ return REFTABLE_OUT_OF_MEMORY_ERROR;
for (size_t i = 0; i < st->merged->tables_len; i++)
sizes[i] = st->tables[i]->size - overhead;
- return sizes;
+ *seg = suggest_compaction_segment(sizes, st->merged->tables_len,
+ st->opts.auto_compaction_factor);
+ reftable_free(sizes);
+
+ return 0;
}
-int reftable_stack_auto_compact(struct reftable_stack *st)
+static int update_segment_if_compaction_required(struct reftable_stack *st,
+ struct segment *seg,
+ bool use_geometric,
+ bool *required)
{
- struct segment seg;
- uint64_t *sizes;
+ int err;
- if (st->merged->tables_len < 2)
+ if (st->merged->tables_len < 2) {
+ *required = false;
return 0;
+ }
- sizes = stack_table_sizes_for_compaction(st);
- if (!sizes)
- return REFTABLE_OUT_OF_MEMORY_ERROR;
+ if (!use_geometric) {
+ *required = true;
+ return 0;
+ }
- seg = suggest_compaction_segment(sizes, st->merged->tables_len,
- st->opts.auto_compaction_factor);
- reftable_free(sizes);
+ err = stack_segments_for_compaction(st, seg);
+ if (err)
+ return err;
+
+ *required = segment_size(seg) > 0;
+ return 0;
+}
+
+int reftable_stack_compaction_required(struct reftable_stack *st,
+ bool use_heuristics,
+ bool *required)
+{
+ struct segment seg;
+ return update_segment_if_compaction_required(st, &seg, use_heuristics,
+ required);
+}
+
+int reftable_stack_auto_compact(struct reftable_stack *st)
+{
+ struct segment seg;
+ bool required;
+ int err;
+
+ err = update_segment_if_compaction_required(st, &seg, true, &required);
+ if (err)
+ return err;
- if (segment_size(&seg) > 0)
+ if (required)
return stack_compact_range(st, seg.start, seg.end - 1,
NULL, STACK_COMPACT_RANGE_BEST_EFFORT);