Class: Farce::Transaction::Vector
- Inherits:
-
Abstract::Vector
- Object
- Abstract::Collection
- Abstract::Vector
- Farce::Transaction::Vector
- Defined in:
- lib/farce/transaction/vector.rb
Overview
A Vector that is part of a transaction.
Instance Method Summary collapse
- #<<(value) ⇒ BasicObject
-
#[](index, length = UNDEFINED) ⇒ BasicObject, ...
Read an index without waiting for atomic-update access, or return a slice snapshot.
-
#[]=(index, value, replacement = UNDEFINED) ⇒ BasicObject
Store a value or replace a slice atomically, growing the vector if necessary.
-
#clear ⇒ self
Remove all slots.
-
#compare_and_set(index, expected, replacement, mode: nil) ⇒ Boolean
Replace an existing index only if its value matches the expected value.
-
#compare_by_identity? ⇒ Boolean
Whether values are compared by identity.
-
#each {|value| ... } ⇒ self, Enumerator
Iterate over live entries, up to the length when enumeration starts.
- #empty? ⇒ Boolean
-
#get(index) ⇒ BasicObject?
Read an index after acquiring atomic-update access.
-
#pop(count = UNDEFINED) ⇒ BasicObject, ...
Remove and return the last value, or a Vector of the last count values, atomically.
-
#push(value = UNDEFINED, *rest, mode: nil) ⇒ self, false
Append values atomically.
-
#shareable_values? ⇒ Boolean
Whether stored values must be Ractor-shareable.
-
#size ⇒ Integer
The number of slots, including nil slots.
-
#store(index, value, mode: nil) ⇒ BasicObject, false
Store a value after acquiring atomic-update access.
-
#store_if_absent(index, mode: nil) { ... } ⇒ BasicObject?
Compute and store a value only when the index is absent or contains nil.
-
#swap(index, value, mode: nil) ⇒ BasicObject?
Replace an index and return its previous value, growing the vector if necessary.
-
#update(index, mode: nil) {|value| ... } ⇒ BasicObject?
Atomically replace an index with the block result, growing the vector if necessary.
-
#upsert(index, initial, mode: nil) {|value| ... } ⇒ BasicObject?
Store initial for an absent or nil index, otherwise replace it with the block result.
Methods included from Unshareable
#initialize, #ractor_shareable?
Methods inherited from Abstract::Vector
#&, #*, #+, #-, #<=>, #append, #as_extended_json, #as_json, #assoc, #at, #bsearch, #bsearch_index, #bson_type, #chunk, #chunk_while, #combination, #compact, #compact!, #compact_blank, #concat, #deconstruct, #deep_dup, #delete, #delete_at, #delete_if, #difference, #dig, #drop, #drop_while, #each_cons, #each_index, #each_slice, #entries, #excluding, #fetch, #fetch_values, #fifth, #fill, #filter_map, #first, #flat_map, #flatten, #flatten!, #forty_two, #fourth, #from, #grep, #grep_v, #group_by, #in_groups, #in_groups_of, #in_order_of, #include?, #including, #index, #inquiry, #insert, #intersect?, #intersection, #keep_if, #last, #map, #map!, #max, #max_by, #maximum, #min, #min_by, #minimum, #minmax, #minmax_by, #pack, #partition, #permutation, #pick, #pluck, #product, #rassoc, #reject, #reject!, #repeated_combination, #repeated_permutation, #replace, #reverse, #reverse!, #reverse_each, #rfind, #rindex, #rotate, #rotate!, #sample, #second, #second_to_last, #select, #select!, #shift, #shuffle, #shuffle!, #slice, #slice!, #slice_after, #slice_before, #slice_when, #sort, #sort!, #sort_by, #sort_by!, #split, #take, #take_while, #third, #third_to_last, #to, #to_a, #to_ary, #to_bson, #to_bson_normalized_value, #to_cbor, #to_fs, #to_h, #to_json, #to_msgpack, #to_param, #to_query, #to_sentence, #to_xml, #transpose, #union, #uniq, #uniq!, #unshift, #values_at, #wait_until, #wait_until_changed, #wait_until_match, #wait_until_non_nil, #wait_until_value, #wait_while, #wait_while_match, #wait_while_value, #zip, #|
Methods inherited from Abstract::Collection
[], #count, #filter, #include?, #join, #length, #member?, #reject, #select, #to_a, #to_s
Methods included from Internal::Copyable
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Farce::Transaction::Wrapper
Instance Method Details
#<<(value) ⇒ BasicObject
75 |
# File 'lib/farce/transaction/vector.rb', line 75 def <<(value) = push(value) |
#[](index, length = UNDEFINED) ⇒ BasicObject, ...
Read an index without waiting for atomic-update access, or return a slice snapshot.
21 22 23 24 25 26 |
# File 'lib/farce/transaction/vector.rb', line 21 def [](index, length = UNDEFINED) access do next unwrap_stored(@working[index]) if length.equal?(UNDEFINED) && !index.is_a?(Range) slice(index, length) end end |
#[]=(index, value, replacement = UNDEFINED) ⇒ BasicObject
Store a value or replace a slice atomically, growing the vector if necessary. Slice replacements accept a Vector, Array-like object, or one scalar value.
42 43 44 45 46 47 48 |
# File 'lib/farce/transaction/vector.rb', line 42 def []=(index, value, replacement = UNDEFINED) if replacement.equal?(UNDEFINED) && !index.is_a?(Range) store(index, value) else write { assign_vector_slice(index, value, replacement) } end end |
#clear ⇒ self
Remove all slots.
85 86 87 88 |
# File 'lib/farce/transaction/vector.rb', line 85 def clear write { @working.clear } self end |
#compare_and_set(index, expected, replacement, mode: nil) ⇒ Boolean
Replace an existing index only if its value matches the expected value. This never grows the vector. Matching uses the configured comparison mode.
125 126 127 128 129 130 131 132 133 134 |
# File 'lib/farce/transaction/vector.rb', line 125 def compare_and_set(index, expected, replacement, mode: nil) write do next compared(@working.compare_and_set(index, expected, replacement)) unless @manager index = Integer(index) next compared(false) unless index >= -@working.size && index < @working.size && matches?(@working[index], expected, identity: @object.compare_by_identity?) @working.store(index, wrap(replacement, mode:)) true end end |
#compare_by_identity? ⇒ Boolean
Returns Whether values are compared by identity.
13 |
# File 'lib/farce/transaction/vector.rb', line 13 def compare_by_identity? = access { @object.compare_by_identity? } |
#each {|value| ... } ⇒ self, Enumerator
Iterate over live entries, up to the length when enumeration starts. Changes can affect entries not yet visited. Indexes beyond the starting length are not visited. Each entry is read separately. The block runs without holding a collection lock.
92 93 94 95 96 |
# File 'lib/farce/transaction/vector.rb', line 92 def each return enum_for(__method__) unless block_given? access { @working.snapshot.each { |value| yield unwrap_stored(value) } } self end |
#empty? ⇒ Boolean
38 |
# File 'lib/farce/transaction/vector.rb', line 38 def empty? = size.zero? |
#get(index) ⇒ BasicObject?
Read an index after acquiring atomic-update access.
30 |
# File 'lib/farce/transaction/vector.rb', line 30 def get(index) = self[index] |
#pop(count = UNDEFINED) ⇒ BasicObject, ...
Remove and return the last value, or a Vector of the last count values, atomically. This does not wait for an empty vector to become nonempty.
79 80 81 |
# File 'lib/farce/transaction/vector.rb', line 79 def pop(count = UNDEFINED) write { count.equal?(UNDEFINED) ? unwrap_stored(@working.pop) : pop_values(count) } end |
#push(value = UNDEFINED, *rest, mode: nil) ⇒ self, false
Append values atomically. Calls with one value use the scalar backend path.
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/farce/transaction/vector.rb', line 64 def push(value = UNDEFINED, *rest, mode: nil) write do if rest.empty? && !value.equal?(UNDEFINED) @working.push(wrap(value, mode:)) else push_values(value.equal?(UNDEFINED) ? rest : [value, *rest], mode:) end end self end |
#shareable_values? ⇒ Boolean
Returns Whether stored values must be Ractor-shareable.
17 |
# File 'lib/farce/transaction/vector.rb', line 17 def shareable_values? = access { @object.shareable_values? } |
#size ⇒ Integer
Returns The number of slots, including nil slots.
34 |
# File 'lib/farce/transaction/vector.rb', line 34 def size = access { @working.size } |
#store(index, value, mode: nil) ⇒ BasicObject, false
Store a value after acquiring atomic-update access.
52 53 54 |
# File 'lib/farce/transaction/vector.rb', line 52 def store(index, value, mode: nil) write { unwrap_stored(@working.store(index, wrap(value, mode:))) } end |
#store_if_absent(index, mode: nil) { ... } ⇒ BasicObject?
Compute and store a value only when the index is absent or contains nil.
107 108 109 110 |
# File 'lib/farce/transaction/vector.rb', line 107 def store_if_absent(index, mode: nil) require_block!(block_given?) write { unwrap_stored(@working.store_if_absent(index) { wrap(yield, mode:) }) } end |
#swap(index, value, mode: nil) ⇒ BasicObject?
Replace an index and return its previous value, growing the vector if necessary.
58 59 60 |
# File 'lib/farce/transaction/vector.rb', line 58 def swap(index, value, mode: nil) write { unwrap_stored(@working.swap(index, wrap(value, mode:))) } end |
#update(index, mode: nil) {|value| ... } ⇒ BasicObject?
Atomically replace an index with the block result, growing the vector if necessary.
100 101 102 103 |
# File 'lib/farce/transaction/vector.rb', line 100 def update(index, mode: nil) require_block!(block_given?) write { unwrap_stored(@working.update(index) { |value| wrap(yield(unwrap_stored(value)), mode:) }) } end |
#upsert(index, initial, mode: nil) {|value| ... } ⇒ BasicObject?
Store initial for an absent or nil index, otherwise replace it with the block result.
114 115 116 117 118 119 120 121 |
# File 'lib/farce/transaction/vector.rb', line 114 def upsert(index, initial, mode: nil) require_block!(block_given?) write do unwrap_stored(@working.upsert(index, wrap(initial, mode:)) do |value| wrap(yield(unwrap_stored(value)), mode:) end) end end |