class Ref::AbstractReferenceKeyMap

Abstract base class for WeakKeyMap and SoftKeyMap.

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

Public Class Methods

new() click to toggle source

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

# File lib/ref/abstract_reference_key_map.rb, line 21
def initialize
  @values = {}
  @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_key_map.rb, line 30
def [](key)
  @lock.synchronize do
    rkey = ref_key(key)
    @values[rkey] if rkey
  end
end
Also aliased as: get
[]=(key, value) click to toggle source

Add a key/value to the map.

# File lib/ref/abstract_reference_key_map.rb, line 40
def []=(key, value)
  ObjectSpace.define_finalizer(key, @reference_cleanup)
  @lock.synchronize do
    @references_to_keys_map[key.__id__] = self.class.reference_class.new(key)
    @values[key.__id__] = value
  end
end
Also aliased as: put
clear() click to toggle source

Clear the map of all key/value pairs.

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

Remove the value associated with the key from the map.

# File lib/ref/abstract_reference_key_map.rb, line 51
def delete(key)
  @lock.synchronize do
    rkey = ref_key(key)
    if rkey
      @references_to_keys_map.delete(rkey)
      @values.delete(rkey)
    else
      nil
    end
  end
end
each() { |key, values| ... } 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_key_map.rb, line 84
def each
  @references_to_keys_map.each do |rkey, ref|
    key = ref.object
    yield(key, @values[rkey]) if key
  end
end
empty?() click to toggle source

True if there are entries that exist in the map

# File lib/ref/abstract_reference_key_map.rb, line 128
def empty?
  @references_to_keys_map.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_key_map.rb, line 135
def inspect
  live_entries = {}
  each do |key, value|
    live_entries[key] = value
  end
  live_entries.inspect
end
keys() click to toggle source

Get an array of keys that have not yet been garbage collected.

# File lib/ref/abstract_reference_key_map.rb, line 64
def keys
  @values.keys.collect{|rkey| @references_to_keys_map[rkey].object}.compact
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_key_map.rb, line 104
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_key_map.rb, line 112
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_key_map.rb, line 119
def size
  @references_to_keys_map.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_key_map.rb, line 69
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_key_map.rb, line 76
def to_h
  hash = {}
  each{|k,v| hash[k] = v}
  hash
end

Private Instance Methods

ref_key(key) click to toggle source
# File lib/ref/abstract_reference_key_map.rb, line 145
def ref_key (key)
  ref = @references_to_keys_map[key.__id__]
  if ref && ref.object
    ref.referenced_object_id
  else
    nil
  end
end
remove_reference_to(object_id) click to toggle source
# File lib/ref/abstract_reference_key_map.rb, line 154
def remove_reference_to(object_id)
  @lock.synchronize do
    @references_to_keys_map.delete(object_id)
    @values.delete(object_id)
  end
end