<feed xmlns='http://www.w3.org/2005/Atom'>
<title>git/reftable/stack_test.c, branch v2.45.2</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/git/git.git/
</subtitle>
<id>https://git.shady.money/git/atom?h=v2.45.2</id>
<link rel='self' href='https://git.shady.money/git/atom?h=v2.45.2'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/'/>
<updated>2024-04-16T21:50:30Z</updated>
<entry>
<title>Merge branch 'jt/reftable-geometric-compaction'</title>
<updated>2024-04-16T21:50:30Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2024-04-16T21:50:30Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=82a31ec32441cd06daa5e0397a73f4159cdaad4b'/>
<id>urn:sha1:82a31ec32441cd06daa5e0397a73f4159cdaad4b</id>
<content type='text'>
The strategy to compact multiple tables of reftables after many
operations accumulate many entries has been improved to avoid
accumulating too many tables uncollected.

* jt/reftable-geometric-compaction:
  reftable/stack: use geometric table compaction
  reftable/stack: add env to disable autocompaction
  reftable/stack: expose option to disable auto-compaction
</content>
</entry>
<entry>
<title>Merge branch 'ps/pack-refs-auto'</title>
<updated>2024-04-09T21:31:45Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2024-04-09T21:31:45Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=eacfd581d2b805b95b4c12beb1a63ceb2fd4ca69'/>
<id>urn:sha1:eacfd581d2b805b95b4c12beb1a63ceb2fd4ca69</id>
<content type='text'>
"git pack-refs" learned the "--auto" option, which is a useful
addition to be triggered from "git gc --auto".

Acked-by: Karthik Nayak &lt;karthik.188@gmail.com&gt;
cf. &lt;CAOLa=ZRAEA7rSUoYL0h-2qfEELdbPHbeGpgBJRqesyhHi9Q6WQ@mail.gmail.com&gt;

* ps/pack-refs-auto:
  builtin/gc: pack refs when using `git maintenance run --auto`
  builtin/gc: forward git-gc(1)'s `--auto` flag when packing refs
  t6500: extract objects with "17" prefix
  builtin/gc: move `struct maintenance_run_opts`
  builtin/pack-refs: introduce new "--auto" flag
  builtin/pack-refs: release allocated memory
  refs/reftable: expose auto compaction via new flag
  refs: remove `PACK_REFS_ALL` flag
  refs: move `struct pack_refs_opts` to where it's used
  t/helper: drop pack-refs wrapper
  refs/reftable: print errors on compaction failure
  reftable/stack: gracefully handle failed auto-compaction due to locks
  reftable/stack: use error codes when locking fails during compaction
  reftable/error: discern locked/outdated errors
  reftable/stack: fix error handling in `reftable_stack_init_addition()`
</content>
</entry>
<entry>
<title>reftable/stack: use geometric table compaction</title>
<updated>2024-04-08T19:11:10Z</updated>
<author>
<name>Justin Tobler</name>
<email>jltobler@gmail.com</email>
</author>
<published>2024-04-08T16:16:55Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=a949ebd342440049a1ac77ca675f66884eae4187'/>
<id>urn:sha1:a949ebd342440049a1ac77ca675f66884eae4187</id>
<content type='text'>
To reduce the number of on-disk reftables, compaction is performed.
Contiguous tables with the same binary log value of size are grouped
into segments. The segment that has both the lowest binary log value and
contains more than one table is set as the starting point when
identifying the compaction segment.

Since segments containing a single table are not initially considered
for compaction, if the table appended to the list does not match the
previous table log value, no compaction occurs for the new table. It is
therefore possible for unbounded growth of the table list. This can be
demonstrated by repeating the following sequence:

git branch -f foo
git branch -d foo

Each operation results in a new table being written with no compaction
occurring until a separate operation produces a table matching the
previous table log value.

Instead, to avoid unbounded growth of the table list, the compaction
strategy is updated to ensure tables follow a geometric sequence after
each operation by individually evaluating each table in reverse index
order. This strategy results in a much simpler and more robust algorithm
compared to the previous one while also maintaining a minimal ordered
set of tables on-disk.

When creating 10 thousand references, the new strategy has no
performance impact:

Benchmark 1: update-ref: create refs sequentially (revision = HEAD~)
  Time (mean ± σ):     26.516 s ±  0.047 s    [User: 17.864 s, System: 8.491 s]
  Range (min … max):   26.447 s … 26.569 s    10 runs

Benchmark 2: update-ref: create refs sequentially (revision = HEAD)
  Time (mean ± σ):     26.417 s ±  0.028 s    [User: 17.738 s, System: 8.500 s]
  Range (min … max):   26.366 s … 26.444 s    10 runs

Summary
  update-ref: create refs sequentially (revision = HEAD) ran
    1.00 ± 0.00 times faster than update-ref: create refs sequentially (revision = HEAD~)

