Class: Farce::Strict::Map

Inherits:
Abstract::ConcurrentMap show all
Includes:
Farce::Shareable::Delegated
Defined in:
lib/farce/strict/map.rb

Overview

A Ractor-shareable concurrent map that stores shareable keys and values directly. Updates on different keys can run concurrently.

Clearing the map invalidates unfinished updates so they cannot restore removed entries.

dup and clone copy entries into independent storage while sharing stored values. dup and ordinary clone remain Ractor-shareable.

Examples:

Atomically counting occurrences

counts = Farce::Strict::Map.new
counts.upsert(:ruby, 1) { |count| count + 1 } # => 1
counts.upsert(:ruby, 1) { |count| count + 1 } # => 2

Instance Method Summary collapse

Methods included from Farce::Shareable

#ractor_shareable?

Methods inherited from Abstract::ConcurrentMap

#[], #[]=, #clear, #compact!, #compact_blank!, #compare_and_set, #compare_keys_by_identity?, #compare_values_by_identity?, #delete, #delete_if, #each, #each_key, #each_value, #fetch, #get, #getkey, #keep_if, #key?, #keys, #merge!, #reject!, #reverse_merge!, #select!, #size, #store, #store_if_absent, #swap, #transform_values!, #update, #upsert, #values, #wait_until, #wait_until_changed, #wait_until_match, #wait_until_non_nil, #wait_until_value, #wait_while, #wait_while_match, #wait_while_value

Methods included from Abstract::DuplicableMap

#compact, #compact_blank, #deep_dup, #duplicable?, #except, #flatten, #invert, #merge, #reject, #reverse_merge, #select, #slice, #stringify_keys, #symbolize_keys, #to_proc, #transform_keys, #transform_values, #with_indifferent_access

Methods inherited from Abstract::Map

#[], #[]=, #as_extended_json, #as_json, #assert_valid_keys, #assoc, #bson_type, #clear, #compare_by_identity?, #compare_keys_by_identity?, #compare_values_by_identity?, #deconstruct_keys, #delete, #dig, #each, #each_key, #each_pair, #each_value, #empty?, #fetch, #fetch_values, #getkey, #has_key?, #key, #key?, #keys, #length, #rassoc, #size, #store, #store_if_absent, #to_a, #to_bson, #to_bson_normalized_value, #to_cbor, #to_h, #to_hash, #to_json, #to_msgpack, #to_query, #to_s, #value?, #values_at, #weak_keys?, #weak_values?

Constructor Details

#initialize(initial_mapping = nil, normalize_keys: nil, compare_by_identity: false, compare_keys_by_identity: compare_by_identity, compare_values_by_identity: compare_by_identity) ⇒ Map

Create a map with optional initial entries.

Parameters:

  • initial_mapping (Hash, Farce::Abstract::Map, #each, nil) (defaults to: nil) —

    The entries to store initially. Each iteration must yield a key-value pair. Nil creates an empty map.

  • normalize_keys (Symbol, Proc, Hash, Farce::Abstract::Map, nil) (defaults to: nil) —

    Converts incoming keys to their canonical stored form:

    • If a Symbol is provided, it will be used as a method name to call on each key.
    • If a Proc is provided, it will be called with each key and should return the normalized key.
    • If a Hash or Map is provided, it will be used to look up the normalized key for each incoming key.
  • compare_by_identity (Boolean) (defaults to: false) —

    The default identity-comparison setting for keys and values. Defaults to false.

  • compare_keys_by_identity (Boolean) (defaults to: compare_by_identity) —

    Whether keys use object identity instead of hash and eql?. Defaults to compare_by_identity.

  • compare_values_by_identity (Boolean) (defaults to: compare_by_identity) —

    Whether values use object identity instead of ==. Defaults to compare_by_identity.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/farce/strict/map.rb', line 23

def initialize(
  initial_mapping = nil,
  normalize_keys: nil,
  compare_by_identity: false,
  compare_keys_by_identity: compare_by_identity,
  compare_values_by_identity: compare_by_identity
)
  initial_mapping = convert_entries(initial_mapping)
  restoring  = Internal::KeyNormalizer.restoration?(normalize_keys)
  normalizer = Internal::KeyNormalizer.build(normalize_keys, shareable: true)
  populate   = initial_mapping && ((normalizer && !restoring) || !initial_mapping.is_a?(Hash))
  @map       = Internal::StrictMap.new(
    populate ? nil : initial_mapping,
    compare_by_identity:,
    compare_keys_by_identity:,
    compare_values_by_identity:,
  )
  Internal::KeyNormalizer.install_concurrent(self, normalizer) unless restoring
  initial_mapping.each { |key, value| self[key] = value } if populate
  Internal::KeyNormalizer.install_concurrent(self, normalizer) if restoring
  super()
end

Instance Method Details

#shareable_keys? ⇒ Boolean

Returns:

  • (Boolean)


46
# File 'lib/farce/strict/map.rb', line 46

def shareable_keys? = true

#shareable_values? ⇒ Boolean

Returns:

  • (Boolean)


47
# File 'lib/farce/strict/map.rb', line 47

def shareable_values? = true