Skip to main content

Module arms

Module arms 

Source
Expand description

Which implementation of each trait a store is built on. One selector, read once at construction, never per operation — arms::StoreConfig. Which implementation of each trait a store is built on — one selector, read once, never per operation.

Three traits in this crate have more than one implementation, every one of them written and benchmarked (PLAN §7, §8):

traitarmswhat varies
ArchiveWriteWriterArm::Fast / Safe / Uringthe durability contract, and nothing else
ObjectIndexIndexArm::OneTableFourColumns / FourTables / PackedPayloadthe payload layout behind the same stree
[Gc]GcArm::NewGeneration / CompactInPlacewhether the old generation survives until the new one is proven

Until this module existed, GitStore named one of each by hand, so none of them could be A/B’d through a server or a bench without editing the source. StoreConfig is that choice made data.

§The default is the shipping combination and it did not move

StoreConfig::DEFAULT is SafeWriter + ObjectReadStack<OneTableFourColumns>

  • NewGeneration, which is exactly what GitStore::open built before this module and is exactly what it builds now. open and open_with do not read the environment at all — an operator who exports a variable cannot silently change the durability contract under a caller that never asked for a selector. Choosing an arm is something a caller does on purpose, through open_with_arms or open_from_env.

§Read once, at construction. Never per operation.

Every getenv this crate performs goes through [read_env] and happens either inside StoreConfig::from_env (which a store calls once, while it is being opened — the three arms and, since 2026-08-21, the cache ceiling with them) or behind a process-wide OnceLock for the knobs that never vary between two stores in one process. A std::env::var in a copy loop would be one syscall per object served, and that exact defect was found and fixed in gunnar the day before this was written. It is not a style rule here, it is asserted: env_reads_here counts every read this module makes on the calling thread, and the_selector_is_read_once_at_construction_and_never_per_operation pushes and serves a whole pack across an unchanged counter.

Five reads at construction — three arms, the cache ceiling and the explode policy — and zero per operation. env_reads is the same count process-wide; see env_reads_here for why the guard asserts on the thread-local one. The complete roster of keys is ALL_ENV.

§The names, so an operator can type them

  ZNIPPY_GIT_WRITER = fast | safe | uring     (default: safe)
  ZNIPPY_GIT_INDEX  = one-table | four-tables | packed   (default: one-table)
  ZNIPPY_GIT_GC     = new-generation | in-place          (default: new-generation)

  ZNIPPY_GIT_REDB_CACHE_BYTES = <bytes>                  (default: 67108864)

  ZNIPPY_GIT_EXPLODE        = off | graph | full          (default: see exploded_arrow.rs)
  ZNIPPY_GIT_BOUNDARY_DELTA = 0 | off | false to disable  (default: on)
  ZNIPPY_GIT_REACH_COMMITS  = <commits>                   (default: 512)
  ZNIPPY_GIT_EMIT_WORKERS   = <workers>, 0 = all cores    (default: 4)

The first four are per store and are what StoreConfig holds and prints; the last four are per process. ALL_ENV is all eight, and a consumer that has to carry any of them across a boundary asserts its list against it.

An unset variable takes the default. A variable set to something else is an error, named and listing what is accepted — a typo that silently fell back to the default would make an operator believe a measurement came from an arm that never ran, which is worse than a failed open.

⚠ The fourth one is not an arm, and it is the only variable here that GitStore::open reads. It selects no implementation and changes no contract — it is a memory ceiling, and redb’s own default for it is 1 GiB per database. See redb_cache_bytes.

Structs§

StoreConfig
One implementation of each trait, chosen.

Enums§

GcArm
Which Gc GitOps::gc runs as its third step, after reachability and after the dead index rows are dropped.
IndexArm
Which payload layout sits behind the read stack’s stree.
WriterArm
Which ArchiveWrite the push path appends through.

Constants§

ALL_ENV
Every environment variable this crate reads outside its tests, in one place, so a consumer that carries them across a process or container boundary can assert its list against this one instead of against a count it remembers.
DEFAULT_REDB_CACHE_BYTES
64 MiB. See redb_cache_bytes for how that number was arrived at.
ENV_BOUNDARY_DELTA
Environment variable switching the boundary re-delta off for an A/B (0 / off / false; anything else, or unset, is on). Read once per process by crate::delta::enabled.
ENV_EMIT_WORKERS
Environment variable setting the phase-1 emit workers per request. An operator knob, not an arm — see emit_workers in git_ops.rs. Read once per process.
ENV_EXPLODE
Environment variable naming the explode policy of the objects.exploded table (off · graph · full). Read once per store open by ExplodePolicy::from_env.
ENV_GC
Environment variable naming the Gc arm.
ENV_INDEX
Environment variable naming the ObjectIndex arm.
ENV_REACH_COMMITS
Environment variable capping the live reachability walk in commits. An operator knob, not an arm — see live_reach_policy in git_ops.rs. Read once per process.
ENV_REDB_CACHE
Environment variable bounding redb’s page cache, in bytes. See redb_cache_bytes.
ENV_WRITER
Environment variable naming the ArchiveWrite arm.

Functions§

env_reads
getenv calls this module has made since the process started.
env_reads_here
The same count, for the calling thread only.
redb_cache_bytes
The page-cache ceiling for one repository’s two redb databases, in bytes.