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