Luxar Viewer API Documentation - v2026.10.19
    Preparing search index...

    Class SliceCache

    SliceCache — byte-budget LRU of decoded per-slice geometry.

    Key format: ${nodePath}\u0000${viewSig} (see SliceCache.makeKey), where viewSig is a stable serialization of the query's displayDims / slicePosition / tolerance / dimensions — the loader's viewStatesEqual fields, ALL of them (a key narrower than that equality can restore a snapshot the loader itself would have reloaded; see data/loaders/progressive/slice-cache-helper.ts::buildSliceViewSig).

    Index
    MAX_TOMBSTONES: 4096

    Tombstone cap — bounded so long sessions can't grow it unboundedly.

    debug: boolean
    maxSize: number
    tombstones: Set<string> = ...
    thrashMisses: number = 0
    oversizedWarned: Set<string> = ...
    ladderDepths: Map<string, { depth: number; totalDepth: number }> = ...
    pinnedBytes: Map<string, number> = ...
    pinnedBytesTotal: number = 0
    pendingStores: Map<string, Promise<void>> = ...
    stageBytesTotal: number = 0
    stageHits: number = 0
    stageMisses: number = 0
    stageRejected: number = 0
    stageShed: number = 0
    • Default cache size derived from config.cache.sliceCacheMaxSizeMB. A method, not a static initializer: reading config at module-load time couples every transitive importer (e.g. the shared facade helpers) to a fully-populated config mock in tests.

      Returns number

    • Cache a per-slice entry (may evict entries to stay within budget).

      Parameters

      • key: string

        Cache key (use SliceCache.makeKey).

      • entry: SliceCacheEntry

        Cloned payload + its retained byte size.

      • Optionalopts: { scan?: boolean; pin?: boolean }
        • Optionalscan?: boolean

          The caller KNOWS it is storing inside a sequential scan (dimension playback: the loaders pass frameBudgetMs !== null). Evicts from the MRU end instead of LRU — scan-resistant eviction that keeps the loop-head prefix resident across cyclic loops (see LRUCache.set). Known trade-off: under bounce loop mode near a turnaround this is locally worse than LRU (the loaders only see the budget directive, not the loop mode) — accepted; a loop-mode-aware per-pass hint is a possible follow-up.

        • Optionalpin?: boolean

          Protect this entry from eviction until it is next read (unpinned on the first get hit). The SlicePrefetcher sets it so a projected next-frame slice — which lands as the MRU entry and would be the FIRST victim of a subsequent scan store under budget pressure — survives until the foreground tick restores it. Best-effort: if the whole working set is pinned and over budget, pinned entries are still evicted.

      Returns void

    • The stage output attached to the entry under key, provided that entry still holds exactly payload (reference identity — the caller's proof that the stage input is this entry's slice data) and the output was produced under sig. A bookkeeping read: no LRU promotion, no S-cache hit/miss count (the slice lookup that produced payload already counted). Returns undefined when the entry is gone or was replaced, or when the attached output is missing or was produced under other parameters.

      Parameters

      • key: string
      • payload: unknown
      • sig: string

      Returns unknown

    • Attach (or replace) the stage output of the entry under key, provided it still holds exactly payload. The entry keeps its recency position and pin; its byte count grows by bytes (minus any output it replaces).

      Admission never evicts a slice. Outside a scan, room is found by shedding OTHER entries' stage outputs, least recently used first. Inside a scan (opts.scan, dimension playback) an output is admitted only into FREE budget: under a cyclic scan every other resident output is needed sooner than the one being stored, so displacing any of them to admit it would only churn — a stable resident subset is what yields hits every loop (the same reasoning as the slices' own MRU scan eviction). A refused output returns false and leaves the entry exactly as it was, so a saturated cache keeps every decoded slice it would have kept without B2.

      Parameters

      • key: string
      • payload: unknown
      • stage: SliceStageOutput
      • Optionalopts: { scan?: boolean }

      Returns boolean

    • Whether setStage (with the same opts) could admit a bytes-sized output on key's entry holding payload. Lets a caller skip preparing an output that would be refused; a budget refusal is counted in stageRejected exactly as setStage's is.

      Parameters

      • key: string
      • payload: unknown
      • bytes: number
      • Optionalopts: { scan?: boolean }

      Returns boolean

    • Drop stage outputs from entries other than keepKey until growth more bytes fit under the budget (or none are left): least recently used first, or — inside a scan (mostRecentFirst) — most recently used first, for the same reason the slices themselves use MRU eviction during playback (the oldest outputs are the ones the loop reaches next). O(entries) only when the cache is actually over budget AND holds stage outputs; free otherwise.

      Parameters

      • growth: number
      • keepKey: string
      • mostRecentFirst: boolean

      Returns void

    • Entries (other than keepKey) whose stage outputs free excess bytes, in shed order.

      Parameters

      • excess: number
      • keepKey: string
      • mostRecentFirst: boolean

      Returns [string, SliceCacheEntry][]

    • Refresh a pinned entry's byte tally after an in-place size change.

      Parameters

      • key: string

      Returns void

    • Release a prefetch pin without reading the entry (no LRU promotion, no hit/miss count). The SlicePrefetcher calls it on playback stop for every key its shadow passes may have pinned, since a pin is otherwise released only by a consuming get. Harmless when key is absent or unpinned.

      Parameters

      • key: string

      Returns void

    • Announce that a background (shadow) pass is about to store key. Until the returned release function is called, pendingStore hands out a promise that settles on release, so a foreground pass for the same key can wait for the shadow's result instead of re-assembling the same slice. The release is idempotent and only clears its OWN registration.

      Parameters

      • key: string

      Returns () => void

    • The in-flight shadow store for key, if one is running (see beginPendingStore).

      Parameters

      • key: string

      Returns Promise<void> | undefined

    • Check whether a slice is cached (without LRU promotion).

      Parameters

      • key: string

      Returns boolean

    • Read an entry WITHOUT LRU promotion and WITHOUT counting a hit/miss. Used by storeLadder's upgrade-if-longer check so bookkeeping reads don't perturb the hit-rate statistic the monitor reports.

      Parameters

      • key: string

      Returns SliceCacheEntry | undefined

    • Remove one cached slice without leaving an eviction tombstone.

      Parameters

      • key: string

        Cache key to invalidate.

      Returns boolean

      Whether an entry was removed.

    • Whether an entry of bytes could ever be stored (i.e. it does not exceed the whole budget). The LRU silently rejects oversized entries, so callers check this BEFORE doing the (potentially large) clone to avoid a wasted copy that would just be dropped — see storeLadder.

      Parameters

      • bytes: number

      Returns boolean

    • Warn-once gate for oversized ladders: returns true the FIRST time key is reported oversized (a full ladder exceeding the whole budget, so only a coarse prefix is cached — see storeLadder), false thereafter. Bounded FIFO + cleared on clear, so warnings can't leak across a long session or a dataset switch (mirrors the tombstone discipline).

      Parameters

      • key: string

      Returns boolean

    • Clear all cached slices (invoked on content-hash / dataset invalidation).

      Returns void

    • Update the pin tally after a set. The LRU pins only a key it holds, and a re-set of an already-pinned key keeps that pin, so the stored entry is pinned iff it exists and was either just pinned or already pinned.

      Parameters

      • key: string
      • requested: boolean

      Returns void

    • Drop key from the pin tally (no-op when it was not pinned).

      Parameters

      • key: string

      Returns void

    • Record an evicted key as a tombstone (bounded FIFO).

      Parameters

      • key: string

      Returns void

    • Build a cache key from a node path and a view signature.

      The NUL separator can't appear in a node path or the JSON-ish view signature, so the two are always unambiguously recoverable.

      Parameters

      • nodePath: string

        Scene-graph path of the geometry node (per-node namespace).

      • viewSig: string

        Stable serialization of the query view (slice/tolerance/displayDims).

      Returns string