class Concurrent::Map
`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
Public Class Methods
new(options = nil, &block)
click to toggle source
@!method delete_pair
@!macro map_method_is_atomic
Calls superclass method
# File lib/concurrent/map.rb, line 81 def initialize(options = nil, &block) if options.kind_of?(::Hash) validate_options_hash!(options) else options = nil end super(options) @default_proc = block end
Public Instance Methods
[](key)
click to toggle source
Calls superclass method
# 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
Also aliased as: get
each_key() { |k| ... }
click to toggle source
# File lib/concurrent/map.rb, line 166 def each_key each_pair {|k, v| yield k} end
each_value() { |v| ... }
click to toggle source
# File lib/concurrent/map.rb, line 170 def each_value each_pair {|k, v| yield v} end
empty?()
click to toggle source
# File lib/concurrent/map.rb, line 182 def empty? each_pair {|k, v| return false} true end
fetch(key, default_value = NULL) { |key| ... }
click to toggle source
@!macro [attach] map_method_not_atomic
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.
# 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
fetch_or_store(key, default_value = NULL) { |key| ... }
click to toggle source
@!macro map_method_not_atomic
# 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
inspect()
click to toggle source
@!visibility private
# File lib/concurrent/map.rb, line 208 def inspect format '%s entries=%d default_proc=%s>', to_s[0..-2], size.to_s, @default_proc.inspect end
key(value)
click to toggle source
# File lib/concurrent/map.rb, line 176 def key(value) each_pair {|k, v| return k if v == value} nil end
Also aliased as: index
keys()
click to toggle source
# File lib/concurrent/map.rb, line 154 def keys arr = [] each_pair {|k, v| arr << k} arr end
marshal_dump()
click to toggle source
# 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
marshal_load(hash)
click to toggle source
# File lib/concurrent/map.rb, line 200 def marshal_load(hash) initialize populate_from(hash) end
put_if_absent(key, value)
click to toggle source
@!macro map_method_is_atomic
# File lib/concurrent/map.rb, line 138 def put_if_absent(key, value) computed = false result = compute_if_absent(key) do computed = true value end computed ? nil : result end
size()
click to toggle source
# File lib/concurrent/map.rb, line 187 def size count = 0 each_pair {|k, v| count += 1} count end
value?(value)
click to toggle source
# File lib/concurrent/map.rb, line 147 def value?(value) each_value do |v| return true if value.equal?(v) end false end
values()
click to toggle source
# File lib/concurrent/map.rb, line 160 def values arr = [] each_pair {|k, v| arr << v} arr end
Private Instance Methods
initialize_copy(other)
click to toggle source
Calls superclass method
# File lib/concurrent/map.rb, line 217 def initialize_copy(other) super populate_from(other) end
populate_from(hash)
click to toggle source
# File lib/concurrent/map.rb, line 222 def populate_from(hash) hash.each_pair {|k, v| self[k] = v} self end
raise_fetch_no_key()
click to toggle source
# File lib/concurrent/map.rb, line 213 def raise_fetch_no_key raise KeyError, 'key not found' end
validate_options_hash!(options)
click to toggle source
# File lib/concurrent/map.rb, line 227 def validate_options_hash!(options) if (initial_capacity = options[:initial_capacity]) && (!initial_capacity.kind_of?(Integer) || initial_capacity < 0) raise ArgumentError, ":initial_capacity must be a positive Integer" end if (load_factor = options[:load_factor]) && (!load_factor.kind_of?(Numeric) || load_factor <= 0 || load_factor > 1) raise ArgumentError, ":load_factor must be a number between 0 and 1" end end