Class: Concurrent::Map
- Inherits:
-
Collection::MapImplementation
- Object
- Concurrent::Map
- Defined in:
- lib/concurrent/map.rb
Overview
Concurrent::Map
is a hash-like object and should have much better performance
characteristics, especially under high concurrency, than Concurrent::Hash
.
However, Concurrent::Map
is not strictly semantically equivalent to a ruby Hash
-- for instance, it does not necessarily retain ordering by insertion time as Hash
does. For most uses it should do fine though, and we recommend you consider
Concurrent::Map
instead of Concurrent::Hash
for your concurrency-safe hash needs.
require 'concurrent'
map = Concurrent::Map.new
Constant Summary
Instance Method Summary (collapse)
- - (undocumented) [](key) (also: #get)
-
- (undocumented) compute
This method is atomic.
-
- (undocumented) compute_if_absent
This method is atomic.
-
- (undocumented) compute_if_present
This method is atomic.
-
- (undocumented) delete
This method is atomic.
-
- (undocumented) delete_pair
This method is atomic.
- - (undocumented) each_key
- - (undocumented) each_value
- - (Boolean) empty?
-
- (undocumented) fetch(key, default_value = NULL)
The "fetch-then-act" methods of
Map
are not atomic. -
- (undocumented) fetch_or_store(key, default_value = NULL)
The "fetch-then-act" methods of
Map
are not atomic. -
- (undocumented) get_and_set
This method is atomic.
-
- (Map) initialize(options = nil, &block)
constructor
A new instance of Map.
-
- (undocumented) inspect
override default #inspect() method: firstly, we don't want to be spilling our guts (i-vars), secondly, MRI backend's #inspect() call on its @backend i-var will bump @backend's iter level while possibly yielding GVL.
- - (undocumented) key(value) (also: #index)
- - (undocumented) keys
- - (undocumented) marshal_dump
- - (undocumented) marshal_load(hash)
-
- (undocumented) merge_pair
This method is atomic.
-
- (undocumented) put_if_absent(key, value)
This method is atomic.
-
- (undocumented) replace_if_exists
This method is atomic.
-
- (undocumented) replace_pair
This method is atomic.
- - (undocumented) size
- - (Boolean) value?(value)
- - (undocumented) values
Constructor Details
- (Map) initialize(options = nil, &block)
Returns a new instance of Map
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/concurrent/map.rb', line 81 def initialize( = nil, &block) if .kind_of?(::Hash) () else = nil end super() @default_proc = block end |
Instance Method Details
- (undocumented) [](key) Also known as: get
92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/concurrent/map.rb', line 92 def [](key) if value = super # non-falsy value is an existing mapping, return it right away value # re-check is done with get_or_default(key, NULL) instead of a simple !key?(key) in order to avoid a race condition, whereby by the time the current thread gets to the key?(key) call # a key => value mapping might have already been created by a different thread (key?(key) would then return true, this elsif branch wouldn't be taken and an incorrent +nil+ value # would be returned) # note: nil == value check is not technically necessary elsif @default_proc && nil == value && NULL == (value = get_or_default(key, NULL)) @default_proc.call(self, key) else value end end |
- (undocumented) compute
This method is atomic. Atomic methods of Map
which accept a block
do not allow the self
instance to be used within the block. Doing
so will cause a deadlock.
|
# File 'lib/concurrent/map.rb', line 60
|
- (undocumented) compute_if_absent
This method is atomic. Atomic methods of Map
which accept a block
do not allow the self
instance to be used within the block. Doing
so will cause a deadlock.
|
# File 'lib/concurrent/map.rb', line 54
|
- (undocumented) compute_if_present
This method is atomic. Atomic methods of Map
which accept a block
do not allow the self
instance to be used within the block. Doing
so will cause a deadlock.
|
# File 'lib/concurrent/map.rb', line 57
|
- (undocumented) delete
This method is atomic. Atomic methods of Map
which accept a block
do not allow the self
instance to be used within the block. Doing
so will cause a deadlock.
|
# File 'lib/concurrent/map.rb', line 75
|
- (undocumented) delete_pair
This method is atomic. Atomic methods of Map
which accept a block
do not allow the self
instance to be used within the block. Doing
so will cause a deadlock.
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/concurrent/map.rb', line 81 def initialize( = nil, &block) if .kind_of?(::Hash) () else = nil end super() @default_proc = block end |
- (undocumented) each_key
166 167 168 |
# File 'lib/concurrent/map.rb', line 166 def each_key each_pair {|k, v| yield k} end |
- (undocumented) each_value
170 171 172 |
# File 'lib/concurrent/map.rb', line 170 def each_value each_pair {|k, v| yield v} end |
- (Boolean) empty?
182 183 184 185 |
# File 'lib/concurrent/map.rb', line 182 def empty? each_pair {|k, v| return false} true end |
- (undocumented) fetch(key, default_value = NULL)
The "fetch-then-act" methods of Map
are not atomic. Map
is intended
to be use as a concurrency primitive with strong happens-before
guarantees. It is not intended to be used as a high-level abstraction
supporting complex operations. All read and write operations are
thread safe, but no guarantees are made regarding race conditions
between the fetch operation and yielding to the block. Additionally,
this method does not support recursion. This is due to internal
constraints that are very unlikely to change in the near future.
118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/concurrent/map.rb', line 118 def fetch(key, default_value = NULL) if NULL != (value = get_or_default(key, NULL)) value elsif block_given? yield key elsif NULL != default_value default_value else raise_fetch_no_key end end |
- (undocumented) fetch_or_store(key, default_value = NULL)
The "fetch-then-act" methods of Map
are not atomic. Map
is intended
to be use as a concurrency primitive with strong happens-before
guarantees. It is not intended to be used as a high-level abstraction
supporting complex operations. All read and write operations are
thread safe, but no guarantees are made regarding race conditions
between the fetch operation and yielding to the block. Additionally,
this method does not support recursion. This is due to internal
constraints that are very unlikely to change in the near future.
131 132 133 134 135 |
# File 'lib/concurrent/map.rb', line 131 def fetch_or_store(key, default_value = NULL) fetch(key) do put(key, block_given? ? yield(key) : (NULL == default_value ? raise_fetch_no_key : default_value)) end end |
- (undocumented) get_and_set
This method is atomic. Atomic methods of Map
which accept a block
do not allow the self
instance to be used within the block. Doing
so will cause a deadlock.
|
# File 'lib/concurrent/map.rb', line 72
|
- (undocumented) inspect
override default #inspect() method: firstly, we don't want to be spilling our guts (i-vars), secondly, MRI backend's
inspect() call on its @backend i-var will bump @backend's iter level while possibly yielding GVL
211 212 213 214 |
# File 'lib/concurrent/map.rb', line 211 def inspect id_str = (object_id << 1).to_s(16).rjust(DEFAULT_OBJ_ID_STR_WIDTH, '0') "#<#{self.class.name}:0x#{id_str} entries=#{size} default_proc=#{@default_proc.inspect}>" end |
- (undocumented) key(value) Also known as: index
176 177 178 179 |
# File 'lib/concurrent/map.rb', line 176 def key(value) each_pair {|k, v| return k if v == value} nil end |
- (undocumented) keys
154 155 156 157 158 |
# File 'lib/concurrent/map.rb', line 154 def keys arr = [] each_pair {|k, v| arr << k} arr end |
- (undocumented) marshal_dump
193 194 195 196 197 198 |
# File 'lib/concurrent/map.rb', line 193 def marshal_dump raise TypeError, "can't dump hash with default proc" if @default_proc h = {} each_pair {|k, v| h[k] = v} h end |
- (undocumented) marshal_load(hash)
200 201 202 203 |
# File 'lib/concurrent/map.rb', line 200 def marshal_load(hash) initialize populate_from(hash) end |
- (undocumented) merge_pair
This method is atomic. Atomic methods of Map
which accept a block
do not allow the self
instance to be used within the block. Doing
so will cause a deadlock.
|
# File 'lib/concurrent/map.rb', line 63
|
- (undocumented) put_if_absent(key, value)
This method is atomic. Atomic methods of Map
which accept a block
do not allow the self
instance to be used within the block. Doing
so will cause a deadlock.
|
# File 'lib/concurrent/map.rb', line 51
|
- (undocumented) replace_if_exists
This method is atomic. Atomic methods of Map
which accept a block
do not allow the self
instance to be used within the block. Doing
so will cause a deadlock.
|
# File 'lib/concurrent/map.rb', line 69
|
- (undocumented) replace_pair
This method is atomic. Atomic methods of Map
which accept a block
do not allow the self
instance to be used within the block. Doing
so will cause a deadlock.
|
# File 'lib/concurrent/map.rb', line 66
|
- (undocumented) size
187 188 189 190 191 |
# File 'lib/concurrent/map.rb', line 187 def size count = 0 each_pair {|k, v| count += 1} count end |
- (Boolean) value?(value)
147 148 149 150 151 152 |
# File 'lib/concurrent/map.rb', line 147 def value?(value) each_value do |v| return true if value.equal?(v) end false end |
- (undocumented) values
160 161 162 163 164 |
# File 'lib/concurrent/map.rb', line 160 def values arr = [] each_pair {|k, v| arr << v} arr end |