Class: Farce::Map

Inherits:
Abstract::ConcurrentMap show all
Includes:
Shareable::Delegated, Internal::MapValueModes
Defined in:
lib/farce/map.rb,
lib/farce/map.rb

Overview

A concurrent map with direct shareable keys and strongly retained values. Transfer modes apply only to values. String keys use their frozen unary-minus form, except when comparing keys by identity. Other keys must already be shareable. Values stored through this map's mode manager are automatically unwrapped. 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. Move-mode envelopes keep their ownership across copies. dup and ordinary clone remain Ractor-shareable.

Examples:

Atomically updating a value

map = Farce::Map.new({ count: 0 })
map.update(:count) { |count| count + 1 } # => 1

Automatically making values shareable

map = Farce::Map.new(mode: :make_shareable)
map[:jobs] = []
map.update(:jobs) { |items| items + [:job] } # => [:job]
map[:jobs] # => [:job]
Ractor.shareable?(map[:jobs]) # => true

Instance Method Summary collapse

Methods included from 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, #shareable_keys?, #shareable_values?, #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, mode: :copy, 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. Valid modes are:

  • :copy - The value will be copied between Ractors. This is the default mode.
  • :make_shareable - The value will be made Ractor-shareable using Ractor.make_shareable.
  • :move - The value will be moved between Ractors. This saves memory compared to copying, and supports values that can't be copied but moved (like IO objects). However, the value will no longer be accessible on the Ractor that pushed it.
  • :mutable - A Farce::Mutable instance will be created for the value. This isn't done recursively and thus will fail for nested unshareable values.
  • :local - The value will be kept local to the Ractor that pushed it. Another ractor trying to receive it will get an error. Useful for usage contained within a single Ractor.
  • :proxy - The value will be wrapped in a Farce::Proxy that executes calls in the original Ractor.
  • :raise - An error will be raised if the value is not Ractor-shareable. Useful for enforcing shareability.
  • :dedup - The value will be deduplicated using Farce.dedup, then made Ractor-shareable. This may update and freeze the original. Already-shareable values pass through unchanged.
  • :shareable_copy - The value will be copied and the copy will be made Ractor-shareable.

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.

  • mode (Symbol) (defaults to: :copy) —

    The default transfer mode for values. Defaults to :copy.



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/farce/map.rb', line 45

class Map < Abstract::ConcurrentMap
  include Internal::MapValueModes
  include Shareable::Delegated

  private

  def new_map(**)    = Internal::StrictMap.new(**)
  def freeze_backend = @map

  Internal.prepare_map_access(self, :modes)
end