Class: Wref::Map

Inherits:
Object
  • Object
show all
Defined in:
lib/wref/map.rb

Overview

A weak hash-map.

Examples

map = Wref::Map.new map = 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

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Map

Returns a new instance of Map.



19
20
21
22
23
24
25
# File 'lib/wref/map.rb', line 19

def initialize(args = {})
  require "monitor"

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

Instance Method Details

#cleanObject

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.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# 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) ⇒ Object

Deletes a key in the hash.



132
133
134
135
136
137
138
139
140
141
142
143
# 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) ⇒ Object

Iterates over every valid object in the weak map.

Examples

map.each do |obj|

puts "Object alive: #{obj}"

end



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# 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) ⇒ Object Also known as: []

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



65
66
67
68
69
70
71
# File 'lib/wref/map.rb', line 65

def get(id)
  begin
    return get!(id)
  rescue Wref::Recycled
    return nil
  end
end

#get!(id) ⇒ Object

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



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 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

#key?(key) ⇒ Boolean Also known as: has_key?

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)

Returns:

  • (Boolean)


108
109
110
111
112
113
114
115
116
# 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

#lengthObject

Returns the length of the hash. This may not be true since invalid objects is also counted.



119
120
121
122
123
# File 'lib/wref/map.rb', line 119

def length
  @mutex.synchronize do
    return @map.length
  end
end

#length_validObject

Cleans the hash and returns the length. This is slower but more accurate than the ordinary length that just returns the hash-length.



126
127
128
129
# File 'lib/wref/map.rb', line 126

def length_valid
  clean
  return length
end

#set(id, obj) ⇒ Object Also known as: []=

Sets a new object in the map with a given ID.



28
29
30
31
32
33
34
35
36
# 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

#valid?(key) ⇒ Boolean

Returns true if a given key exists and the object it holds is alive.

Returns:

  • (Boolean)


92
93
94
95
96
97
98
99
100
101
102
103
# 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