]> git.ipfire.org Git - thirdparty/git.git/commitdiff
refs/reftable: allow configuring restart interval
authorPatrick Steinhardt <ps@pks.im>
Mon, 13 May 2024 08:18:28 +0000 (10:18 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 14 May 2024 00:02:38 +0000 (17:02 -0700)
Add a new option `reftable.restartInterval` that allows the user to
control the restart interval when writing reftable records used by the
reftable library.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config/reftable.txt
refs/reftable-backend.c
t/t0613-reftable-write-options.sh

index fa7c4be014a3e98d4e900f81d46ce77176225a3f..2374be71d7df850829cb310ec3aa722c573de1fa 100644 (file)
@@ -12,3 +12,21 @@ readers during access.
 +
 The largest block size is `16777215` bytes (15.99 MiB). The default value is
 `4096` bytes (4kB). A value of `0` will use the default value.
+
+reftable.restartInterval::
+       The interval at which to create restart points. The reftable backend
+       determines the restart points at file creation. Every 16 may be
+       more suitable for smaller block sizes (4k or 8k), every 64 for larger
+       block sizes (64k).
++
+More frequent restart points reduces prefix compression and increases
+space consumed by the restart table, both of which increase file size.
++
+Less frequent restart points makes prefix compression more effective,
+decreasing overall file size, with increased penalties for readers
+walking through more records after the binary search step.
++
+A maximum of `65535` restart points per block is supported.
++
+The default value is to create restart points every 16 records. A value of `0`
+will use the default value.
index 8d0ae9e2854ba3db74910ec509f8870c314e3837..a2880aabce3900ec2bd476765cddf65d2abae3e8 100644 (file)
@@ -240,6 +240,11 @@ static int reftable_be_config(const char *var, const char *value,
                if (block_size > 16777215)
                        die("reftable block size cannot exceed 16MB");
                opts->block_size = block_size;
+       } else if (!strcmp(var, "reftable.restartinterval")) {
+               unsigned long restart_interval = git_config_ulong(var, value, ctx->kvi);
+               if (restart_interval > UINT16_MAX)
+                       die("reftable block size cannot exceed %u", (unsigned)UINT16_MAX);
+               opts->restart_interval = restart_interval;
        }
 
        return 0;
index 8bdbc6ec703d601d7862fcc2fdf074fcabb99ac8..e0a5b26f58fc0a995253268b13c1611497beb01c 100755 (executable)
@@ -171,4 +171,47 @@ test_expect_success 'block size exceeding maximum supported size' '
        )
 '
 
+test_expect_success 'restart interval at every single record' '
+       test_when_finished "rm -rf repo" &&
+       git init repo &&
+       (
+               cd repo &&
+               test_commit initial &&
+               for i in $(test_seq 10)
+               do
+                       printf "update refs/heads/branch-%d HEAD\n" "$i" ||
+                       return 1
+               done >input &&
+               git update-ref --stdin <input &&
+               git -c reftable.restartInterval=1 pack-refs &&
+
+               cat >expect <<-EOF &&
+               header:
+                 block_size: 4096
+               ref:
+                 - length: 566
+                   restarts: 13
+               log:
+                 - length: 1393
+                   restarts: 12
+               EOF
+               test-tool dump-reftable -b .git/reftable/*.ref >actual &&
+               test_cmp expect actual
+       )
+'
+
+test_expect_success 'restart interval exceeding maximum supported interval' '
+       test_when_finished "rm -rf repo" &&
+       git init repo &&
+       (
+               cd repo &&
+               test_commit initial &&
+               cat >expect <<-EOF &&
+               fatal: reftable block size cannot exceed 65535
+               EOF
+               test_must_fail git -c reftable.restartInterval=65536 pack-refs 2>err &&
+               test_cmp expect err
+       )
+'
+
 test_done