class Wref::Map
A weak hash-map.
Examples¶ ↑
map = Wref::Map.new map[1] = obj obj = nil sleep 0.5 begin obj = map[1] print "Object still exists in memory." rescue Wref::Recycled print "Object has been garbage-collected." end obj = map.get(1) print "Object still exists in memory." if obj
Public Class Methods
# File lib/wref/map.rb, line 19 def initialize(args = {}) require "monitor" @map = {} @mutex = Monitor.new @impl = args[:impl] end
Public Instance Methods
Scans the whole map and removes dead references. After the implementation of automatic clean-up by using ObjectSpace.define_finalizer, there should be no reason to call this method.
# File lib/wref/map.rb, line 74 def clean keys = nil @mutex.synchronize do keys = @map.keys end keys.each do |key| begin get(key) #this will remove the key if the object no longer exists. rescue Wref::Recycled #ignore. end end return nil end
Deletes a key in the hash.
# File lib/wref/map.rb, line 132 def delete(key) @mutex.synchronize do wref = @map[key] object = @map.delete(key) if object return object.get else return nil end end end
Iterates over every valid object in the weak map.
Examples¶ ↑
map.each do |obj| puts "Object alive: #{obj}" end
# File lib/wref/map.rb, line 150 def each(&block) enum = Enumerator.new do |yielder| ids = nil @mutex.synchronize do ids = @map.keys end ids.each do |id| if obj = get(id) yielder << [id, obj] end end end if block enum.each(&block) else return enum end end
The same as 'get!' but returns nil instead of WeakRef-error. This can be used to avoid writing lots of code.
Examples¶ ↑
obj = map.get(1) print "Object still exists in memory." if obj
# File lib/wref/map.rb, line 65 def get(id) begin return get!(id) rescue Wref::Recycled return nil end end
Returns an object by ID or raises a RefError.
Examples¶ ↑
begin obj = map.get!(1) print "Object still exists in memory." rescue Wref::Recycled print "Object has been garbage-collected." end
# File lib/wref/map.rb, line 46 def get!(id) wref = nil @mutex.synchronize do raise Wref::Recycled unless @map.key?(id) wref = @map[id] end if object = wref.get return object else delete(id) raise Wref::Recycled end end
Returns true if the given key exists in the hash.
Examples¶ ↑
print "Key exists but we dont know if the value has been garbage-collected." if map.key?(1)
# File lib/wref/map.rb, line 108 def key?(key) @mutex.synchronize do if @map.key?(key) && get(key) return true else return false end end end
Returns the length of the hash. This may not be true since invalid objects is also counted.
# File lib/wref/map.rb, line 119 def length @mutex.synchronize do return @map.length end end
Cleans the hash and returns the length. This is slower but more accurate than the ordinary length that just returns the hash-length.
# File lib/wref/map.rb, line 126 def length_valid clean return length end
Sets a new object in the map with a given ID.
# File lib/wref/map.rb, line 28 def set(id, obj) wref = Wref.new(obj, impl: @impl) @mutex.synchronize do @map[id] = wref end return nil end
Returns true if a given key exists and the object it holds is alive.
# File lib/wref/map.rb, line 92 def valid?(key) @mutex.synchronize do return false unless @map.key?(key) end begin @map[key].get return true rescue Wref::Recycled return false end end