Module: Plumb::TypeCache

Defined in:
lib/plumb/type_cache.rb

Overview

Process-level memoization for computed type graphs (resolved input/output and accepted types — see Plumb::Subtyping). Keyed by type identity in WeakKeyMaps, so entries are pruned by GC together with their types. Only frozen types are cached: a mutable type (an unfrozen Pipeline, a Deferred) may change its answer over time, so it always recomputes.

Constant Summary collapse

MAPS =
{
  resolved_input: ObjectSpace::WeakKeyMap.new,
  resolved_output: ObjectSpace::WeakKeyMap.new,
  accepted_type: ObjectSpace::WeakKeyMap.new,
  value_preserving: ObjectSpace::WeakKeyMap.new
}.freeze
LOCK =
Mutex.new

Class Method Summary collapse

Class Method Details

.fetch(slot, key) ⇒ Object

Presence-based so cached false/nil are returned as hits, not recomputed.

NOTE: compute OUTSIDE the lock — computations recurse back into #fetch (And/Or children, resolved_* chains) and a non-reentrant Mutex would deadlock. A race may compute the same pure value twice; the first write wins.



30
31
32
33
34
35
36
37
38
39
# File 'lib/plumb/type_cache.rb', line 30

def self.fetch(slot, key)
  return yield unless key.frozen?

  map = MAPS.fetch(slot)
  cached = LOCK.synchronize { map.key?(key) ? map[key] : ABSENT }
  return cached unless cached.equal?(ABSENT)

  value = yield
  LOCK.synchronize { map.key?(key) ? map[key] : (map[key] = value) }
end