Some tests in `t0610-reftable-basics.sh` assert the on-disk state of
tables and are therefore updated to specify the correct new table count.
Since compaction is more aggressive in ensuring tables maintain a
geometric sequence, the expected table count is reduced in these tests.
In `reftable/stack_test.c` tests related to `sizes_to_segments()` are
removed because the function is no longer needed. Also, the
`test_suggest_compaction_segment()` test is updated to better showcase
and reflect the new geometric compaction behavior.

Signed-off-by: Justin Tobler &lt;jltobler@gmail.com&gt;
Acked-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>reftable/stack: expose option to disable auto-compaction</title>
<updated>2024-04-08T19:11:10Z</updated>
<author>
<name>Justin Tobler</name>
<email>jltobler@gmail.com</email>
</author>
<published>2024-04-08T16:16:53Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=bc91330cecfdc9a00a486923126a969fee6ace36'/>
<id>urn:sha1:bc91330cecfdc9a00a486923126a969fee6ace36</id>
<content type='text'>
The reftable stack already has a variable to configure whether or not to
run auto-compaction, but it is inaccessible to users of the library.
There exist use cases where a caller may want to have more control over
auto-compaction.

Move the `disable_auto_compact` option into `reftable_write_options` to
allow external callers to disable auto-compaction. This will be used in
a subsequent commit.

Signed-off-by: Justin Tobler &lt;jltobler@gmail.com&gt;
Acked-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'ps/pack-refs-auto' into jt/reftable-geometric-compaction</title>
<updated>2024-04-05T17:34:23Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2024-04-05T17:34:23Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=7424fb779752c77f68d1cc793cd5c6cc3cc60971'/>
<id>urn:sha1:7424fb779752c77f68d1cc793cd5c6cc3cc60971</id>
<content type='text'>
* ps/pack-refs-auto:
  builtin/gc: pack refs when using `git maintenance run --auto`
  builtin/gc: forward git-gc(1)'s `--auto` flag when packing refs
  t6500: extract objects with "17" prefix
  builtin/gc: move `struct maintenance_run_opts`
  builtin/pack-refs: introduce new "--auto" flag
  builtin/pack-refs: release allocated memory
  refs/reftable: expose auto compaction via new flag
  refs: remove `PACK_REFS_ALL` flag
  refs: move `struct pack_refs_opts` to where it's used
  t/helper: drop pack-refs wrapper
  refs/reftable: print errors on compaction failure
  reftable/stack: gracefully handle failed auto-compaction due to locks
  reftable/stack: use error codes when locking fails during compaction
  reftable/error: discern locked/outdated errors
  reftable/stack: fix error handling in `reftable_stack_init_addition()`
</content>
</entry>
<entry>
<title>Merge branch 'ps/reftable-unit-test-nfs-workaround'</title>
<updated>2024-04-01T20:21:35Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2024-04-01T20:21:35Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=6938b355c01ae2479b07b2f3c067ea1863f0b2bb'/>
<id>urn:sha1:6938b355c01ae2479b07b2f3c067ea1863f0b2bb</id>
<content type='text'>
A unit test for reftable code tried to enumerate all files in a
directory after reftable operations and expected to see nothing but
the files it wanted to leave there, but was fooled by .nfs* cruft
files left, which has been corrected.

* ps/reftable-unit-test-nfs-workaround:
  reftable: fix tests being broken by NFS' delete-after-close semantics
</content>
</entry>
<entry>
<title>reftable/stack: gracefully handle failed auto-compaction due to locks</title>
<updated>2024-03-25T16:54:07Z</updated>
<author>
<name>Patrick Steinhardt</name>
<email>ps@pks.im</email>
</author>
<published>2024-03-25T10:02:50Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=a2f711ade0c4816a59155d72559cbc4759cd4699'/>
<id>urn:sha1:a2f711ade0c4816a59155d72559cbc4759cd4699</id>
<content type='text'>
Whenever we commit a new table to the reftable stack we will end up
invoking auto-compaction of the stack to keep the total number of tables
at bay. This auto-compaction may fail though in case at least one of the
tables which we are about to compact is locked. This is indicated by the
compaction function returning `REFTABLE_LOCK_ERROR`. We do not handle
this case though, and thus bubble that return value up the calling
chain, which will ultimately cause a failure.

Fix this bug by ignoring `REFTABLE_LOCK_ERROR`.

Signed-off-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>reftable/error: discern locked/outdated errors</title>
<updated>2024-03-25T16:51:11Z</updated>
<author>
<name>Patrick Steinhardt</name>
<email>ps@pks.im</email>
</author>
<published>2024-03-25T10:02:42Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=af18098c9d2b2e165aca127c35eeb98d157bd542'/>
<id>urn:sha1:af18098c9d2b2e165aca127c35eeb98d157bd542</id>
<content type='text'>
We currently throw two different errors into a similar-but-different
error code:

  - Errors when trying to lock the reftable stack.

  - Errors when trying to write to the reftable stack which has been
    modified concurrently.

This results in unclear error handling and user-visible error messages.

