Skip to main content

Module cache

Module cache 

Source
Expand description

Content-addressed memoization of crate::featurize (design L0).

φ is a pure function of (term, spec) — that is the determinism contract crate::render states — so any featurization the engine has already performed can be replayed instead of re-rendered. That matters because the engine performs the same featurization repeatedly and unavoidably:

  • fugue-ppl’s adaptive single-site MH executes the model twice per step, once to re-score the current trace — which is bit-identically the tree the previous step accepted. Every refinement step therefore renders one tree it has already rendered.
  • Engine::insert_candidate re-featurizes the tree the refinement walk (or the edit bench) just featurized, to obtain the φ it admits it with.

Neither is a bug to be deleted — the first is inside a dependency’s kernel, the second is the honest way to admit a candidate. A memo removes the cost without touching either. It is exactly lossless: a hit returns the same Features object the miss produced, so nothing downstream — least of all the raw φ that enters the observation log — can tell the two apart.

§Keys

render_key is fnv1a128 over serde_json of the term and of the phrase spec. FNV rather than DefaultHasher because DefaultHasher’s output is explicitly not guaranteed stable across Rust releases, and this key is meant to be persistable (design L2) — a toolchain bump must not silently invalidate every stored row. serde_json is deterministic across runs and platforms for these types: field order is the struct’s, and floats round-trip exactly under the float_roundtrip feature the workspace pins.

§Persisting a row: the key is not enough

render_key addresses (term, spec), which is everything φ depends on given a fixed featurizer. A stored row survives a reload only if the code that would recompute it agrees, and the key cannot see that code: change the normalizer, a descriptor’s formula, or the vet gate, and the same key now names a different measurement.

RENDER_EPOCH is that missing coordinate, and cache_namespace combines the two. Bumping the epoch orphans every stored row at once, which is the intended and only correct response to φ moving — a persistent cache whose invalidation is anything less than total is a cache that will one day serve a number from a featurizer that no longer exists.

Structs§

CachedFeatures
Everything featurize produces except the samples — the persistable unit, and what a memo hit returns.
MemoStats
Memo occupancy and hit accounting.
RenderMemo
A bounded, content-addressed featurization memo.

Constants§

DEFAULT_AUDIO_CAP
Audition buffers retained (~565 KB each at the default phrase) — enough for the current duel pair, the bench, and recent history, at ~7 MB.
DEFAULT_FEATURE_CAP
Feature entries retained. A refinement generation is a few hundred featurizations; 2048 keeps a whole session’s worth of walks resident at ~2 MB.
RENDER_EPOCH
Generation of the featurizer itself.

Functions§

cache_namespace
The persistent cache’s namespace for one stimulus: "e<epoch>:<spec hash>".
canonical_tree_json
The exact bytes a key is computed over for a term.
featurize_memo
featurize, consulting memo first and populating it on a miss.
render_key
Content address of one (term, spec) featurization, 32 lowercase hex chars.