Class: Farce::Abstract::Vector Abstract
- Inherits:
-
Collection
- Object
- Collection
- Farce::Abstract::Vector
- Includes:
- Internal::MarshalSupport::Vector
- Defined in:
- lib/farce/abstract/vector.rb,
lib/farce/integrations/bson.rb,
lib/farce/integrations/cbor.rb,
lib/farce/integrations/msgpack.rb,
lib/farce/integrations/shared/to_json.rb,
lib/farce/integrations/active_support/vector.rb
Overview
Superclass for concurrent indexed collections.
Negative indexes count from the end. Assignments beyond the end fill gaps with nil. Atomic updates reserve the entire vector. Reads through #[] do not wait for updates. Timeouts are finite, non-negative seconds. Nil waits indefinitely for access.
Direct Known Subclasses
Local::Vector, Strict::Vector, Transaction::Vector, Unshared::Vector, Vector
JSON Integration collapse
-
#to_json(*arguments) ⇒ String
Serialize a logical snapshot as a JSON Array.
ActiveSupport Integration collapse
-
#as_json(options = nil) ⇒ Array
Convert a snapshot to ActiveSupport's explicit JSON representation.
-
#compact_blank ⇒ Vector
Entries for which
blank?is false, excluding nil and false. -
#deep_dup ⇒ Vector
Copy entries using ActiveSupport's deep-copy rules and the Vector's storage rules.
-
#excluding(*elements) ⇒ Vector
(also: #without)
Exclude entries using Array's hash-based difference semantics.
-
#fifth ⇒ BasicObject?
The fifth entry, or nil if absent.
-
#forty_two ⇒ BasicObject?
The forty-second entry, or nil if absent.
-
#fourth ⇒ BasicObject?
The fourth entry, or nil if absent.
-
#from(position) ⇒ Vector
Return entries starting at position from one snapshot.
-
#in_groups(number, fill_with = nil) {|group| ... } ⇒ Vector
Divide a snapshot into a requested number of Vector groups.
-
#in_groups_of(number, fill_with = nil) {|group| ... } ⇒ Vector, self
Divide a snapshot into Vector groups with a maximum size.
-
#in_order_of(key, series, filter: true) ⇒ Vector
Order a snapshot by the keys in series, preserving retained entries.
-
#including(*elements) ⇒ Vector
Append entries to a new Vector, flattening argument Arrays by one level.
-
#inquiry ⇒ ActiveSupport::ArrayInquirer
Create ActiveSupport's specialized query wrapper from a logical snapshot.
-
#maximum(key) ⇒ BasicObject?
Find the maximum extracted value without storing intermediate results in a Vector.
-
#minimum(key) ⇒ BasicObject?
Find the minimum extracted value without storing intermediate results in a Vector.
-
#pick(*keys) ⇒ BasicObject, ...
Extract keys from the first entry in a snapshot.
-
#pluck(*keys) ⇒ Vector
Extract keys from each entry in a snapshot.
-
#second ⇒ BasicObject?
The second entry, or nil if absent.
-
#second_to_last ⇒ BasicObject?
The second entry from the end, or nil if absent.
-
#split(value = nil) {|entry| ... } ⇒ Vector
Split a snapshot at matching entries, omitting the separators.
-
#third ⇒ BasicObject?
The third entry, or nil if absent.
-
#third_to_last ⇒ BasicObject?
The third entry from the end, or nil if absent.
-
#to(position) ⇒ Vector
Return entries through position from one snapshot.
-
#to_fs(format = :default) ⇒ String
(also: #to_formatted_s)
Format a snapshot, optionally as a database ID list.
-
#to_param ⇒ String
The snapshot's URL parameter representation, joined with slashes.
-
#to_query(key) ⇒ String
The encoded query string for the snapshot.
-
#to_sentence(options = {}) ⇒ String
Format a snapshot as a sentence using ActiveSupport's connectors and locale.
-
#to_xml(options = {}) {|builder| ... } ⇒ String
Serialize a logical snapshot with ActiveSupport's Array XML conversion.
Methods included from Internal::Copyable
Instance Method Summary collapse
-
#&(other) ⇒ Vector
Intersect with another sequence.
-
#*(other) ⇒ Vector, String
Repeat a snapshot, or join it when a String separator is supplied.
-
#+(other) ⇒ Vector
Concatenate a snapshot with another sequence.
-
#-(other) ⇒ Vector
Remove values present in another sequence.
-
#<<(value) ⇒ self
Append a single value without a timeout.
-
#<=>(other) ⇒ Integer?
Compare logical entries lexicographically, as with Array.
-
#[](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.
-
#append(*values, timeout: nil) ⇒ self, false
Append values using the same options as #push.
-
#as_extended_json(**options) ⇒ Array
Represent a snapshot as Extended JSON, forwarding BSON's format options.
-
#assoc(key) ⇒ Array, ...
Find the first pair whose first value equals key.
-
#at(index) ⇒ BasicObject, ...
Read an index without waiting for atomic-update access, or return a slice snapshot.
-
#bsearch {|value| ... } ⇒ BasicObject, ...
Binary-search the live entries and return the matching value.
-
#bsearch_index {|value| ... } ⇒ Integer, ...
Binary-search the live entries and return the matching index.
-
#bson_type ⇒ String
Identify this value as a BSON array when embedded in a document or array.
-
#chunk {|value| ... } ⇒ Enumerator
Group adjacent entries by a block-generated key.
-
#chunk_while {|left, right| ... } ⇒ Enumerator
Group adjacent entries while the block accepts each pair.
-
#clear ⇒ self
Remove all slots.
-
#combination(count) {|tuple| ... } ⇒ self, Enumerator
Visit combinations of entries in a snapshot.
-
#compact ⇒ Vector
Remove nil values.
-
#compact! ⇒ self?
Remove nil entries atomically.
-
#compare_and_set(index, expected, replacement, timeout: nil) ⇒ Boolean
Replace an existing index only if its value matches the expected value.
-
#compare_by_identity? ⇒ Boolean
Whether values are compared by identity.
-
#concat(*sources) ⇒ self
Append snapshots of one or more sequences and return this vector.
-
#deconstruct ⇒ Array<BasicObject>
Return a new Array containing a logical snapshot of the values.
-
#delete(value) {|value| ... } ⇒ BasicObject?
Remove all matching values using the configured comparison mode.
-
#delete_at(index) ⇒ BasicObject?
Remove the entry at an index and shift later entries left atomically.
-
#delete_if {|value| ... } ⇒ self, Enumerator
Atomically remove entries for which the block returns a truthy value.
-
#difference(*others) ⇒ Vector
Remove values present in any supplied sequence.
-
#dig(index, *identifiers) ⇒ BasicObject?
Recursively retrieve a nested value.
-
#drop(count) ⇒ Vector
Return all entries after count entries.
-
#drop_while {|value| ... } ⇒ Vector, Enumerator
Drop entries before the first rejected value.
-
#each {|value| ... } ⇒ self, Enumerator
Iterate over live entries, up to the length when enumeration starts.
-
#each_cons(count) {|window| ... } ⇒ self, Enumerator
Yield same-kind overlapping windows from live iteration.
-
#each_index {|index| ... } ⇒ self, Enumerator
Iterate over indexes up to the length when enumeration starts.
-
#each_slice(count) {|window| ... } ⇒ self, Enumerator
Yield same-kind windows from live iteration.
-
#entries ⇒ Vector
Materialize enumeration as a Vector rather than an Array.
-
#fetch(index, *fallback) {|index| ... } ⇒ BasicObject
Fetch a value by index, with Array-compatible fallback behavior.
-
#fetch_values(*indexes) {|index| ... } ⇒ Vector
Fetch several values.
-
#fill(*arguments) ⇒ self
Fill all or part of the vector atomically, growing it when necessary.
-
#filter_map {|value| ... } ⇒ Vector, Enumerator
Transform accepted values into a Vector.
-
#first(count = UNDEFINED) ⇒ BasicObject, ...
Return one value, or a Vector when a count is supplied.
-
#flat_map {|value| ... } ⇒ Vector, Enumerator
(also: #collect_concat)
Transform and flatten one Array or Vector level.
-
#flatten(level = -1)) ⇒ Vector
Expand nested Arrays and Vectors into a new Vector.
-
#flatten!(level = -1)) ⇒ self?
Expand nested Arrays and Vectors atomically.
-
#get(index, timeout: nil) ⇒ BasicObject?
Read an index after acquiring atomic-update access.
-
#grep(pattern) {|value| ... } ⇒ Vector
Select values matched by pattern, optionally transforming them.
-
#grep_v(pattern) {|value| ... } ⇒ Vector
Select values not matched by pattern, optionally transforming them.
-
#group_by {|value| ... } ⇒ Hash{BasicObject => Vector}, Enumerator
Group live entries into same-kind Vectors.
-
#include?(value) ⇒ Boolean
(also: #member?)
Return whether a live entry equals value.
-
#index(value = UNDEFINED) {|entry| ... } ⇒ Integer, ...
(also: #find_index)
Return the first matching index.
-
#insert(index, *values) ⇒ self
Insert values before an index atomically.
-
#intersect?(other) ⇒ Boolean
Return whether another sequence shares any value.
-
#intersection(*others) ⇒ Vector
Intersect with every supplied sequence.
-
#keep_if {|value| ... } ⇒ self, Enumerator
Keep entries accepted by the block, publishing the result atomically.
-
#last(count = UNDEFINED) ⇒ BasicObject, ...
Return one value, or a Vector when a count is supplied.
-
#map {|value| ... } ⇒ Vector, Enumerator
(also: #collect)
Transform a snapshot into a Vector.
-
#map! {|value| ... } ⇒ self, Enumerator
(also: #collect!)
Replace each entry with the block result, publishing all replacements together.
-
#max(count = UNDEFINED) {|left, right| ... } ⇒ BasicObject, ...
Return one maximum, or a Vector when count is supplied.
-
#max_by(count = UNDEFINED) {|value| ... } ⇒ BasicObject, ...
Return one block maximum, or a Vector when count is supplied.
-
#min(count = UNDEFINED) {|left, right| ... } ⇒ BasicObject, ...
Return one minimum, or a Vector when count is supplied.
-
#min_by(count = UNDEFINED) {|value| ... } ⇒ BasicObject, ...
Return one block minimum, or a Vector when count is supplied.
-
#minmax {|left, right| ... } ⇒ Vector
Return minimum and maximum in a Vector.
-
#minmax_by {|value| ... } ⇒ Vector, Enumerator
Return the block minimum and maximum in a Vector.
-
#pack(format, buffer: nil) ⇒ String
Pack a logical snapshot according to format.
-
#partition {|value| ... } ⇒ Vector, Enumerator
Split live entries into accepted and rejected Vectors, wrapped in a Vector.
-
#permutation(count = UNDEFINED) {|tuple| ... } ⇒ self, Enumerator
Visit permutations of entries in a snapshot.
-
#pop(count = UNDEFINED, timeout: nil) ⇒ BasicObject, ...
Remove and return the last value, or a Vector of the last count values, atomically.
-
#product(*others) {|tuple| ... } ⇒ Vector, self
Produce tuples containing one entry from each sequence.
-
#push(value = UNDEFINED, *rest, timeout: nil) ⇒ self, false
Append values atomically.
-
#rassoc(value) ⇒ Array, ...
Find the first pair whose second value equals value.
-
#reject {|value| ... } ⇒ Vector, Enumerator
Remove values accepted by a block.
-
#reject! {|value| ... } ⇒ self, ...
Remove entries accepted by the block, returning nil if no entry was removed.
-
#repeated_combination(count) {|tuple| ... } ⇒ self, Enumerator
Visit combinations that may reuse entries in a snapshot.
-
#repeated_permutation(count) {|tuple| ... } ⇒ self, Enumerator
Visit permutations that may reuse entries in a snapshot.
-
#replace(source) ⇒ self
Replace all entries atomically with the contents of another sequence.
-
#reverse ⇒ Vector
Return a reversed snapshot.
-
#reverse! ⇒ self
Reverse all entries atomically.
-
#reverse_each {|value| ... } ⇒ self, Enumerator
Iterate over live entries from the last index when enumeration starts.
-
#rfind(if_none = nil) {|value| ... } ⇒ BasicObject, ...
Find a value by searching from the end.
-
#rindex(value = UNDEFINED) {|entry| ... } ⇒ Integer, ...
Return the last matching index.
-
#rotate(count = 1) ⇒ Vector
Return a rotated snapshot.
-
#rotate!(count = 1) ⇒ self
Rotate all entries atomically.
-
#sample(count = UNDEFINED, random: Random) ⇒ BasicObject, ...
Return one sample, or a Vector when count is supplied.
-
#select {|value| ... } ⇒ Vector, Enumerator
(also: #filter, #find_all)
Keep values accepted by a block.
-
#select! {|value| ... } ⇒ self, ...
(also: #filter!)
Keep entries accepted by the block, returning nil if no entry was removed.
-
#shareable_values? ⇒ Boolean
Whether stored values must be Ractor-shareable.
-
#shift(count = UNDEFINED) ⇒ BasicObject, ...
Remove the first entry, or the first count entries, atomically.
-
#shuffle(random: Random) ⇒ Vector
Return a shuffled snapshot.
-
#shuffle!(random: Random) ⇒ self
Shuffle all entries atomically without transferring retained values again.
-
#size ⇒ Integer
The number of slots, including nil slots.
-
#slice(index, length = UNDEFINED) ⇒ BasicObject, ...
Return an element or subsequence from a snapshot.
-
#slice!(index, length = UNDEFINED) ⇒ BasicObject, ...
Remove a range of entries atomically.
-
#slice_after(*arguments) {|value| ... } ⇒ Enumerator
Group a snapshot after matching entries.
-
#slice_before(*arguments) {|value| ... } ⇒ Enumerator
Group a snapshot before matching entries.
-
#slice_when {|left, right| ... } ⇒ Enumerator
Group a snapshot between pairs accepted by the block.
-
#sort {|left, right| ... } ⇒ Vector
Return a sorted snapshot.
-
#sort! {|left, right| ... } ⇒ self
Sort all entries atomically using logical values.
-
#sort_by {|value| ... } ⇒ Vector, Enumerator
Sort a snapshot by block results.
-
#sort_by! {|value| ... } ⇒ self, Enumerator
Sort all entries atomically by the block result.
-
#store(index, value, timeout: nil) ⇒ BasicObject, false
Store a value after acquiring atomic-update access.
-
#store_if_absent(index, timeout: nil) { ... } ⇒ BasicObject?
Compute and store a value only when the index is absent or contains nil.
-
#swap(index, replacement, timeout: nil) ⇒ BasicObject?
Replace an index and return its previous value, growing the vector if necessary.
-
#take(count) ⇒ Vector
Return the first count entries.
-
#take_while {|value| ... } ⇒ Vector, Enumerator
Return entries before the first rejected value.
-
#to_a ⇒ Array<BasicObject>
Return a new Array containing a logical snapshot of the values.
-
#to_ary ⇒ Array<BasicObject>
Return an Array snapshot for implicit Array conversion, such as
[].concat(vector). -
#to_bson(buffer = ::BSON::ByteBuffer.new) ⇒ BSON::ByteBuffer
Serialize a snapshot using BSON's array representation.
-
#to_bson_normalized_value ⇒ Array
Return a snapshot with nested values normalized by BSON.
-
#to_cbor(*arguments) ⇒ String, ...
Serialize a snapshot as a CBOR array.
-
#to_h {|value| ... } ⇒ Hash
Convert pair-like entries to a Hash.
-
#to_msgpack(*arguments) ⇒ String, ::MessagePack::Packer
Serialize a snapshot as a MessagePack array.
-
#transpose ⇒ Vector
Transpose rows represented by Arrays or Vectors.
-
#union(*others) ⇒ Vector
Union with every supplied sequence.
-
#uniq {|value| ... } ⇒ Vector
Remove duplicate values, retaining the first stored entry.
-
#uniq! {|value| ... } ⇒ self?
Remove duplicate entries atomically, retaining the first stored entry.
-
#unshift(*values) ⇒ self
(also: #prepend)
Prepend values atomically using the vector's default transfer mode.
-
#update(index, timeout: nil) {|value| ... } ⇒ BasicObject?
Atomically replace an index with the block result, growing the vector if necessary.
-
#upsert(index, initial, timeout: nil) {|value| ... } ⇒ BasicObject?
Store initial for an absent or nil index, otherwise replace it with the block result.
-
#values_at(*indexes) ⇒ Vector
Select values at indexes and ranges.
-
#wait_until(index, timeout: nil) {|value| ... } ⇒ BasicObject?
Wait until a block condition matches the value at an index.
-
#wait_until_changed(index, expected, timeout: nil) ⇒ BasicObject?
Wait until an index no longer matches expected.
-
#wait_until_match(index, object, timeout: nil) ⇒ BasicObject?
Wait until
object === valueis true. -
#wait_until_non_nil(index, timeout: nil) ⇒ BasicObject?
Wait until an index contains a non-nil value.
-
#wait_until_value(index, object, timeout: nil) ⇒ BasicObject?
Wait until the current value equals an object using the configured comparison mode.
-
#wait_while(index, timeout: nil) {|value| ... } ⇒ BasicObject?
Wait while the block returns a truthy value.
-
#wait_while_match(index, object, timeout: nil) ⇒ BasicObject?
Wait while
object === valueis true. -
#wait_while_value ⇒ BasicObject?
Wait until an index no longer matches expected.
-
#zip(*others) {|row| ... } ⇒ Vector?
Zip values into Vector rows.
-
#|(other) ⇒ Vector
Union with another sequence.
Methods inherited from Collection
[], #count, #empty?, #join, #length, #to_s
Instance Method Details
#&(other) ⇒ Vector
Intersect with another sequence.
719 |
# File 'lib/farce/abstract/vector.rb', line 719 def &(other) = derive_array_operation(:&, other) |
#*(other) ⇒ Vector, String
Repeat a snapshot, or join it when a String separator is supplied.
705 706 707 708 709 |
# File 'lib/farce/abstract/vector.rb', line 705 def *(other) separator = String.try_convert(other) return join(separator) if separator build_derived_vector(internal_vector.snapshot * other) end |
#+(other) ⇒ Vector
Concatenate a snapshot with another sequence.
692 693 694 695 696 697 698 699 700 |
# File 'lib/farce/abstract/vector.rb', line 692 def +(other) snapshot = internal_vector.snapshot appended = if other.equal?(self) snapshot else reusable_operand_snapshot(other) || vector_operand(other).map { derived_storage(it) } end build_derived_vector(snapshot + appended) end |
#-(other) ⇒ Vector
Remove values present in another sequence.
714 |
# File 'lib/farce/abstract/vector.rb', line 714 def -(other) = derive_array_operation(:-, other) |
#<<(value) ⇒ self
Append a single value without a timeout.
1135 |
# File 'lib/farce/abstract/vector.rb', line 1135 def <<(value) = push(value) |
#<=>(other) ⇒ Integer?
Compare logical entries lexicographically, as with Array.
1234 1235 1236 1237 |
# File 'lib/farce/abstract/vector.rb', line 1234 def <=>(other) return 0 if equal?(other) compare_vector(other) end |
#[](index, length = UNDEFINED) ⇒ BasicObject, ...
Read an index without waiting for atomic-update access, or return a slice snapshot.
1066 1067 1068 1069 |
# File 'lib/farce/abstract/vector.rb', line 1066 def [](index, length = UNDEFINED) return internal_vector[index] if length.equal?(UNDEFINED) && !index.is_a?(Range) slice(index, length) 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.
1077 1078 1079 1080 1081 1082 1083 |
# File 'lib/farce/abstract/vector.rb', line 1077 def []=(index, value, replacement = UNDEFINED) if replacement.equal?(UNDEFINED) && !index.is_a?(Range) internal_vector[index] = value else assign_vector_slice(index, value, replacement) end end |
#append(*values, timeout: nil) ⇒ self, false
Append values using the same options as #push.
1142 |
# File 'lib/farce/abstract/vector.rb', line 1142 def append(...) = push(...) |
#as_extended_json(**options) ⇒ Array
33 |
# File 'lib/farce/integrations/bson.rb', line 33 def as_extended_json(**) = to_a.as_extended_json(**) |
#as_json(options = nil) ⇒ Array
This methods is only available if ActiveSupport has been loaded.
Convert a snapshot to ActiveSupport's explicit JSON representation.
175 |
# File 'lib/farce/integrations/active_support/vector.rb', line 175 def as_json( = nil) = to_a.as_json() |
#assoc(key) ⇒ Array, ...
Find the first pair whose first value equals key.
125 |
# File 'lib/farce/abstract/vector.rb', line 125 def assoc(key) = find_pair(key, 0) |
#at(index) ⇒ BasicObject, ...
Read an index without waiting for atomic-update access, or return a slice snapshot.
133 |
# File 'lib/farce/abstract/vector.rb', line 133 def at(index) = self[index] |
#bsearch {|value| ... } ⇒ BasicObject, ...
Binary-search the live entries and return the matching value. The entries must remain sorted. Concurrent writes can change the result.
753 754 755 756 757 758 759 760 761 762 763 764 |
# File 'lib/farce/abstract/vector.rb', line 753 def bsearch return enum_for(__method__) { size } unless block_given? candidate = nil index = (0...size).bsearch do |position| value = self[position] result = yield(value) candidate = value if result.equal?(true) || (result.is_a?(Numeric) && result.zero?) result end candidate if index end |
#bsearch_index {|value| ... } ⇒ Integer, ...
Binary-search the live entries and return the matching index. The entries must remain sorted. Concurrent writes can change the result.
773 774 775 776 777 |
# File 'lib/farce/abstract/vector.rb', line 773 def bsearch_index return enum_for(__method__) { size } unless block_given? (0...size).bsearch { yield self[it] } end |
#bson_type ⇒ String
This method is only available if BSON has been loaded.
Identify this value as a BSON array when embedded in a document or array.
21 |
# File 'lib/farce/integrations/bson.rb', line 21 def bson_type = ::BSON::Array::BSON_TYPE |
#chunk {|value| ... } ⇒ Enumerator
Group adjacent entries by a block-generated key. Group contents are Vectors.
972 973 974 975 976 977 978 979 980 981 |
# File 'lib/farce/abstract/vector.rb', line 972 def chunk(&block) return enum_for(__method__) { size } unless block Enumerator.new do |yielder| snapshot = internal_vector.snapshot snapshot.chunk { block.call(logical_value(it)) }.each do |key, group| yielder.yield(key, build_derived_vector(group)) end end end |
#chunk_while {|left, right| ... } ⇒ Enumerator
Group adjacent entries while the block accepts each pair.
989 990 991 992 993 994 995 996 997 |
# File 'lib/farce/abstract/vector.rb', line 989 def chunk_while(&block) raise ArgumentError, "no block given" unless block Enumerator.new do |yielder| snapshot = internal_vector.snapshot snapshot.chunk_while { |left, right| block.call(logical_value(left), logical_value(right)) } .each { yielder << build_derived_vector(it) } end end |
#clear ⇒ self
Remove all slots.
1363 1364 1365 1366 |
# File 'lib/farce/abstract/vector.rb', line 1363 def clear internal_vector.clear self end |
#combination(count) {|tuple| ... } ⇒ self, Enumerator
Visit combinations of entries in a snapshot.
561 |
# File 'lib/farce/abstract/vector.rb', line 561 def combination(count, &block) = vector_combinations(__method__, [count], block) |
#compact ⇒ Vector
Remove nil values.
591 |
# File 'lib/farce/abstract/vector.rb', line 591 def compact = build_derived_vector(internal_vector.each.compact) |
#compact! ⇒ self?
Remove nil entries atomically.
429 430 431 432 |
# File 'lib/farce/abstract/vector.rb', line 429 def compact! changed = mutate_vector(&:compact!) self if changed end |
#compact_blank ⇒ Vector
This methods is only available if ActiveSupport has been loaded.
Returns Entries for which blank? is false, excluding nil and false.
76 |
# File 'lib/farce/integrations/active_support/vector.rb', line 76 def compact_blank = reject(&:blank?) |
#compare_and_set(index, expected, replacement, timeout: 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.
1261 1262 1263 |
# File 'lib/farce/abstract/vector.rb', line 1261 def compare_and_set(index, expected, replacement, timeout: nil) internal_vector.compare_and_set(index, expected, replacement, timeout:) end |
#compare_by_identity? ⇒ Boolean
Returns Whether values are compared by identity.
1356 |
# File 'lib/farce/abstract/vector.rb', line 1356 def compare_by_identity? = internal_vector.compare_by_identity? |
#concat(*sources) ⇒ self
Append snapshots of one or more sequences and return this vector. Each append is synchronized separately. Other writers may interleave. Values use the vector's default transfer mode. Self-concatenation reuses existing storage and captures the original contents only once.
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 |
# File 'lib/farce/abstract/vector.rb', line 1118 def concat(*sources) Internal::Freeze.check(self) own_snapshot = internal_vector.snapshot if sources.any? { it.equal?(self) } snapshots = sources.map do |source| if source.equal?(self) own_snapshot else reusable_operand_snapshot(source) || vector_operand(source).map { derived_storage(it) } end end snapshots.each { |values| values.each { internal_vector.push(it) } } self end |
#deconstruct ⇒ Array<BasicObject>
Return a new Array containing a logical snapshot of the values.
65 |
# File 'lib/farce/abstract/vector.rb', line 65 def deconstruct = to_a |
#deep_dup ⇒ Vector
This methods is only available if ActiveSupport has been loaded.
Copy entries using ActiveSupport's deep-copy rules and the Vector's storage rules. Strict Vectors reject deep copies that are not shareable.
72 |
# File 'lib/farce/integrations/active_support/vector.rb', line 72 def deep_dup = map(&:deep_dup) |
#delete(value) {|value| ... } ⇒ BasicObject?
Remove all matching values using the configured comparison mode. Other writers wait until the comparison finishes. Reads can observe the original values. Comparison callbacks must not write to this vector.
75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/farce/abstract/vector.rb', line 75 def delete(value) expected = deletion_comparison(value) removed = UNDEFINED mutate_vector do |values| values.delete_if do |stored| next false unless deletion_match?(stored, expected) removed = stored true end end return logical_value(removed) unless removed.equal?(UNDEFINED) yield(value) if block_given? end |
#delete_at(index) ⇒ BasicObject?
Remove the entry at an index and shift later entries left atomically.
1186 |
# File 'lib/farce/abstract/vector.rb', line 1186 def delete_at(index) = logical_value(mutate_vector { it.delete_at(index) }) |
#delete_if {|value| ... } ⇒ self, Enumerator
Atomically remove entries for which the block returns a truthy value. The block runs without a collection lock. Other writers wait for update access. The block must not write to this vector. Reads can observe the original values. If the block raises, no entries are removed.
97 98 99 100 101 |
# File 'lib/farce/abstract/vector.rb', line 97 def delete_if return enum_for(__method__) { size } unless block_given? mutate_vector { |values| values.delete_if { yield logical_value(it) } } self end |
#difference(*others) ⇒ Vector
Remove values present in any supplied sequence.
729 |
# File 'lib/farce/abstract/vector.rb', line 729 def difference(*others) = derive_array_operation(:difference, *others) |
#dig(index, *identifiers) ⇒ BasicObject?
Recursively retrieve a nested value.
114 115 116 117 118 119 120 |
# File 'lib/farce/abstract/vector.rb', line 114 def dig(index, *identifiers) value = at(index) return value if identifiers.empty? return if value.nil? raise TypeError, "#{value.class} does not have #dig method" unless value.respond_to?(:dig) value.dig(*identifiers) end |
#drop(count) ⇒ Vector
Return all entries after count entries.
652 |
# File 'lib/farce/abstract/vector.rb', line 652 def drop(count) = build_derived_vector(internal_vector.each.drop(count)) |
#drop_while {|value| ... } ⇒ Vector, Enumerator
Drop entries before the first rejected value.
669 670 671 672 |
# File 'lib/farce/abstract/vector.rb', line 669 def drop_while return enum_for(__method__) { size } unless block_given? build_derived_vector(internal_vector.each.drop_while { yield logical_value(it) }) end |
#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.
24 25 26 27 28 29 |
# File 'lib/farce/abstract/vector.rb', line 24 def each return enum_for(__method__) { size } unless block_given? internal_vector.each { yield logical_value(it) } self end |
#each_cons(count) {|window| ... } ⇒ self, Enumerator
Yield same-kind overlapping windows from live iteration.
958 959 960 961 962 963 964 965 |
# File 'lib/farce/abstract/vector.rb', line 958 def each_cons(count) count = convert_vector_count(count) raise ArgumentError, "invalid size" unless count.positive? return enum_for(__method__, count) { [size - count + 1, 0].max } unless block_given? internal_vector.each.each_cons(count) { yield build_derived_vector(it) } self end |
#each_index {|index| ... } ⇒ self, Enumerator
Iterate over indexes up to the length when enumeration starts.
36 37 38 39 40 41 |
# File 'lib/farce/abstract/vector.rb', line 36 def each_index(&) return enum_for(__method__) { size } unless block_given? size.times(&) self end |
#each_slice(count) {|window| ... } ⇒ self, Enumerator
Yield same-kind windows from live iteration.
943 944 945 946 947 948 949 950 |
# File 'lib/farce/abstract/vector.rb', line 943 def each_slice(count) count = convert_vector_count(count) raise ArgumentError, "invalid slice size" unless count.positive? return enum_for(__method__, count) { (size + count - 1) / count } unless block_given? internal_vector.each.each_slice(count) { yield build_derived_vector(it) } self end |
#entries ⇒ Vector
Materialize enumeration as a Vector rather than an Array.
1060 |
# File 'lib/farce/abstract/vector.rb', line 1060 def entries = build_derived_vector(internal_vector.snapshot) |
#excluding(*elements) ⇒ Vector Also known as: without
This methods is only available if ActiveSupport has been loaded.
Exclude entries using Array's hash-based difference semantics.
37 |
# File 'lib/farce/integrations/active_support/vector.rb', line 37 def excluding(*elements) = self - elements.flatten(1) |
#fetch(index, *fallback) {|index| ... } ⇒ BasicObject
Fetch a value by index, with Array-compatible fallback behavior.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/farce/abstract/vector.rb', line 143 def fetch(index, *fallback) original_index = index index = convert_vector_index(index) if fallback.length > 1 raise ArgumentError, "wrong number of arguments (given #{fallback.length + 1}, expected 1..2)" end warn("block supersedes default value argument") if !fallback.empty? && block_given? return logical_value(internal_vector.fetch(index)) if fallback.empty? && !block_given? stored = internal_vector.fetch(index) do return yield(original_index) if block_given? return fallback.first end logical_value(stored) end |
#fetch_values(*indexes) {|index| ... } ⇒ Vector
Fetch several values. Missing indexes are passed to the block.
170 171 172 173 174 175 176 177 |
# File 'lib/farce/abstract/vector.rb', line 170 def fetch_values(*indexes) values = if block_given? indexes.map { |index| internal_vector.fetch(index) { derived_storage(yield(index)) } } else indexes.map { internal_vector.fetch(it) } end build_derived_vector(values) end |
#fifth ⇒ BasicObject?
This methods is only available if ActiveSupport has been loaded.
Returns The fifth entry, or nil if absent.
54 |
# File 'lib/farce/integrations/active_support/vector.rb', line 54 def fifth = self[4] |
#fill(value, start = 0, length = size) ⇒ self #fill(start = 0, length = size) {|index| ... } ⇒ self
Fill all or part of the vector atomically, growing it when necessary. The block must not write to this vector.
1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 |
# File 'lib/farce/abstract/vector.rb', line 1219 def fill(*arguments) mutate_vector do |values| if block_given? values.fill(*arguments) { derived_storage(yield(it)) } else raise ArgumentError, "wrong number of arguments (given 0, expected 1..3)" if arguments.empty? values.fill(derived_storage(arguments.first), *arguments.drop(1)) end end self end |
#filter_map {|value| ... } ⇒ Vector, Enumerator
Transform accepted values into a Vector.
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/farce/abstract/vector.rb', line 334 def filter_map return enum_for(__method__) { size } unless block_given? snapshot = internal_vector.snapshot logical = [] values = [] snapshot.each do |stored| value = logical_value(stored) logical << value mapped = yield(value) values << mapped if mapped end build_derived_from_logical(values, snapshot, logical) end |
#first(count = UNDEFINED) ⇒ BasicObject, ...
Return one value, or a Vector when a count is supplied.
188 189 190 191 192 193 |
# File 'lib/farce/abstract/vector.rb', line 188 def first(count = UNDEFINED) return self[0] if count.equal?(UNDEFINED) snapshot = internal_vector.snapshot build_derived_vector(snapshot.first(count)) end |
#flat_map {|value| ... } ⇒ Vector, Enumerator Also known as: collect_concat
Transform and flatten one Array or Vector level.
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'lib/farce/abstract/vector.rb', line 356 def flat_map return enum_for(__method__) { size } unless block_given? snapshot = internal_vector.snapshot logical = [] values = [] snapshot.each do |stored| value = logical_value(stored) logical << value mapped = yield(value) converted = mapped.is_a?(Vector) ? mapped.to_a : Array.try_convert(mapped) values.concat(converted || [mapped]) end build_derived_from_logical(values, snapshot, logical) end |
#flatten(level = -1)) ⇒ Vector
Expand nested Arrays and Vectors into a new Vector.
502 503 504 505 506 507 508 |
# File 'lib/farce/abstract/vector.rb', line 502 def flatten(level = -1) snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } retained = retained_storage_index(snapshot, logical) flattened = flatten_vector_values(logical, level, retained) build_derived_vector(sequence_storage(flattened, retained)) end |
#flatten!(level = -1)) ⇒ self?
Expand nested Arrays and Vectors atomically.
514 515 516 517 518 519 520 521 522 523 |
# File 'lib/farce/abstract/vector.rb', line 514 def flatten!(level = -1) changed = mutate_vector do |values| logical = values.map { logical_value(it) } retained = retained_storage_index(values, logical) flattened = flatten_vector_values(logical, level, retained) next if flattened.equal?(logical) values.replace(sequence_storage(flattened, retained)) end self if changed end |
#forty_two ⇒ BasicObject?
This methods is only available if ActiveSupport has been loaded.
Returns The forty-second entry, or nil if absent.
58 |
# File 'lib/farce/integrations/active_support/vector.rb', line 58 def forty_two = self[41] |
#fourth ⇒ BasicObject?
This methods is only available if ActiveSupport has been loaded.
Returns The fourth entry, or nil if absent.
50 |
# File 'lib/farce/integrations/active_support/vector.rb', line 50 def fourth = self[3] |
#from(position) ⇒ Vector
This methods is only available if ActiveSupport has been loaded.
Return entries starting at position from one snapshot.
15 16 17 18 |
# File 'lib/farce/integrations/active_support/vector.rb', line 15 def from(position) snapshot = internal_vector.snapshot build_derived_vector(snapshot.from(position)) end |
#get(index, timeout: nil) ⇒ BasicObject?
Read an index after acquiring atomic-update access.
1089 |
# File 'lib/farce/abstract/vector.rb', line 1089 def get(index, timeout: nil) = internal_vector.get(index, timeout:) |
#grep(pattern) {|value| ... } ⇒ Vector
Select values matched by pattern, optionally transforming them.
792 793 794 795 796 797 |
# File 'lib/farce/abstract/vector.rb', line 792 def grep(pattern, &) snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } result = block_given? ? logical.grep(pattern, &) : logical.grep(pattern) build_derived_from_logical(result, snapshot, logical) end |
#grep_v(pattern) {|value| ... } ⇒ Vector
Select values not matched by pattern, optionally transforming them.
805 806 807 808 809 810 |
# File 'lib/farce/abstract/vector.rb', line 805 def grep_v(pattern, &) snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } result = block_given? ? logical.grep_v(pattern, &) : logical.grep_v(pattern) build_derived_from_logical(result, snapshot, logical) end |
#group_by {|value| ... } ⇒ Hash{BasicObject => Vector}, Enumerator
Group live entries into same-kind Vectors.
829 830 831 832 833 834 |
# File 'lib/farce/abstract/vector.rb', line 829 def group_by return enum_for(__method__) { size } unless block_given? internal_vector.each.group_by { yield logical_value(it) } .transform_values { build_derived_vector(it) } end |
#in_groups(number, fill_with = nil) {|group| ... } ⇒ Vector
This methods is only available if ActiveSupport has been loaded.
Divide a snapshot into a requested number of Vector groups.
133 134 135 136 137 138 |
# File 'lib/farce/integrations/active_support/vector.rb', line 133 def in_groups(number, fill_with = nil) groups = active_support_groups(:in_groups, number, fill_with) result = build_derived_values(groups.map { build_derived_vector(it) }) result.each { yield it } if block_given? result end |
#in_groups_of(number, fill_with = nil) {|group| ... } ⇒ Vector, self
This methods is only available if ActiveSupport has been loaded.
Divide a snapshot into Vector groups with a maximum size.
148 149 150 151 152 153 154 |
# File 'lib/farce/integrations/active_support/vector.rb', line 148 def in_groups_of(number, fill_with = nil) padding = fill_with != false groups = active_support_groups(:in_groups_of, number, fill_with) return build_derived_values(groups.map { build_derived_vector(it) }) unless block_given? groups.each { yield build_derived_vector(it) } padding ? build_derived_vector(groups.flatten(1)) : self end |
#in_order_of(key, series, filter: true) ⇒ Vector
This methods is only available if ActiveSupport has been loaded.
Order a snapshot by the keys in series, preserving retained entries.
106 107 108 109 110 111 |
# File 'lib/farce/integrations/active_support/vector.rb', line 106 def in_order_of(key, series, filter: true) snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } result = logical.in_order_of(key, series, filter:) build_derived_from_logical(result, snapshot, logical) end |
#include?(value) ⇒ Boolean Also known as: member?
Return whether a live entry equals value.
226 227 228 229 |
# File 'lib/farce/abstract/vector.rb', line 226 def include?(value) each { return true if array_value_equal?(it, value) } false end |
#including(*elements) ⇒ Vector
This methods is only available if ActiveSupport has been loaded.
Append entries to a new Vector, flattening argument Arrays by one level. New entries follow the receiver's storage rules and transfer mode.
31 |
# File 'lib/farce/integrations/active_support/vector.rb', line 31 def including(*elements) = self + elements.flatten(1) |
#index(value = UNDEFINED) {|entry| ... } ⇒ Integer, ... Also known as: find_index
Return the first matching index.
238 239 240 241 242 243 244 245 246 |
# File 'lib/farce/abstract/vector.rb', line 238 def index(value = UNDEFINED) return enum_for(__method__) { size } if value.equal?(UNDEFINED) && !block_given? # rubocop:disable Lint/ToEnumArguments warn("given block not used") if !value.equal?(UNDEFINED) && block_given? each_with_index do |entry, index| return index if value.equal?(UNDEFINED) ? yield(entry) : array_value_equal?(entry, value) end nil end |
#inquiry ⇒ ActiveSupport::ArrayInquirer
This methods is only available if ActiveSupport has been loaded.
Create ActiveSupport's specialized query wrapper from a logical snapshot.
212 |
# File 'lib/farce/integrations/active_support/vector.rb', line 212 def inquiry = to_a.inquiry |
#insert(index, *values) ⇒ self
Insert values before an index atomically. Negative indexes count from the end.
1178 1179 1180 1181 |
# File 'lib/farce/abstract/vector.rb', line 1178 def insert(index, *values) mutate_vector { it.insert(index, *values.map { derived_storage(it) }) } self end |
#intersect?(other) ⇒ Boolean
Return whether another sequence shares any value.
744 |
# File 'lib/farce/abstract/vector.rb', line 744 def intersect?(other) = to_a.intersect?(vector_operand(other)) |
#intersection(*others) ⇒ Vector
Intersect with every supplied sequence.
734 |
# File 'lib/farce/abstract/vector.rb', line 734 def intersection(*others) = derive_array_operation(:intersection, *others) |
#keep_if {|value| ... } ⇒ self, Enumerator
Keep entries accepted by the block, publishing the result atomically. The block must not write to this vector.
396 397 398 399 400 |
# File 'lib/farce/abstract/vector.rb', line 396 def keep_if return enum_for(__method__) { size } unless block_given? mutate_vector { |values| values.keep_if { yield logical_value(it) } } self end |
#last(count = UNDEFINED) ⇒ BasicObject, ...
Return one value, or a Vector when a count is supplied.
198 199 200 201 202 203 |
# File 'lib/farce/abstract/vector.rb', line 198 def last(count = UNDEFINED) return self[-1] if count.equal?(UNDEFINED) snapshot = internal_vector.snapshot build_derived_vector(snapshot.last(count)) end |
#map {|value| ... } ⇒ Vector, Enumerator Also known as: collect
Transform a snapshot into a Vector.
291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/farce/abstract/vector.rb', line 291 def map return enum_for(__method__) { size } unless block_given? snapshot = internal_vector.snapshot logical = [] mapped = snapshot.map do |stored| value = logical_value(stored) logical << value yield value end build_derived_from_logical(mapped, snapshot, logical) end |
#map! {|value| ... } ⇒ self, Enumerator Also known as: collect!
Replace each entry with the block result, publishing all replacements together. The block must not write to this vector. Failure leaves the stored entries unchanged.
379 380 381 382 383 384 385 386 387 |
# File 'lib/farce/abstract/vector.rb', line 379 def map! return enum_for(__method__) { size } unless block_given? mutate_vector do |values| logical = values.map { logical_value(it) } mapped = logical.map { yield it } values.replace(storage_from_logical(mapped, values, logical)) end self end |
#max(count = UNDEFINED) {|left, right| ... } ⇒ BasicObject, ...
Return one maximum, or a Vector when count is supplied.
872 873 874 875 876 877 878 879 880 |
# File 'lib/farce/abstract/vector.rb', line 872 def max(count = UNDEFINED, &) count = normalized_extreme_count(count) return super(&) if count.nil? return build_derived_vector([]) if count.zero? snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } build_derived_from_logical(logical.max(count, &), snapshot, logical) end |
#max_by(count = UNDEFINED) {|value| ... } ⇒ BasicObject, ...
Return one block maximum, or a Vector when count is supplied.
910 911 912 913 914 915 916 917 918 919 920 921 922 |
# File 'lib/farce/abstract/vector.rb', line 910 def max_by(count = UNDEFINED) count = normalized_extreme_count(count) unless block_given? return enum_for(__method__) { size } if count.nil? # rubocop:disable Lint/ToEnumArguments return enum_for(__method__, count) { size } end return super() { yield it } if count.nil? return build_derived_vector([]) if count.zero? snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } build_derived_from_logical(logical.max_by(count) { yield it }, snapshot, logical) end |
#maximum(key) ⇒ BasicObject?
This methods is only available if ActiveSupport has been loaded.
Find the maximum extracted value without storing intermediate results in a Vector.
123 |
# File 'lib/farce/integrations/active_support/vector.rb', line 123 def maximum(key) = to_a.maximum(key) |
#min(count = UNDEFINED) {|left, right| ... } ⇒ BasicObject, ...
Return one minimum, or a Vector when count is supplied.
855 856 857 858 859 860 861 862 863 |
# File 'lib/farce/abstract/vector.rb', line 855 def min(count = UNDEFINED, &) count = normalized_extreme_count(count) return super(&) if count.nil? return build_derived_vector([]) if count.zero? snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } build_derived_from_logical(logical.min(count, &), snapshot, logical) end |
#min_by(count = UNDEFINED) {|value| ... } ⇒ BasicObject, ...
Return one block minimum, or a Vector when count is supplied.
889 890 891 892 893 894 895 896 897 898 899 900 901 |
# File 'lib/farce/abstract/vector.rb', line 889 def min_by(count = UNDEFINED) count = normalized_extreme_count(count) unless block_given? return enum_for(__method__) { size } if count.nil? # rubocop:disable Lint/ToEnumArguments return enum_for(__method__, count) { size } end return super() { yield it } if count.nil? return build_derived_vector([]) if count.zero? snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } build_derived_from_logical(logical.min_by(count) { yield it }, snapshot, logical) end |
#minimum(key) ⇒ BasicObject?
This methods is only available if ActiveSupport has been loaded.
Find the minimum extracted value without storing intermediate results in a Vector.
117 |
# File 'lib/farce/integrations/active_support/vector.rb', line 117 def minimum(key) = to_a.minimum(key) |
#minmax {|left, right| ... } ⇒ Vector
Return minimum and maximum in a Vector.
842 843 844 845 846 |
# File 'lib/farce/abstract/vector.rb', line 842 def minmax(&) snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } build_derived_from_logical(logical.minmax(&), snapshot, logical) end |
#minmax_by {|value| ... } ⇒ Vector, Enumerator
Return the block minimum and maximum in a Vector.
929 930 931 932 933 934 935 |
# File 'lib/farce/abstract/vector.rb', line 929 def minmax_by return enum_for(__method__) { size } unless block_given? snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } build_derived_from_logical(logical.minmax_by { yield it }, snapshot, logical) end |
#pack(format, buffer: nil) ⇒ String
Pack a logical snapshot according to format.
784 |
# File 'lib/farce/abstract/vector.rb', line 784 def pack(format, **) = to_a.pack(format, **) |
#partition {|value| ... } ⇒ Vector, Enumerator
Split live entries into accepted and rejected Vectors, wrapped in a Vector.
817 818 819 820 821 822 |
# File 'lib/farce/abstract/vector.rb', line 817 def partition return enum_for(__method__) { size } unless block_given? accepted, rejected = internal_vector.each.partition { yield logical_value(it) } build_derived_values([build_derived_vector(accepted), build_derived_vector(rejected)]) end |
#permutation(count = UNDEFINED) {|tuple| ... } ⇒ self, Enumerator
Visit permutations of entries in a snapshot.
577 578 579 |
# File 'lib/farce/abstract/vector.rb', line 577 def permutation(count = UNDEFINED, &block) vector_combinations(__method__, count.equal?(UNDEFINED) ? [] : [count], block) end |
#pick(*keys) ⇒ BasicObject, ...
This methods is only available if ActiveSupport has been loaded.
Extract keys from the first entry in a snapshot.
92 93 94 95 96 97 98 |
# File 'lib/farce/integrations/active_support/vector.rb', line 92 def pick(*keys) snapshot = internal_vector.snapshot return if snapshot.empty? entry = logical_value(snapshot.first) return entry[keys.first] unless keys.length > 1 build_derived_values(keys.map { |key| entry[key] }) end |
#pluck(*keys) ⇒ Vector
This methods is only available if ActiveSupport has been loaded.
Extract keys from each entry in a snapshot. Extracted values follow the receiver's storage rules and transfer mode.
83 84 85 86 |
# File 'lib/farce/integrations/active_support/vector.rb', line 83 def pluck(*keys) return map { |entry| entry[keys.first] } unless keys.length > 1 map { |entry| build_derived_values(keys.map { |key| entry[key] }) } end |
#pop(count = UNDEFINED, timeout: nil) ⇒ 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.
1149 1150 1151 1152 1153 1154 1155 |
# File 'lib/farce/abstract/vector.rb', line 1149 def pop(count = UNDEFINED, timeout: nil) if count.equal?(UNDEFINED) backend = internal_vector return timeout.nil? ? backend.pop : backend.pop(timeout:) end pop_values(count, timeout:) end |
#product(*others) {|tuple| ... } ⇒ Vector, self
Produce tuples containing one entry from each sequence.
541 542 543 544 545 546 547 548 549 550 551 552 553 |
# File 'lib/farce/abstract/vector.rb', line 541 def product(*others) snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } retained = retained_storage_index(snapshot, logical) operands = others.map { sequence_operand(it, retained) } if block_given? logical.product(*operands) { yield build_derived_vector(sequence_storage(it, retained)) } self else tuples = logical.product(*operands).map { build_derived_vector(sequence_storage(it, retained)) } build_derived_values(tuples) end end |
#push(value = UNDEFINED, *rest, timeout: nil) ⇒ self, false
Append values atomically. Calls with one value use the scalar backend path.
1103 1104 1105 1106 1107 1108 1109 1110 |
# File 'lib/farce/abstract/vector.rb', line 1103 def push(value = UNDEFINED, *rest, timeout: nil) if rest.empty? && !value.equal?(UNDEFINED) backend = internal_vector completed = timeout.nil? ? backend.push(value) : backend.push(value, timeout:) return completed ? self : false end push_values(value.equal?(UNDEFINED) ? rest : [value, *rest], timeout:) end |
#rassoc(value) ⇒ Array, ...
Find the first pair whose second value equals value.
130 |
# File 'lib/farce/abstract/vector.rb', line 130 def rassoc(value) = find_pair(value, 1) |
#reject {|value| ... } ⇒ Vector, Enumerator
Remove values accepted by a block.
323 324 325 326 327 |
# File 'lib/farce/abstract/vector.rb', line 323 def reject return enum_for(__method__) { size } unless block_given? build_derived_vector(internal_vector.each.reject { yield logical_value(it) }) end |
#reject! {|value| ... } ⇒ self, ...
Remove entries accepted by the block, returning nil if no entry was removed. The block must not write to this vector.
421 422 423 424 425 |
# File 'lib/farce/abstract/vector.rb', line 421 def reject! return enum_for(__method__) { size } unless block_given? changed = mutate_vector { |values| values.reject! { yield logical_value(it) } } self if changed end |
#repeated_combination(count) {|tuple| ... } ⇒ self, Enumerator
Visit combinations that may reuse entries in a snapshot.
569 |
# File 'lib/farce/abstract/vector.rb', line 569 def repeated_combination(count, &block) = vector_combinations(__method__, [count], block) |
#repeated_permutation(count) {|tuple| ... } ⇒ self, Enumerator
Visit permutations that may reuse entries in a snapshot.
587 |
# File 'lib/farce/abstract/vector.rb', line 587 def repeated_permutation(count, &block) = vector_combinations(__method__, [count], block) |
#replace(source) ⇒ self
Replace all entries atomically with the contents of another sequence.
1201 1202 1203 1204 |
# File 'lib/farce/abstract/vector.rb', line 1201 def replace(source) mutate_vector { |values| values.replace(source.equal?(self) ? values : operand_storage(source)) } self end |
#reverse ⇒ Vector
Return a reversed snapshot.
611 |
# File 'lib/farce/abstract/vector.rb', line 611 def reverse = build_derived_vector(internal_vector.snapshot.reverse) |
#reverse! ⇒ self
Reverse all entries atomically.
449 450 451 452 |
# File 'lib/farce/abstract/vector.rb', line 449 def reverse! mutate_vector(&:reverse!) self end |
#reverse_each {|value| ... } ⇒ self, Enumerator
Iterate over live entries from the last index when enumeration starts. Replacements and removals can affect entries not yet visited. The block runs without a collection lock.
49 50 51 52 53 54 |
# File 'lib/farce/abstract/vector.rb', line 49 def reverse_each return enum_for(__method__) { size } unless block_given? internal_vector.reverse_each { yield logical_value(it) } self end |
#rfind(if_none = nil) {|value| ... } ⇒ BasicObject, ...
Find a value by searching from the end.
279 280 281 282 283 284 |
# File 'lib/farce/abstract/vector.rb', line 279 def rfind(if_none = nil) return enum_for(__method__, if_none) { size } unless block_given? reverse_each { return it if yield(it) } if_none&.call end |
#rindex(value = UNDEFINED) {|entry| ... } ⇒ Integer, ...
Return the last matching index.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/farce/abstract/vector.rb', line 255 def rindex(value = UNDEFINED) return enum_for(__method__) { size } if value.equal?(UNDEFINED) && !block_given? # rubocop:disable Lint/ToEnumArguments warn("given block not used") if !value.equal?(UNDEFINED) && block_given? backend = internal_vector index = backend.size while index.positive? index -= 1 found = true stored = backend.fetch(index) { found = false } next unless found entry = logical_value(stored) return index if value.equal?(UNDEFINED) ? yield(entry) : array_value_equal?(entry, value) end nil end |
#rotate(count = 1) ⇒ Vector
Return a rotated snapshot.
616 |
# File 'lib/farce/abstract/vector.rb', line 616 def rotate(count = 1) = build_derived_vector(internal_vector.snapshot.rotate(count)) |
#rotate!(count = 1) ⇒ self
Rotate all entries atomically.
457 458 459 460 |
# File 'lib/farce/abstract/vector.rb', line 457 def rotate!(count = 1) mutate_vector { it.rotate!(count) } self end |
#sample(count = UNDEFINED, random: Random) ⇒ BasicObject, ...
Return one sample, or a Vector when count is supplied.
683 684 685 686 687 |
# File 'lib/farce/abstract/vector.rb', line 683 def sample(count = UNDEFINED, random: Random) snapshot = internal_vector.snapshot return logical_value(snapshot.sample(random:)) if count.equal?(UNDEFINED) build_derived_vector(snapshot.sample(count, random:)) end |
#second ⇒ BasicObject?
This methods is only available if ActiveSupport has been loaded.
Returns The second entry, or nil if absent.
42 |
# File 'lib/farce/integrations/active_support/vector.rb', line 42 def second = self[1] |
#second_to_last ⇒ BasicObject?
This methods is only available if ActiveSupport has been loaded.
Returns The second entry from the end, or nil if absent.
66 |
# File 'lib/farce/integrations/active_support/vector.rb', line 66 def second_to_last = self[-2] |
#select {|value| ... } ⇒ Vector, Enumerator Also known as: filter, find_all
Keep values accepted by a block.
310 311 312 313 314 |
# File 'lib/farce/abstract/vector.rb', line 310 def select return enum_for(__method__) { size } unless block_given? build_derived_vector(internal_vector.each.select { yield logical_value(it) }) end |
#select! {|value| ... } ⇒ self, ... Also known as: filter!
Keep entries accepted by the block, returning nil if no entry was removed. The block must not write to this vector.
408 409 410 411 412 |
# File 'lib/farce/abstract/vector.rb', line 408 def select! return enum_for(__method__) { size } unless block_given? changed = mutate_vector { |values| values.select! { yield logical_value(it) } } self if changed end |
#shareable_values? ⇒ Boolean
Returns Whether stored values must be Ractor-shareable.
1359 |
# File 'lib/farce/abstract/vector.rb', line 1359 def shareable_values? = false |
#shift(count = UNDEFINED) ⇒ BasicObject, ...
Remove the first entry, or the first count entries, atomically.
1160 1161 1162 1163 |
# File 'lib/farce/abstract/vector.rb', line 1160 def shift(count = UNDEFINED) result = mutate_vector { count.equal?(UNDEFINED) ? it.shift : it.shift(count) } count.equal?(UNDEFINED) ? logical_value(result) : build_derived_vector(result) end |
#shuffle(random: Random) ⇒ Vector
Return a shuffled snapshot.
677 |
# File 'lib/farce/abstract/vector.rb', line 677 def shuffle(random: Random) = build_derived_vector(internal_vector.snapshot.shuffle(random:)) |
#shuffle!(random: Random) ⇒ self
Shuffle all entries atomically without transferring retained values again.
465 466 467 468 |
# File 'lib/farce/abstract/vector.rb', line 465 def shuffle!(random: Random) mutate_vector { it.shuffle!(random:) } self end |
#size ⇒ Integer
Returns The number of slots, including nil slots.
1353 |
# File 'lib/farce/abstract/vector.rb', line 1353 def size = internal_vector.size |
#slice(index, length = UNDEFINED) ⇒ BasicObject, ...
Return an element or subsequence from a snapshot. Range and start-length results are Vectors.
210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/farce/abstract/vector.rb', line 210 def slice(index, length = UNDEFINED) snapshot = internal_vector.snapshot if length.equal?(UNDEFINED) result = snapshot.slice(index) return logical_value(result) unless index.is_a?(Range) else result = snapshot.slice(index, length) end result && build_derived_vector(result) end |
#slice!(index, length = UNDEFINED) ⇒ BasicObject, ...
Remove a range of entries atomically.
1192 1193 1194 1195 1196 |
# File 'lib/farce/abstract/vector.rb', line 1192 def slice!(index, length = UNDEFINED) result = mutate_vector { length.equal?(UNDEFINED) ? it.slice!(index) : it.slice!(index, length) } return if result.nil? length.equal?(UNDEFINED) && !index.is_a?(Range) ? logical_value(result) : build_derived_vector(result) end |
#slice_after(*arguments) {|value| ... } ⇒ Enumerator
Group a snapshot after matching entries.
1015 1016 1017 |
# File 'lib/farce/abstract/vector.rb', line 1015 def slice_after(*arguments, &block) logical_grouping_enumerator(:slice_after, arguments, block) end |
#slice_before(*arguments) {|value| ... } ⇒ Enumerator
Group a snapshot before matching entries.
1005 1006 1007 |
# File 'lib/farce/abstract/vector.rb', line 1005 def slice_before(*arguments, &block) logical_grouping_enumerator(:slice_before, arguments, block) end |
#slice_when {|left, right| ... } ⇒ Enumerator
Group a snapshot between pairs accepted by the block.
1025 1026 1027 1028 |
# File 'lib/farce/abstract/vector.rb', line 1025 def slice_when(&block) raise ArgumentError, "no block given" unless block logical_grouping_enumerator(:slice_when, [], block) end |
#sort {|left, right| ... } ⇒ Vector
Return a sorted snapshot.
624 625 626 627 628 629 |
# File 'lib/farce/abstract/vector.rb', line 624 def sort(&block) snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } sorted = block ? logical.sort(&block) : logical.sort build_derived_from_logical(sorted, snapshot, logical) end |
#sort! {|left, right| ... } ⇒ self
Sort all entries atomically using logical values. The comparison block must not write to this vector.
477 478 479 480 481 482 483 484 |
# File 'lib/farce/abstract/vector.rb', line 477 def sort!(&block) mutate_vector do |values| logical = values.map { logical_value(it) } sorted = block ? logical.sort(&block) : logical.sort values.replace(storage_from_logical(sorted, values, logical)) end self end |
#sort_by {|value| ... } ⇒ Vector, Enumerator
Sort a snapshot by block results.
636 637 638 639 640 641 642 |
# File 'lib/farce/abstract/vector.rb', line 636 def sort_by return enum_for(__method__) { size } unless block_given? snapshot = internal_vector.snapshot logical = snapshot.map { logical_value(it) } build_derived_from_logical(logical.sort_by { yield it }, snapshot, logical) end |
#sort_by! {|value| ... } ⇒ self, Enumerator
Sort all entries atomically by the block result. The block must not write to this vector.
492 493 494 495 496 |
# File 'lib/farce/abstract/vector.rb', line 492 def sort_by! return enum_for(__method__) { size } unless block_given? mutate_vector { |values| values.sort_by! { yield logical_value(it) } } self end |
#split(value = nil) {|entry| ... } ⇒ Vector
This methods is only available if ActiveSupport has been loaded.
Split a snapshot at matching entries, omitting the separators.
163 164 165 166 167 168 169 |
# File 'lib/farce/integrations/active_support/vector.rb', line 163 def split(value = nil) groups = internal_vector.snapshot.split do |stored| entry = logical_value(stored) block_given? ? yield(entry) : array_value_equal?(entry, value) end build_derived_values(groups.map { build_derived_vector(it) }) end |
#store(index, value, timeout: nil) ⇒ BasicObject, false
Store a value after acquiring atomic-update access.
1096 |
# File 'lib/farce/abstract/vector.rb', line 1096 def store(index, value, timeout: nil) = internal_vector.store(index, value, timeout:) |
#store_if_absent(index, timeout: nil) { ... } ⇒ BasicObject?
Compute and store a value only when the index is absent or contains nil.
1252 |
# File 'lib/farce/abstract/vector.rb', line 1252 def store_if_absent(index, timeout: nil, &) = internal_vector.store_if_absent(index, timeout:, &) |
#swap(index, replacement, timeout: nil) ⇒ BasicObject?
Replace an index and return its previous value, growing the vector if necessary.
1244 |
# File 'lib/farce/abstract/vector.rb', line 1244 def swap(index, replacement, timeout: nil) = internal_vector.swap(index, replacement, timeout:) |
#take(count) ⇒ Vector
Return the first count entries.
647 |
# File 'lib/farce/abstract/vector.rb', line 647 def take(count) = build_derived_vector(internal_vector.each.take(count)) |
#take_while {|value| ... } ⇒ Vector, Enumerator
Return entries before the first rejected value.
659 660 661 662 |
# File 'lib/farce/abstract/vector.rb', line 659 def take_while return enum_for(__method__) { size } unless block_given? build_derived_vector(internal_vector.each.take_while { yield logical_value(it) }) end |
#third ⇒ BasicObject?
This methods is only available if ActiveSupport has been loaded.
Returns The third entry, or nil if absent.
46 |
# File 'lib/farce/integrations/active_support/vector.rb', line 46 def third = self[2] |
#third_to_last ⇒ BasicObject?
This methods is only available if ActiveSupport has been loaded.
Returns The third entry from the end, or nil if absent.
62 |
# File 'lib/farce/integrations/active_support/vector.rb', line 62 def third_to_last = self[-3] |
#to(position) ⇒ Vector
This methods is only available if ActiveSupport has been loaded.
Return entries through position from one snapshot.
24 |
# File 'lib/farce/integrations/active_support/vector.rb', line 24 def to(position) = build_derived_vector(internal_vector.snapshot.to(position)) |
#to_a ⇒ Array<BasicObject>
Return a new Array containing a logical snapshot of the values.
58 |
# File 'lib/farce/abstract/vector.rb', line 58 def to_a = internal_vector.snapshot.map! { logical_value(it) } |
#to_ary ⇒ Array<BasicObject>
Return an Array snapshot for implicit Array conversion, such as [].concat(vector).
62 |
# File 'lib/farce/abstract/vector.rb', line 62 def to_ary = to_a |
#to_bson(buffer = ::BSON::ByteBuffer.new) ⇒ BSON::ByteBuffer
This method is only available if BSON has been loaded.
Serialize a snapshot using BSON's array representation. Nested value wrappers are read before encoding their BSON types and payloads.
16 |
# File 'lib/farce/integrations/bson.rb', line 16 def to_bson(buffer = ::BSON::ByteBuffer.new) = to_bson_normalized_value.to_bson(buffer) |
#to_bson_normalized_value ⇒ Array
This method is only available if BSON has been loaded.
Return a snapshot with nested values normalized by BSON.
26 |
# File 'lib/farce/integrations/bson.rb', line 26 def to_bson_normalized_value = to_a.to_bson_normalized_value |
#to_cbor(*arguments) ⇒ String, ...
19 |
# File 'lib/farce/integrations/cbor.rb', line 19 def to_cbor(...) = to_a.to_cbor(...) |
#to_fs(format = :default) ⇒ String Also known as: to_formatted_s
This methods is only available if ActiveSupport has been loaded.
Format a snapshot, optionally as a database ID list.
196 |
# File 'lib/farce/integrations/active_support/vector.rb', line 196 def to_fs(format = :default) = to_a.to_fs(format) |
#to_h {|value| ... } ⇒ Hash
Convert pair-like entries to a Hash. Vector entries are accepted as pairs.
108 |
# File 'lib/farce/abstract/vector.rb', line 108 def to_h = to_a.to_h { normalize_hash_pair(block_given? ? yield(it) : it) } |
#to_json(*arguments) ⇒ String
This method is only available if a supported JSON library has been loaded.
Serialize a logical snapshot as a JSON Array.
13 |
# File 'lib/farce/integrations/shared/to_json.rb', line 13 def to_json(...) = to_a.to_json(...) |
#to_msgpack(*arguments) ⇒ String, ::MessagePack::Packer
This method is only available if MessagePack has been loaded.
Serialize a snapshot as a MessagePack array.
16 |
# File 'lib/farce/integrations/msgpack.rb', line 16 def to_msgpack(...) = to_a.to_msgpack(...) |
#to_param ⇒ String
This methods is only available if ActiveSupport has been loaded.
Returns The snapshot's URL parameter representation, joined with slashes.
179 |
# File 'lib/farce/integrations/active_support/vector.rb', line 179 def to_param = to_a.to_param |
#to_query(key) ⇒ String
This methods is only available if ActiveSupport has been loaded.
Returns The encoded query string for the snapshot.
184 |
# File 'lib/farce/integrations/active_support/vector.rb', line 184 def to_query(key) = to_a.to_query(key) |
#to_sentence(options = {}) ⇒ String
This methods is only available if ActiveSupport has been loaded.
Format a snapshot as a sentence using ActiveSupport's connectors and locale.
190 |
# File 'lib/farce/integrations/active_support/vector.rb', line 190 def to_sentence( = {}) = to_a.to_sentence() |
#to_xml(options = {}) {|builder| ... } ⇒ String
This methods is only available if ActiveSupport has been loaded.
Serialize a logical snapshot with ActiveSupport's Array XML conversion. Requires ActiveSupport's optional Builder dependency, as Array#to_xml does.
207 |
# File 'lib/farce/integrations/active_support/vector.rb', line 207 def to_xml( = {}, &) = to_a.to_xml(, &) |
#transpose ⇒ Vector
Transpose rows represented by Arrays or Vectors.
528 529 530 531 532 533 |
# File 'lib/farce/abstract/vector.rb', line 528 def transpose retained = {}.compare_by_identity rows = to_a.map { sequence_operand(it, retained) } columns = rows.transpose.map { build_derived_vector(sequence_storage(it, retained)) } build_derived_values(columns) end |
#union(*others) ⇒ Vector
Union with every supplied sequence.
739 |
# File 'lib/farce/abstract/vector.rb', line 739 def union(*others) = derive_array_operation(:union, *others) |
#uniq {|value| ... } ⇒ Vector
Remove duplicate values, retaining the first stored entry.
599 600 601 602 603 604 605 606 607 |
# File 'lib/farce/abstract/vector.rb', line 599 def uniq snapshot = internal_vector.snapshot selected = if block_given? snapshot.uniq { yield logical_value(it) } else snapshot.uniq { logical_value(it) } end build_derived_vector(selected) end |
#uniq! {|value| ... } ⇒ self?
Remove duplicate entries atomically, retaining the first stored entry. The block must not write to this vector.
440 441 442 443 444 445 |
# File 'lib/farce/abstract/vector.rb', line 440 def uniq! changed = mutate_vector do |values| values.uniq! { block_given? ? yield(logical_value(it)) : logical_value(it) } end self if changed end |
#unshift(*values) ⇒ self Also known as: prepend
Prepend values atomically using the vector's default transfer mode.
1168 1169 1170 1171 |
# File 'lib/farce/abstract/vector.rb', line 1168 def unshift(*values) mutate_vector { it.unshift(*values.map { derived_storage(it) }) } self end |
#update(index, timeout: nil) {|value| ... } ⇒ BasicObject?
Atomically replace an index with the block result, growing the vector if necessary.
1272 |
# File 'lib/farce/abstract/vector.rb', line 1272 def update(index, timeout: nil, &) = internal_vector.update(index, timeout:, &) |
#upsert(index, initial, timeout: nil) {|value| ... } ⇒ BasicObject?
Store initial for an absent or nil index, otherwise replace it with the block result.
1282 |
# File 'lib/farce/abstract/vector.rb', line 1282 def upsert(index, initial, timeout: nil, &) = internal_vector.upsert(index, initial, timeout:, &) |
#values_at(*indexes) ⇒ Vector
Select values at indexes and ranges.
183 |
# File 'lib/farce/abstract/vector.rb', line 183 def values_at(...) = build_derived_vector(internal_vector.snapshot.values_at(...)) |
#wait_until(index, timeout: nil) {|value| ... } ⇒ BasicObject?
Wait until a block condition matches the value at an index. Absent indexes are observed as nil. One timeout budget covers all checks and waits. The block is not interrupted.
1293 |
# File 'lib/farce/abstract/vector.rb', line 1293 def wait_until(index, timeout: nil, &) = Internal.wait_until(internal_vector, index, timeout:, &) |
#wait_until_changed(index, expected, timeout: nil) ⇒ BasicObject?
Wait until an index no longer matches expected. Absent indexes are observed as nil.
1339 1340 1341 |
# File 'lib/farce/abstract/vector.rb', line 1339 def wait_until_changed(index, expected, timeout: nil) internal_vector.wait_until_changed(index, expected, timeout:) end |
#wait_until_match(index, object, timeout: nil) ⇒ BasicObject?
Wait until object === value is true.
1330 1331 1332 |
# File 'lib/farce/abstract/vector.rb', line 1330 def wait_until_match(index, object, timeout: nil) wait_until(index, timeout:) { |value| object === value } # rubocop:disable Style/CaseEquality end |
#wait_until_non_nil(index, timeout: nil) ⇒ BasicObject?
Wait until an index contains a non-nil value.
1350 |
# File 'lib/farce/abstract/vector.rb', line 1350 def wait_until_non_nil(index, timeout: nil) = internal_vector.wait_until_non_nil(index, timeout:) |
#wait_until_value(index, object, timeout: nil) ⇒ BasicObject?
Wait until the current value equals an object using the configured comparison mode.
1321 1322 1323 |
# File 'lib/farce/abstract/vector.rb', line 1321 def wait_until_value(index, object, timeout: nil) wait_until(index, timeout:) { |value| compare_by_identity? ? object.equal?(value) : object == value } end |
#wait_while(index, timeout: nil) {|value| ... } ⇒ BasicObject?
Wait while the block returns a truthy value.
1302 1303 1304 1305 |
# File 'lib/farce/abstract/vector.rb', line 1302 def wait_while(index, timeout: nil) raise LocalJumpError, "no block given" unless block_given? wait_until(index, timeout:) { |value| !yield(value) } end |
#wait_while_match(index, object, timeout: nil) ⇒ BasicObject?
Wait while object === value is true.
1312 1313 1314 |
# File 'lib/farce/abstract/vector.rb', line 1312 def wait_while_match(index, object, timeout: nil) wait_while(index, timeout:) { |value| object === value } # rubocop:disable Style/CaseEquality end |
#wait_while_value ⇒ BasicObject?
Wait until an index no longer matches expected. Absent indexes are observed as nil.
1344 |
# File 'lib/farce/abstract/vector.rb', line 1344 def wait_while_value(...) = wait_until_changed(...) |
#zip(*others) {|row| ... } ⇒ Vector?
Zip values into Vector rows. With a block, yield rows and return nil.
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 |
# File 'lib/farce/abstract/vector.rb', line 1036 def zip(*others) snapshot = internal_vector.snapshot operands = others.map do |other| stored = other.equal?(self) ? snapshot : reusable_operand_snapshot(other) stored ? [stored, true] : [zip_operand(other, snapshot.length), false] end build_row = lambda do |stored, index| row = [stored] operands.each do |values, prepared| row << (prepared ? values[index] : derived_storage(values[index])) end build_derived_vector(row) end if block_given? snapshot.each_with_index { |stored, index| yield build_row.call(stored, index) } nil else rows = snapshot.each_with_index.map { |stored, index| build_row.call(stored, index) } build_derived_values(rows) end end |
#|(other) ⇒ Vector
Union with another sequence.
724 |
# File 'lib/farce/abstract/vector.rb', line 724 def |(other) = derive_array_operation(:|, other) |