class Guacamole::IdentityMap

This class implements the ‘Identity Map’ pattern ({www.martinfowler.com/eaaCatalog/identityMap.html Fowler, EAA, 195}) to ensure only one copy of the same database document is present in memory within the same session. Internally a ‘Hamster::Hash` is used. This hash implementation is immutable and thus it is safe to use the current `IdentityMap` implementation in concurrent situations.

The ‘IdentityMap` should be purged after any unit of work (i.e. a request). If used in Rails the {IdentityMap::Session} middleware will automatically be registered. For other Rack-based use cases you must register it yourself. For all other use cases you need to take when to call {Guacamole::IdentityMap.reset} all by yourself.

Public Class Methods

identity_map_instance() click to toggle source

The internally used map

@api private @return [Hamster::Hash] an instance of an immutable hash

# File lib/guacamole/identity_map.rb, line 118
def identity_map_instance
  @identity_map_instance ||= Hamster.hash
end
include?(object_or_class, key = nil) click to toggle source

Tests if the map contains some object

The method accepts either a ‘class` and `key` or just any `Object` that responds to `key`. Supporting both is made for your convenience.

@param [Object#read, Class] object_or_class Either the object to check or the ‘class`

of the object you're looking for

@param [Object, nil] key In case you provided a ‘Class` as first parameter you must

provide the key for the object here

@return [true, false] does the map contain the object or not

# File lib/guacamole/identity_map.rb, line 100
def include?(object_or_class, key = nil)
  identity_map_instance.key? key_for(object_or_class, key)
end
key_for(object_or_class, key = nil) click to toggle source

Constructs the key used internally by the map

@param [Object#read, Class] object_or_class Either an object or a ‘Class` @param [Object, nil] key In case you provided a `Class` as first parameter you must

provide the key for the object here

@return [Array(Class, Object)] the created key

# File lib/guacamole/identity_map.rb, line 110
def key_for(object_or_class, key = nil)
  key ? [object_or_class, key] : [object_or_class.class, object_or_class.key]
end
reset() click to toggle source

Purges all stored object from the map by setting the internal structure to ‘nil`

@return [nil]

# File lib/guacamole/identity_map.rb, line 50
def reset
  @identity_map_instance = nil
end
retrieve(klass, key) click to toggle source

Retrieves a stored object from the map

@param [Class] klass The class of the object you want to get @param [Object] key Whatever is the key of that object @return [Object] the stored object

# File lib/guacamole/identity_map.rb, line 70
def retrieve(klass, key)
  identity_map_instance.get key_for(klass, key)
end
retrieve_or_store(klass, key, &block) click to toggle source

Retrieves a stored object or adds it based on the block if it is not already present

This can be used to retrieve and store in one step. See {Guacamole::DocumentModelMapper#document_to_model} for an example.

@param [Class] klass The class of the object you want to get @param [Object] key Whatever is the key of that object @yield A block if the object is not already present @yieldreturn [Object#read] the object to store. The ‘key` and `class` should match with input params @return [Object] the stored object

# File lib/guacamole/identity_map.rb, line 84
def retrieve_or_store(klass, key, &block)
  return retrieve(klass, key) if include?(klass, key)

  store block.call
end
store(object) click to toggle source

Add an object to the map

The object must implement a ‘key` method. There is no check if that method is present.

@param [Object#key] object Any object that implements the ‘key` method (and has a `class`) @return [Object#key] the object which just has been stored

# File lib/guacamole/identity_map.rb, line 60
def store(object)
  @identity_map_instance = identity_map_instance.put(key_for(object), object)
  object
end