Class: Mustermann::EqualityMap

Inherits:
Object
  • Object
show all
Defined in:
mustermann/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


25
26
27
28
# File 'mustermann/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 'mustermann/lib/mustermann/equality_map.rb', line 19

def map
  @map
end

Class Method Details

.newObject


21
22
23
# File 'mustermann/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

Yields:

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


33
34
35
36
37
38
39
40
# File 'mustermann/lib/mustermann/equality_map.rb', line 33

def fetch(*key)
  identity = @keys[key.hash]
  key      = identity == key ? identity : key

  # 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