]> git.ipfire.org Git - thirdparty/git.git/commitdiff
reftable: make the compaction factor configurable
authorPatrick Steinhardt <ps@pks.im>
Mon, 13 May 2024 08:18:38 +0000 (10:18 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 14 May 2024 00:02:39 +0000 (17:02 -0700)
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>
reftable/constants.h
reftable/reftable-writer.h
reftable/stack.c
reftable/stack.h
reftable/stack_test.c

index 5eee72c4c113457334d57019af196f19559435ed..f6beb843ebf2defb320d42a7aae834b423ece008 100644 (file)
@@ -17,5 +17,6 @@ https://developers.google.com/open-source/licenses/bsd
 
 #define MAX_RESTARTS ((1 << 16) - 1)
 #define DEFAULT_BLOCK_SIZE 4096
+#define DEFAULT_GEOMETRIC_FACTOR 2
 
 #endif
index 94804eaa687e983e6d897229bea0bd0676a0c929..189b1f4144f22827e5fa293e02ecc4829ef2e8e4 100644 (file)
@@ -45,6 +45,12 @@ struct reftable_write_options {
 
        /* boolean: Prevent auto-compaction of tables. */
        unsigned disable_auto_compact : 1;
+
+       /*
+        * Geometric sequence factor used by auto-compaction to decide which
+        * tables to compact. Defaults to 2 if unset.
+        */
+       uint8_t auto_compaction_factor;
 };
 
 /* reftable_block_stats holds statistics for a single block type */
index d2e68be7e867cc6b1acad758d45d27861072407a..0ebe69e81dea9dbfdac8890f5222f0df7b129b04 100644 (file)
@@ -10,6 +10,7 @@ https://developers.google.com/open-source/licenses/bsd
 
 #include "../write-or-die.h"
 #include "system.h"
+#include "constants.h"
 #include "merged.h"
 #include "reader.h"
 #include "reftable-error.h"
@@ -1212,12 +1213,16 @@ static int segment_size(struct segment *s)
        return s->end - s->start;
 }
 
-struct segment suggest_compaction_segment(uint64_t *sizes, size_t n)
+struct segment suggest_compaction_segment(uint64_t *sizes, size_t n,
+                                         uint8_t factor)
 {
        struct segment seg = { 0 };
        uint64_t bytes;
        size_t i;
 
+       if (!factor)
+               factor = DEFAULT_GEOMETRIC_FACTOR;
+
        /*
         * If there are no tables or only a single one then we don't have to
         * compact anything. The sequence is geometric by definition already.
@@ -1249,7 +1254,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n)
         *      64, 32, 16, 8, 4, 3, 1
         */
        for (i = n - 1; i > 0; i--) {
-               if (sizes[i - 1] < sizes[i] * 2) {
+               if (sizes[i - 1] < sizes[i] * factor) {
                        seg.end = i + 1;
                        bytes = sizes[i];
                        break;
@@ -1275,7 +1280,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n)
                uint64_t curr = bytes;
                bytes += sizes[i - 1];
 
-               if (sizes[i - 1] < curr * 2) {
+               if (sizes[i - 1] < curr * factor) {
                        seg.start = i - 1;
                        seg.bytes = bytes;
                }
@@ -1301,7 +1306,8 @@ int reftable_stack_auto_compact(struct reftable_stack *st)
 {
        uint64_t *sizes = stack_table_sizes_for_compaction(st);
        struct segment seg =
-               suggest_compaction_segment(sizes, st->merged->stack_len);
+               suggest_compaction_segment(sizes, st->merged->stack_len,
+                                          st->opts.auto_compaction_factor);
        reftable_free(sizes);
        if (segment_size(&seg) > 0)
                return stack_compact_range_stats(st, seg.start, seg.end - 1,
index 97d7ebc0435804a6366418734c76eb758d9c3940..5b45cff4f75b0307f5c9c2735a5110b1e2b13db1 100644 (file)
@@ -35,6 +35,7 @@ struct segment {
        uint64_t bytes;
 };
 
-struct segment suggest_compaction_segment(uint64_t *sizes, size_t n);
+struct segment suggest_compaction_segment(uint64_t *sizes, size_t n,
+                                         uint8_t factor);
 
 #endif
index d15f11d712066fbdc1f675a87269fdb142d11bd2..0f7b1453e6064079af209e3e117babf9401299fa 100644 (file)
@@ -729,7 +729,7 @@ static void test_suggest_compaction_segment(void)
 {
        uint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 };
        struct segment min =
-               suggest_compaction_segment(sizes, ARRAY_SIZE(sizes));
+               suggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);
        EXPECT(min.start == 1);
        EXPECT(min.end == 10);
 }
@@ -738,7 +738,7 @@ static void test_suggest_compaction_segment_nothing(void)
 {
        uint64_t sizes[] = { 64, 32, 16, 8, 4, 2 };
        struct segment result =
-               suggest_compaction_segment(sizes, ARRAY_SIZE(sizes));
+               suggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);
        EXPECT(result.start == result.end);
 }