Create a new `REFTABLE_OUTDATED_ERROR` so that those error conditions
can be clearly told apart from each other. Adjust users of the old
`REFTABLE_LOCK_ERROR` to use the new error code as required.

Signed-off-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>reftable: fix tests being broken by NFS' delete-after-close semantics</title>
<updated>2024-03-21T17:32:21Z</updated>
<author>
<name>Patrick Steinhardt</name>
<email>ps@pks.im</email>
</author>
<published>2024-03-21T15:39:52Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=0068aa794696188d3c9bea62804780d44bee824f'/>
<id>urn:sha1:0068aa794696188d3c9bea62804780d44bee824f</id>
<content type='text'>
It was reported that the reftable unit tests in t0032 fail with the
following assertion when running on top of NFS:

    running test_reftable_stack_compaction_concurrent_clean
    reftable/stack_test.c: 1063: failed assertion count_dir_entries(dir) == 2
    Aborted

Setting a breakpoint immediately before the assertion in fact shows the
following list of files:

    ./stack_test-1027.QJBpnd
    ./stack_test-1027.QJBpnd/0x000000000001-0x000000000003-dad7ac80.ref
    ./stack_test-1027.QJBpnd/.nfs000000000001729f00001e11
    ./stack_test-1027.QJBpnd/tables.list

Note the weird ".nfs*" file? This file is maintained by NFS clients in
order to emulate delete-after-last-close semantics that we rely on in
the reftable code [1]. Instead of unlinking the file right away and
keeping it open in the client, the NFS client will rename it to ".nfs*"
and then delete that temporary file when the last reference to it gets
dropped. Quoting the NFS FAQ:

    &gt; D2. What is a "silly rename"? Why do these .nfsXXXXX files keep
    &gt; showing up?
    &gt;
    &gt; A. Unix applications often open a scratch file and then unlink it.
    &gt; They do this so that the file is not visible in the file system name
    &gt; space to any other applications, and so that the system will
    &gt; automatically clean up (delete) the file when the application exits.
    &gt; This is known as "delete on last close", and is a tradition among
    &gt; Unix applications.
    &gt;
    &gt; Because of the design of the NFS protocol, there is no way for a
    &gt; file to be deleted from the name space but still remain in use by an
    &gt; application. Thus NFS clients have to emulate this using what
    &gt; already exists in the protocol. If an open file is unlinked, an NFS
    &gt; client renames it to a special name that looks like ".nfsXXXXX".
    &gt; This "hides" the file while it remains in use. This is known as a
    &gt; "silly rename." Note that NFS servers have nothing to do with this
    &gt; behavior.

This of course throws off the assertion that we got exactly two files in
that directory.

The test in question triggers this behaviour by holding two open file
descriptors to the "tables.list" file. One of the references is because
we are about to append to the stack, whereas the other reference is
because we want to compact it. As the compaction has just finished we
already rewrote "tables.list" to point to the new contents, but the
other file descriptor pointing to the old version is still open. Thus we
trigger the delete-after-last-close emulation.

Furthermore, it was reported that this behaviour only triggers with
4f36b8597c (reftable/stack: fix race in up-to-date check, 2024-01-18).
This is expected as well because it is the first point in time where we
actually keep the "tables.list" file descriptor open for the stat cache.

Fix this bug by skipping over any files that start with a leading dot
when counting files. While we could explicitly check for a prefix of
".nfs", other network file systems like SMB for example do the same
trickery but with a ".smb" prefix. In any case though, this loosening of
the assertion should be fine given that the reftable library would never
write files with leading dots by itself.

[1]: https://nfs.sourceforge.net/#faq_d2

Reported-by: Chuck Lever &lt;chuck.lever@oracle.com&gt;
Signed-off-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>reftable/record: convert old and new object IDs to arrays</title>
<updated>2024-03-05T17:10:06Z</updated>
<author>
<name>Patrick Steinhardt</name>
<email>ps@pks.im</email>
</author>
<published>2024-03-05T12:10:59Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=87ff723018bfca588b5d68e110ab04494c451ebd'/>
<id>urn:sha1:87ff723018bfca588b5d68e110ab04494c451ebd</id>
<content type='text'>
In 7af607c58d (reftable/record: store "val1" hashes as static arrays,
2024-01-03) and b31e3cc620 (reftable/record: store "val2" hashes as
static arrays, 2024-01-03) we have converted ref records to store their
object IDs in a static array. Convert log records to do the same so that
their old and new object IDs are arrays, too.

This change results in two allocations less per log record that we're
iterating over. Before:

    HEAP SUMMARY:
        in use at exit: 13,473 bytes in 122 blocks
      total heap usage: 8,068,495 allocs, 8,068,373 frees, 401,011,862 bytes allocated

After:

    HEAP SUMMARY:
        in use at exit: 13,473 bytes in 122 blocks
      total heap usage: 6,068,489 allocs, 6,068,367 frees, 361,011,822 bytes allocated

Signed-off-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
</feed>
