reftable: make the compaction factor configurable

When auto-compacting, the reftable library packs references such that the sizes of the tables form a geometric sequence. The factor for this geometric sequence is hardcoded to 2 right now. We're about to expose this as a config option though, so let's expose the factor via write options. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed May 13, 2024 at 10:18 UTC f663d34306d414bca27cf6b5dc7affb00e8603fe
5 files changed +21 -7
reftable/constants.h
+1
@@ -17,5 +17,6 @@ https://developers.google.com/open-source/licenses/bsd
17
18 #define MAX_RESTARTS ((1 << 16) - 1)
19 #define DEFAULT_BLOCK_SIZE 4096
20 +#define DEFAULT_GEOMETRIC_FACTOR 2
21
22 #endif
reftable/reftable-writer.h
+6
@@ -45,6 +45,12 @@ struct reftable_write_options {
45
46 /* boolean: Prevent auto-compaction of tables. */
47 unsigned disable_auto_compact : 1;
48 +
49 + /*
50 + * Geometric sequence factor used by auto-compaction to decide which
51 + * tables to compact. Defaults to 2 if unset.
52 + */
53 + uint8_t auto_compaction_factor;
54 };
55
56 /* reftable_block_stats holds statistics for a single block type */
reftable/stack.c
+10 -4
@@ -10,6 +10,7 @@ https://developers.google.com/open-source/licenses/bsd
10
11 #include "../write-or-die.h"
12 #include "system.h"
13 +#include "constants.h"
14 #include "merged.h"
15 #include "reader.h"
16 #include "reftable-error.h"
@@ -1212,12 +1213,16 @@ static int segment_size(struct segment *s)
1213 return s->end - s->start;
1214 }
1215
1215 -struct segment suggest_compaction_segment(uint64_t *sizes, size_t n)
1216 +struct segment suggest_compaction_segment(uint64_t *sizes, size_t n,
1217 + uint8_t factor)
1218 {
1219 struct segment seg = { 0 };
1220 uint64_t bytes;
1221 size_t i;
1222
1223 + if (!factor)
1224 + factor = DEFAULT_GEOMETRIC_FACTOR;
1225 +
1226 /*
1227 * If there are no tables or only a single one then we don't have to
1228 * compact anything. The sequence is geometric by definition already.
@@ -1249,7 +1254,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n)
1254 * 64, 32, 16, 8, 4, 3, 1
1255 */
1256 for (i = n - 1; i > 0; i--) {
1252 - if (sizes[i - 1] < sizes[i] * 2) {
1257 + if (sizes[i - 1] < sizes[i] * factor) {
1258 seg.end = i + 1;
1259 bytes = sizes[i];
1260 break;
@@ -1275,7 +1280,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n)
1280 uint64_t curr = bytes;
1281 bytes += sizes[i - 1];
1282
1278 - if (sizes[i - 1] < curr * 2) {
1283 + if (sizes[i - 1] < curr * factor) {
1284 seg.start = i - 1;
1285 seg.bytes = bytes;
1286 }
@@ -1301,7 +1306,8 @@ int reftable_stack_auto_compact(struct reftable_stack *st)
1306 {
1307 uint64_t *sizes = stack_table_sizes_for_compaction(st);
1308 struct segment seg =
1304 - suggest_compaction_segment(sizes, st->merged->stack_len);
1309 + suggest_compaction_segment(sizes, st->merged->stack_len,
1310 + st->opts.auto_compaction_factor);
1311 reftable_free(sizes);
1312 if (segment_size(&seg) > 0)
1313 return stack_compact_range_stats(st, seg.start, seg.end - 1,
reftable/stack.h
+2 -1
@@ -35,6 +35,7 @@ struct segment {
35 uint64_t bytes;
36 };
37
38 -struct segment suggest_compaction_segment(uint64_t *sizes, size_t n);
38 +struct segment suggest_compaction_segment(uint64_t *sizes, size_t n,
39 + uint8_t factor);
40
41 #endif
reftable/stack_test.c
+2 -2
@@ -729,7 +729,7 @@ static void test_suggest_compaction_segment(void)
729 {
730 uint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 };
731 struct segment min =
732 - suggest_compaction_segment(sizes, ARRAY_SIZE(sizes));
732 + suggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);
733 EXPECT(min.start == 1);
734 EXPECT(min.end == 10);
735 }
@@ -738,7 +738,7 @@ static void test_suggest_compaction_segment_nothing(void)
738 {
739 uint64_t sizes[] = { 64, 32, 16, 8, 4, 2 };
740 struct segment result =
741 - suggest_compaction_segment(sizes, ARRAY_SIZE(sizes));
741 + suggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);
742 EXPECT(result.start == result.end);
743 }
744