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