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

new(args = {}) click to toggle source
# File lib/wref/map.rb, line 19
def initialize(args = {})
  require "monitor"

  @map = {}
  @mutex = Monitor.new
  @impl = args[:impl]
end

Public Instance Methods

[](id)
Alias for: get
[]=(id, obj)
Alias for: set
clean() click to toggle source

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
delete(key) click to toggle source

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
each(&block) click to toggle source

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
get(id) click to toggle source

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
Also aliased as: []
get!(id) click to toggle source

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
has_key?(key)

Make it hash-compatible.

Alias for: key?
key?(key) click to toggle source

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
Also aliased as: has_key?
length() click to toggle source

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
length_valid() click to toggle source

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
set(id, obj) click to toggle source

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
Also aliased as: []=
valid?(key) click to toggle source

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