Class: Mustermann::EqualityMap

Inherits:
Object
  • Object
show all
Defined in:
lib/mustermann/equality_map.rb

Overview

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.

Examples:

class ExpensiveComputation
  @map = Mustermann::EqualityMap.new

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

See Also:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeEqualityMap

Returns a new instance of EqualityMap.



25
26
27
28
# File 'lib/mustermann/equality_map.rb', line 25

def initialize
  @keys = {}
  @map  = ObjectSpace::WeakMap.new
end

Instance Attribute Details

#mapObject (readonly)

Returns the value of attribute map.



19
20
21
# File 'lib/mustermann/equality_map.rb', line 19

def map
  @map
end

Class Method Details

.newObject



21
22
23
# File 'lib/mustermann/equality_map.rb', line 21

def self.new
  defined?(ObjectSpace::WeakMap) ? super : {}
end

Instance Method Details

#fetch(key) { ... } ⇒ Object

Returns value stored in map or result of block.

Parameters:

  • key (#hash)

    for caching

Yields:

  • block that will be called to populate entry if missing (has to be idempotent)

Returns:

  • value stored in map or result of block



33
34
35
36
37
38
39
40
41
42
43
44
# 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