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):
| trait | arms | what varies |
|---|---|---|
ArchiveWrite | WriterArm::Fast / Safe / Uring | the durability contract, and nothing else |
ObjectIndex | IndexArm::OneTableFourColumns / FourTables / PackedPayload | the payload layout behind the same stree |
Gc | GcArm::NewGeneration / CompactInPlace | whether 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 whatGitStore::openbuilt before this module and is exactly what it builds now.openandopen_withdo 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, throughopen_with_armsoropen_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 thirteen (eight + the five memory/batch knobs of 2026-08-30), 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§
- Store
Config - One implementation of each trait, chosen.
Enums§
- GcArm
- Which
GcGitOps::gcruns as its third step, after reachability and after the dead index rows are dropped. - Index
Arm - Which payload layout sits behind the read stack’s
stree. - Writer
Arm - Which
ArchiveWritethe 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_bytesfor how that number was arrived at. - ENV_
BASE_ BUDGET_ BYTES - Environment variable bounding the held delta-base set of the resolver in
bytes (default 25 % of
MemTotal): over it the base whose next use is farthest is dropped and re-inflated from the mmapped pack when needed. Seecrate::resolve. Read once per process. - 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 bycrate::delta::enabled. - ENV_
EMIT_ WORKERS - Environment variable setting the phase-1 emit workers per request. An
operator knob, not an arm — see
emit_workersingit_ops.rs. Read once per process. - ENV_
EXPLODE - Environment variable naming the explode policy of the
objects.explodedtable (off·graph·full). Read once per store open byExplodePolicy::from_env. - ENV_
EXPLODE_ BUDGET - Environment variable setting the explode cache budget — the byte cap on
the
objects.explodedpools,0/unlimitedfor none. Read once per store open bycrate::exploded_cache::budget_from_env, which supplies the filesystem-derived default when it is unset. The tier it bounds MEASURED 141.7 GiB for an 8.12 GiB pack before the cap existed. - ENV_GC
- Environment variable naming the
Gcarm. - ENV_
GRAPH_ CACHE - Environment variable switching the persisted commit-graph cache
(
objects.graph) off:off/0/falseneither reads nor writes the file, and removes one left by an earlier open;on/1/true, or unset, is the default (read when its token matches, re-persist after a fold). Read once per store open bygraph_cache_from_env. For a store that serves no reads — a replica that only holds packs (gunnar’s twin) — where the file is a derived memo that must not exist on its disk. - ENV_
INDEX - Environment variable naming the
ObjectIndexarm. - ENV_
INDEX_ BATCH_ ROWS - Environment variable setting how many index rows are flushed per batch by the absorber (default 262 144) instead of the whole pack’s rows at once. Read once per process.
- ENV_
MEMINFO - Environment variable naming the file the watchdog reads instead of
/proc/meminfo— a test’s fake. Read once per process. - ENV_
MEM_ BUDGET_ BYTES - Environment variable setting the same floor in absolute bytes, which wins over the percent when both are set. Read once per process.
- ENV_
MEM_ BUDGET_ PCT - Environment variable setting the memory watchdog’s floor as a percent
of
MemTotal(default 20): below it the indexer flushes and waits. Seecrate::memguard. Read once per process. - ENV_
MEM_ PAUSE_ MAX_ MS - Environment variable bounding how long one pause may last, in
milliseconds (default 300 000 = 5 minutes). Past it the worker stops
waiting and the pack is failed BY NAME rather than parked forever. See
crate::memguard::PauseEnd. Read once per process. - ENV_
MEM_ RESUME_ MARGIN_ BYTES - Environment variable setting the absolute resume margin in bytes
(default 64 MiB): a pause ends once
MemAvailableis the floor plus this. It used to bebudget / 8, which on a 16 GB box demanded 410 MB of headroom to leave a pause that a 75 MB shortfall opened — the livelock lane P2 measured. Seecrate::memguard. Read once per process. - ENV_
REACH_ COMMITS - Environment variable capping the live reachability walk in commits. An
operator knob, not an arm — see
live_reach_policyingit_ops.rs. Read once per process. - ENV_
REDB_ CACHE - Environment variable bounding redb’s page cache, in bytes. See
redb_cache_bytes. - ENV_
RESOLVE_ LOOKAHEAD_ BYTES - Environment variable bounding how far the resolver’s workers may run ahead of its ordered output, in bytes (default 128 MiB). Read once per process.
- ENV_
RESOLVE_ WORKERS - Environment variable setting how many subtrees the resolver walks at
once (default: one per core).
1is the serial resolver, and the stream out is the same at every value. Seecrate::resolve::workers_from_env. Read once per process. - ENV_
WRITER - Environment variable naming the
ArchiveWritearm.
Functions§
- env_
reads getenvcalls this module has made since the process started.- env_
reads_ here - The same count, for the calling thread only.
- graph_
cache_ from_ env - Is the
objects.graphmemo on for this store?ENV_GRAPH_CACHE, through the counted door. An unparsable value is an error, never a silent default. - redb_
cache_ bytes - The page-cache ceiling for one repository’s redb database, in bytes.
- set_
graph_ cache_ default - Set the process-wide default of the graph cache for every store opened AFTER this call
(an explicit
ENV_GRAPH_CACHEstill wins). For an embedder that learns its role at runtime and cannot set the environment — edition 2024 makesset_varunsafe, and gunnar forbidsunsafe— such as gunnar’s twin, which holds packs and serves no reads.