class Ref::AbstractReferenceValueMap

Abstract base class for WeakValueMap and SoftValueMap.

The classes behave similar to Hashes, but the values in the map are not strong references and can be reclaimed by the garbage collector at any time. When a value is reclaimed, the map entry will be removed.

Public Class Methods

new() click to toggle source

Create a new map. Values added to the map will be cleaned up by the garbage collector if there are no other reference except in the map.

# File lib/ref/abstract_reference_value_map.rb, line 21
def initialize
  @references = {}
  @references_to_keys_map = {}
  @lock = Monitor.new
  @reference_cleanup = lambda{|object_id| remove_reference_to(object_id)}
end

Public Instance Methods

[](key) click to toggle source

Get a value from the map by key. If the value has been reclaimed by the garbage collector, this will return nil.

# File lib/ref/abstract_reference_value_map.rb, line 30
def [](key)
  @lock.synchronize do
    ref = @references[key]
    value = ref.object if ref
    value
  end
end
Also aliased as: get
[]=(key, value) click to toggle source

Add a key/value to the map.

# File lib/ref/abstract_reference_value_map.rb, line 41
def []=(key, value)
  ObjectSpace.define_finalizer(value, @reference_cleanup)
  key = key.dup if key.is_a?(String)
  @lock.synchronize do
    @references[key] = self.class.reference_class.new(value)
    keys_for_id = @references_to_keys_map[value.__id__]
    unless keys_for_id
      keys_for_id = []
      @references_to_keys_map[value.__id__] = keys_for_id
    end
    keys_for_id << key
  end
  value
end
Also aliased as: put
clear() click to toggle source

Clear the map of all key/value pairs.

# File lib/ref/abstract_reference_value_map.rb, line 104
def clear
  @lock.synchronize do
    @references.clear
    @references_to_keys_map.clear
  end
end
delete(key) click to toggle source

Remove the entry associated with the key from the map.

# File lib/ref/abstract_reference_value_map.rb, line 59
def delete(key)
  ref = @references.delete(key)
  if ref
    keys_to_id = @references_to_keys_map[ref.referenced_object_id]
    if keys_to_id
      keys_to_id.delete(key)
      @references_to_keys_map.delete(ref.referenced_object_id) if keys_to_id.empty?
    end
    ref.object
  else
    nil
  end
end
each() { |key, value| ... } click to toggle source

Iterate through all the key/value pairs in the map that have not been reclaimed by the garbage collector.

# File lib/ref/abstract_reference_value_map.rb, line 96
def each
  @references.each do |key, ref|
    value = ref.object
    yield(key, value) if value
  end
end
empty?() click to toggle source

True if there are entries that exist in the map

# File lib/ref/abstract_reference_value_map.rb, line 140
def empty?
  @references.each do |_, ref|
    return false if ref.object
  end

  true
end
get(key)
Alias for: []
inspect() click to toggle source
# File lib/ref/abstract_reference_value_map.rb, line 148
def inspect
  live_entries = {}
  each do |key, value|
    live_entries[key] = value
  end
  live_entries.inspect
end
length()
Alias for: size
merge(other_hash, &block) click to toggle source

Returns a new struct containing the contents of ‘other` and the contents of `self`. If no block is specified, the value for entries with duplicate keys will be that of `other`. Otherwise the value for each duplicate key is determined by calling the block with the key, its value in `self` and its value in `other`.

# File lib/ref/abstract_reference_value_map.rb, line 116
def merge(other_hash, &block)
  to_h.merge(other_hash, &block).reduce(self.class.new) do |map, pair|
    map[pair.first] = pair.last
    map
  end
end
merge!(other_hash) click to toggle source

Merge the values from another hash into this map.

# File lib/ref/abstract_reference_value_map.rb, line 124
def merge!(other_hash)
  @lock.synchronize do
    other_hash.each { |key, value| self[key] = value }
  end
end
put(key, value)
Alias for: []=
size() click to toggle source

The number of entries in the map

# File lib/ref/abstract_reference_value_map.rb, line 131
def size
  @references.count do |_, ref|
    ref.object
  end
end
Also aliased as: length
to_a() click to toggle source

Turn the map into an arry of [key, value] entries

# File lib/ref/abstract_reference_value_map.rb, line 81
def to_a
  array = []
  each{|k,v| array << [k, v]}
  array
end
to_h() click to toggle source

Returns a hash containing the names and values for the struct’s members.

# File lib/ref/abstract_reference_value_map.rb, line 88
def to_h
  hash = {}
  each{|k,v| hash[k] = v}
  hash
end
values() click to toggle source

Get the list of all values that have not yet been garbage collected.

# File lib/ref/abstract_reference_value_map.rb, line 74
def values
  vals = []
  each{|k,v| vals << v}
  vals
end

Private Instance Methods

remove_reference_to(object_id) click to toggle source
# File lib/ref/abstract_reference_value_map.rb, line 158
def remove_reference_to(object_id)
  @lock.synchronize do
    keys = @references_to_keys_map[object_id]
    if keys
      keys.each do |key|
        @references.delete(key)
      end
      @references_to_keys_map.delete(object_id)
    end
  end
end