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