Class: Ref::AbstractReferenceValueMap
- Inherits:
-
Object
- Object
- Ref::AbstractReferenceValueMap
- Defined in:
- lib/ref/abstract_reference_value_map.rb
Overview
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.
Direct Known Subclasses
Class Method Summary collapse
-
.reference_class ⇒ Object
:nodoc:.
-
.reference_class=(klass) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Get a value from the map by key.
-
#[]=(key, value) ⇒ Object
Add a key/value to the map.
-
#clear ⇒ Object
Clear the map of all key/value pairs.
-
#delete(key) ⇒ Object
Remove the entry associated with the key from the map.
-
#each ⇒ Object
Iterate through all the key/value pairs in the map that have not been reclaimed by the garbage collector.
-
#initialize ⇒ AbstractReferenceValueMap
constructor
Create a new map.
- #inspect ⇒ Object
-
#merge!(other_hash) ⇒ Object
Merge the values from another hash into this map.
-
#to_a ⇒ Object
Turn the map into an arry of [key, value] entries.
-
#values ⇒ Object
Get the list of all values that have not yet been garbage collected.
Constructor Details
#initialize ⇒ AbstractReferenceValueMap
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.
21 22 23 24 25 26 |
# File 'lib/ref/abstract_reference_value_map.rb', line 21 def initialize @references = {} @references_to_keys_map = {} @lock = SafeMonitor.new @reference_cleanup = lambda{|object_id| remove_reference_to(object_id)} end |
Class Method Details
.reference_class ⇒ Object
:nodoc:
13 14 15 16 |
# File 'lib/ref/abstract_reference_value_map.rb', line 13 def reference_class #:nodoc: raise NotImplementedError.new("#{name} is an abstract class and cannot be instantiated") unless @reference_class @reference_class end |
.reference_class=(klass) ⇒ Object
:nodoc:
9 10 11 |
# File 'lib/ref/abstract_reference_value_map.rb', line 9 def reference_class=(klass) #:nodoc: @reference_class = klass end |
Instance Method Details
#[](key) ⇒ Object
Get a value from the map by key. If the value has been reclaimed by the garbage collector, this will return nil.
30 31 32 33 34 |
# File 'lib/ref/abstract_reference_value_map.rb', line 30 def [](key) ref = @references[key] value = ref.object if ref value end |
#[]=(key, value) ⇒ Object
Add a key/value to the map.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/ref/abstract_reference_value_map.rb', line 37 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 |
#clear ⇒ Object
Clear the map of all key/value pairs.
91 92 93 94 95 96 |
# File 'lib/ref/abstract_reference_value_map.rb', line 91 def clear @lock.synchronize do @references.clear @references_to_keys_map.clear end end |
#delete(key) ⇒ Object
Remove the entry associated with the key from the map.
53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/ref/abstract_reference_value_map.rb', line 53 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 ⇒ Object
Iterate through all the key/value pairs in the map that have not been reclaimed by the garbage collector.
83 84 85 86 87 88 |
# File 'lib/ref/abstract_reference_value_map.rb', line 83 def each @references.each do |key, ref| value = ref.object yield(key, value) if value end end |
#inspect ⇒ Object
105 106 107 108 109 110 111 |
# File 'lib/ref/abstract_reference_value_map.rb', line 105 def inspect live_entries = {} each do |key, value| live_entries[key] = value end live_entries.inspect end |
#merge!(other_hash) ⇒ Object
Merge the values from another hash into this map.
99 100 101 102 103 |
# File 'lib/ref/abstract_reference_value_map.rb', line 99 def merge!(other_hash) other_hash.each do |key, value| self[key] = value end end |
#to_a ⇒ Object
Turn the map into an arry of [key, value] entries
75 76 77 78 79 |
# File 'lib/ref/abstract_reference_value_map.rb', line 75 def to_a array = [] each{|k,v| array << [k, v]} array end |
#values ⇒ Object
Get the list of all values that have not yet been garbage collected.
68 69 70 71 72 |
# File 'lib/ref/abstract_reference_value_map.rb', line 68 def values vals = [] each{|k,v| vals << v} vals end |