class Mustermann::EqualityMap

A simple wrapper around ObjectSpace::WeakMap that allows matching keys by equality rather than identity. Used for caching. Note that `fetch` is not guaranteed to return the object, even if it has not been garbage collected yet, especially when used concurrently. Therefore, the block passed to `fetch` has to be idempotent.

@example

class ExpensiveComputation
  @map = Mustermann::EqualityMap.new

  def self.new(*args)
    @map.fetch(args) { super }
  end
end

@see fetch

Attributes

map[R]

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/mustermann/equality_map.rb, line 21
def self.new
  defined?(ObjectSpace::WeakMap) ? super : {}
end
new() click to toggle source
# File lib/mustermann/equality_map.rb, line 25
def initialize
  @keys = {}
  @map  = ObjectSpace::WeakMap.new
end

Public Instance Methods

fetch(key) { || ... } click to toggle source

@param [#hash] key for caching @yield block that will be called to populate entry if missing (has to be idempotent) @return value stored in map or result of block

# File lib/mustermann/equality_map.rb, line 33
def fetch(key)
  identity = @keys[key.hash]
  if identity == key
    key = identity
  elsif key.frozen?
    key = key.dup
  end

  # it is ok that this is not thread-safe, worst case it has double cost in
  # generating, object equality is not guaranteed anyways
  @map[key] ||= track(key, yield)
end