module

Noir::ExtractionResultCache

Process-wide memo helpers for pure tree-sitter / lexer extractors.

Large monorepo scans re-enter the same extractors many times on the same source string:

  • one analyzer calls decorations + blueprints (two full parses)
  • concurrent tech analyzers re-parse the same CodeLocator-cached content for sibling frameworks that both survived detection

Trees themselves cannot be cached (lifetime is tied to the parse block), but the derived route/decoration/constant tables can. Keys combine a content fingerprint so GC reuse of object_id cannot return a stale hit.

Constants

DEFAULT_MAX_ENTRIES = 4096

Soft cap per typed store. Beyond this, the oldest half of entries is dropped (FIFO on insertion order). Extraction results are small relative to source text; the cap mainly bounds pathological cases.

Instance methods

clear(store : Hash(UInt64, T), order : Array(UInt64), mutex : Mutex) : Nil forall T
Source
clear_all
Source
fetch(store : Hash(UInt64, T), order : Array(UInt64), key : UInt64, mutex : Mutex, max_entries : Int32, & : -> T) : T forall T
Source
fetch(store : Hash(UInt64, T), order : Array(UInt64), key : UInt64, mutex : Mutex, & : -> T) : T forall T

Insert-or-fetch with a typed Hash store. store and order are owned by the caller so each extractor keeps its own type-safe map.

Source
key(source : String, *options : String) : UInt64

Combine source fingerprint with a cheap options tag (e.g. joined router names). Callers should keep the tag deterministic.

Source
register_clearer
Source
source_fingerprint(source : String) : UInt64

Content fingerprint for a source buffer. Deliberately not keyed on object_id: a short-lived string can be freed and its id recycled by a later buffer, which would serve another file's extraction table. Content-only means two distinct String instances holding identical source correctly share one entry, which is also the common case (the CodeLocator content cache hands the same text to sibling analyzers).

Source
store_capped(store : Hash(UInt64, T), order : Array(UInt64), key : UInt64, value : T, max_entries : Int32 = DEFAULT_MAX_ENTRIES) : T forall T

Capped insert-or-keep. The caller must already hold the store's mutex. Extractors that fill two stores from a single parse cannot go through fetch (that would parse twice), so they call this directly instead of writing to the Hash — writing raw skips eviction and lets the store grow one entry per file for the whole scan.

Source