reftable/block: reuse zstream when writing log blocks
commita155ab2bf4e16b8fe1e0644d9d57d2c62eecd452
authorPatrick Steinhardt <ps@pks.im>
Mon, 8 Apr 2024 12:24:35 +0000 (8 14:24 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 9 Apr 2024 00:01:42 +0000 (8 17:01 -0700)
tree92df875b5d1038d64f149f70d12259ac459eeb72
parent8aaeffe3b5b85f996ac82ec4b0b0e538f4b5a0ac
reftable/block: reuse zstream when writing log blocks

While most reftable blocks are written to disk as-is, blocks for log
records are compressed with zlib. To compress them we use `compress2()`,
which is a simple wrapper around the more complex `zstream` interface
that would require multiple function invocations.

One downside of this interface is that `compress2()` will reallocate
internal state of the `zstream` interface on every single invocation.
Consequently, as we call `compress2()` for every single log block which
we are about to write, this can lead to quite some memory allocation
churn.

Refactor the code so that the block writer reuses a `zstream`. This
significantly reduces the number of bytes allocated when writing many
refs in a single transaction, as demonstrated by the following benchmark
that writes 100k refs in a single transaction.

Before:

  HEAP SUMMARY:
      in use at exit: 671,931 bytes in 151 blocks
    total heap usage: 22,631,887 allocs, 22,631,736 frees, 1,854,670,793 bytes allocated

After:

  HEAP SUMMARY:
      in use at exit: 671,931 bytes in 151 blocks
    total heap usage: 22,620,528 allocs, 22,620,377 frees, 1,245,549,984 bytes allocated

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
reftable/block.c
reftable/block.h