module Noir::ExtractionResultCache

Overview

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:

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.

Extended Modules

Defined in:

miniparsers/extraction_result_cache.cr

Constant Summary

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 Method Summary

Instance Method Detail

def clear(store : Hash(UInt64, T), order : Array(UInt64), mutex : Mutex) : Nil forall T #

[View source]
def clear_all : Nil #

[View source]
def fetch(store : Hash(UInt64, T), order : Array(UInt64), key : UInt64, mutex : Mutex, max_entries : Int32, & : -> T) : T forall T #

[View source]
def 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.


[View source]
def 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.


[View source]
def register_clearer(&block : -> Nil) : Nil #

[View source]
def 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).


[View source]
def 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.


[View source]