Class: Tool::EqualityMap

Inherits:
Object
  • Object
show all
Defined in:
lib/tool/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 = Tool::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.



24
25
26
27
# File 'lib/tool/equality_map.rb', line 24

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

Instance Attribute Details

#mapObject (readonly)

Returns the value of attribute map.



18
19
20
# File 'lib/tool/equality_map.rb', line 18

def map
  @map
end

Class Method Details

.newObject



20
21
22
# File 'lib/tool/equality_map.rb', line 20

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 (Array<#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



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

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