Class: Familia::UnsortedSet

Inherits:
DataType show all
Includes:
DataType::CollectionBase
Defined in:
lib/familia/data_type/types/unsorted_set.rb

Overview

Familia::UnsortedSet

Instance Attribute Summary collapse

Attributes included from Settings

#current_key_version, #default_expiration, #delim, #encryption_keys, #encryption_personalization, #logical_database, #prefix, #schema_path, #schema_validator, #schemas, #strict_write_order, #suffix, #transaction_mode

Instance Method Summary collapse

Methods included from DataType::CollectionBase

#collection_type?, #each_record

Methods included from Features::Autoloader

autoload_files, included, normalize_to_config_name

Methods included from DataType::Serialization

#deserialize_value, #deserialize_values, #deserialize_values_with_nil, #serialize_value

Methods included from DataType::DatabaseCommands

#current_expiration, #delete!, #echo, #exists?, #expire, #expireat, #persist, #rename, #renamenx, #type

Methods included from DataType::Connection

#dbclient, #dbkey, #uri

Methods included from Connection::Behavior

#connect, #create_dbclient, #multi, #normalize_uri, #pipeline, #pipelined, #transaction, #uri=, #url, #url=

Methods included from Settings

#configure, #default_suffix, #pipelined_mode, #pipelined_mode=

Methods included from Base

add_feature, #as_json, #expired?, #expires?, find_feature, #generate_id, #to_json, #to_s, #ttl, #update_expiration, #uuid

Constructor Details

This class inherits a constructor from Familia::DataType

Instance Attribute Details

#features_enabledObject (readonly) Originally defined in module Features

Returns the value of attribute features_enabled.

#logical_database(val = nil) ⇒ Object Originally defined in module DataType::ClassMethods

#parentObject Originally defined in module DataType::ClassMethods

Returns the value of attribute parent.

#prefixObject Originally defined in module DataType::ClassMethods

Returns the value of attribute prefix.

#suffixObject Originally defined in module DataType::ClassMethods

Returns the value of attribute suffix.

#uri(val = nil) ⇒ Object Originally defined in module DataType::ClassMethods

Returns the value of attribute uri.

Instance Method Details

#<<(v) ⇒ Object



36
37
38
# File 'lib/familia/data_type/types/unsorted_set.rb', line 36

def <<(v)
  add v
end

#add(*values) ⇒ Object Also known as: add_element

Note:

This method executes a Redis SADD immediately, unlike scalar field setters which are deferred until save. If the parent object has unsaved scalar field changes, consider calling save first to avoid split-brain state.



27
28
29
30
31
32
33
# File 'lib/familia/data_type/types/unsorted_set.rb', line 27

def add *values
  warn_if_dirty!
  serialized = values.flatten.compact.map { |v| serialize_value(v) }
  dbclient.sadd?(dbkey, serialized) unless serialized.empty?
  update_expiration
  self
end

#collectrawObject



96
97
98
# File 'lib/familia/data_type/types/unsorted_set.rb', line 96

def collectraw(&)
  membersraw.collect(&)
end

#difference(*other_sets) ⇒ Array Also known as: diff

Returns the difference of this set minus one or more other sets.

Parameters:

  • other_sets (Array<UnsortedSet, String>)

    Other sets (as UnsortedSet instances or raw keys)

Returns:

  • (Array)

    Deserialized members present in this set but not in any other sets



142
143
144
145
146
# File 'lib/familia/data_type/types/unsorted_set.rb', line 142

def difference(*other_sets)
  keys = extract_keys(other_sets)
  elements = dbclient.sdiff(dbkey, *keys)
  deserialize_values(*elements)
end

#diffstore(destination, *other_sets) ⇒ Integer Also known as: difference_store

Stores the difference of this set minus other sets into a destination key.

Parameters:

  • destination (UnsortedSet, String)

    Destination set (as UnsortedSet instance or raw key)

  • other_sets (Array<UnsortedSet, String>)

    Other sets to subtract

Returns:

  • (Integer)

    Number of elements in the resulting set



217
218
219
220
221
222
223
# File 'lib/familia/data_type/types/unsorted_set.rb', line 217

def diffstore(destination, *other_sets)
  dest_key = extract_key(destination)
  keys = extract_keys(other_sets)
  result = dbclient.sdiffstore(dest_key, dbkey, *keys)
  update_expiration
  result
end

#each(matching: nil, batch_size: 100) {|member| ... } ⇒ Enumerator, self

Note:

Pattern matches raw Redis storage (JSON-encoded). To filter on deserialized values, use Enumerable#select instead.

Iterates over members of the set.

Uses SSCAN for memory-efficient iteration. Optionally filters by member pattern using Redis MATCH.

Examples:

Iterate all members

tags.each { |tag| puts tag }

Filter by pattern (matches JSON-encoded storage)

tags.each(matching: "*category*") { |tag| process(tag) }

Parameters:

  • matching (String, nil) (defaults to: nil)

    Optional glob-style pattern to filter members (e.g., "user:", "_active"). Pattern is passed to Redis SSCAN MATCH and matches against raw storage format (JSON-encoded strings). For a string "admin", match with "\"admin\"" or use "*admin*" for substring match.

  • batch_size (Integer) (defaults to: 100)

    Number of elements to fetch per SSCAN iteration

Yields:

  • (member)

    Each deserialized member (optionally filtered)

Returns:

  • (Enumerator, self)

    Returns Enumerator if no block given, self otherwise



74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/familia/data_type/types/unsorted_set.rb', line 74

def each(matching: nil, batch_size: 100, &block)
  return to_enum(:each, matching: matching, batch_size: batch_size) unless block

  cursor = 0
  loop do
    new_cursor, elements = scan(cursor, match: matching, count: batch_size)
    elements.each(&block)
    cursor = new_cursor
    break if cursor.zero?
  end

  self
end

#eachrawObject



88
89
90
# File 'lib/familia/data_type/types/unsorted_set.rb', line 88

def eachraw(&)
  membersraw.each(&)
end

#eachraw_with_indexObject



92
93
94
# File 'lib/familia/data_type/types/unsorted_set.rb', line 92

def eachraw_with_index(&)
  membersraw.each_with_index(&)
end

#element_countInteger Also known as: size, length, count

Returns the number of elements in the unsorted set

Returns:

  • (Integer)

    number of elements



13
14
15
# File 'lib/familia/data_type/types/unsorted_set.rb', line 13

def element_count
  dbclient.scard dbkey
end

#empty?Boolean

Returns:

  • (Boolean)


20
21
22
# File 'lib/familia/data_type/types/unsorted_set.rb', line 20

def empty?
  element_count.zero?
end

#intercard(*other_sets, limit: 0) ⇒ Integer Also known as: intersection_cardinality

Returns the cardinality of the intersection without retrieving members. More memory-efficient than intersection when only the count is needed.

Parameters:

  • other_sets (Array<UnsortedSet, String>)

    Other sets (as UnsortedSet instances or raw keys)

  • limit (Integer) (defaults to: 0)

    Stop counting after reaching this limit (0 = no limit)

Returns:

  • (Integer)

    Number of elements in the intersection



178
179
180
181
182
183
184
# File 'lib/familia/data_type/types/unsorted_set.rb', line 178

def intercard(*other_sets, limit: 0)
  keys = extract_keys(other_sets)
  all_keys = [dbkey, *keys]
  args = [:sintercard, all_keys.size, *all_keys]
  args.push('LIMIT', limit) if limit.positive?
  dbclient.call(*args)
end

#intersection(*other_sets) ⇒ Array Also known as: inter

Returns the intersection of this set with one or more other sets.

Parameters:

  • other_sets (Array<UnsortedSet, String>)

    Other sets (as UnsortedSet instances or raw keys)

Returns:

  • (Array)

    Deserialized members present in all sets



123
124
125
126
127
# File 'lib/familia/data_type/types/unsorted_set.rb', line 123

def intersection(*other_sets)
  keys = extract_keys(other_sets)
  elements = dbclient.sinter(dbkey, *keys)
  deserialize_values(*elements)
end

#interstore(destination, *other_sets) ⇒ Integer Also known as: intersection_store

Stores the intersection of this set with other sets into a destination key.

Parameters:

  • destination (UnsortedSet, String)

    Destination set (as UnsortedSet instance or raw key)

  • other_sets (Array<UnsortedSet, String>)

    Other sets to intersect with

Returns:

  • (Integer)

    Number of elements in the resulting set



191
192
193
194
195
196
197
# File 'lib/familia/data_type/types/unsorted_set.rb', line 191

def interstore(destination, *other_sets)
  dest_key = extract_key(destination)
  keys = extract_keys(other_sets)
  result = dbclient.sinterstore(dest_key, dbkey, *keys)
  update_expiration
  result
end

#member?(val) ⇒ Boolean Also known as: include?

Returns:

  • (Boolean)


104
105
106
# File 'lib/familia/data_type/types/unsorted_set.rb', line 104

def member?(val)
  dbclient.sismember dbkey, serialize_value(val)
end

#member_any?(*values) ⇒ Array<Boolean> Also known as: members?

Checks membership for multiple values at once.

Parameters:

  • values (Array)

    Values to check for membership

Returns:

  • (Array<Boolean>)

    Array of booleans indicating membership for each value



152
153
154
155
156
# File 'lib/familia/data_type/types/unsorted_set.rb', line 152

def member_any?(*values)
  values = values.flatten
  serialized = values.map { |v| serialize_value(v) }
  dbclient.smismember(dbkey, serialized)
end

#membersObject Also known as: all, to_a



40
41
42
43
44
# File 'lib/familia/data_type/types/unsorted_set.rb', line 40

def members
  echo :members, Familia.pretty_stack(limit: 1) if Familia.debug
  elements = membersraw
  deserialize_values(*elements)
end

#membersrawObject



48
49
50
# File 'lib/familia/data_type/types/unsorted_set.rb', line 48

def membersraw
  dbclient.smembers(dbkey)
end

#move(dstkey, val) ⇒ Object



233
234
235
236
237
238
# File 'lib/familia/data_type/types/unsorted_set.rb', line 233

def move(dstkey, val)
  warn_if_dirty!
  ret = dbclient.smove dbkey, dstkey, serialize_value(val)
  update_expiration
  ret
end

#popObject



226
227
228
229
230
231
# File 'lib/familia/data_type/types/unsorted_set.rb', line 226

def pop
  warn_if_dirty!
  ret = deserialize_value(dbclient.spop(dbkey))
  update_expiration
  ret
end

#remove_element(value) ⇒ Integer Also known as: remove

Removes a member from the set

Parameters:

  • value

    The value to remove from the set

Returns:

  • (Integer)

    The number of members that were removed (0 or 1)



112
113
114
115
116
117
# File 'lib/familia/data_type/types/unsorted_set.rb', line 112

def remove_element(value)
  warn_if_dirty!
  ret = dbclient.srem dbkey, serialize_value(value)
  update_expiration
  ret
end

#sample(count = 1) ⇒ Array Also known as: random

Get one or more random members from the set

Parameters:

  • count (Integer) (defaults to: 1)

    Number of random members to return (default: 1)

Returns:

  • (Array)

    Array of deserialized random members



243
244
245
# File 'lib/familia/data_type/types/unsorted_set.rb', line 243

def sample(count = 1)
  deserialize_values(*sampleraw(count))
end

#sampleraw(count = 1) ⇒ Array Also known as: randomraw

Get one or more random members from the set without deserialization

Parameters:

  • count (Integer) (defaults to: 1)

    Number of random members to return (default: 1)

Returns:

  • (Array)

    Array of raw random members



251
252
253
# File 'lib/familia/data_type/types/unsorted_set.rb', line 251

def sampleraw(count = 1)
  dbclient.srandmember(dbkey, count) || []
end

#scan(cursor = 0, match: nil, count: nil) ⇒ Array<Integer, Array>

Iterates over set members using cursor-based iteration.

Parameters:

  • cursor (Integer) (defaults to: 0)

    Starting cursor position (default: 0)

  • match (String, nil) (defaults to: nil)

    Optional pattern to filter members

  • count (Integer, nil) (defaults to: nil)

    Optional hint for number of elements to return per call

Returns:

  • (Array<Integer, Array>)

    Two-element array: [new_cursor, deserialized_members]



164
165
166
167
168
169
170
171
# File 'lib/familia/data_type/types/unsorted_set.rb', line 164

def scan(cursor = 0, match: nil, count: nil)
  opts = {}
  opts[:match] = match if match
  opts[:count] = count if count

  new_cursor, elements = dbclient.sscan(dbkey, cursor, **opts)
  [new_cursor.to_i, deserialize_values(*elements)]
end

#selectrawObject



100
101
102
# File 'lib/familia/data_type/types/unsorted_set.rb', line 100

def selectraw(&)
  membersraw.select(&)
end

#union(*other_sets) ⇒ Array

Returns the union of this set with one or more other sets.

Parameters:

  • other_sets (Array<UnsortedSet, String>)

    Other sets (as UnsortedSet instances or raw keys)

Returns:

  • (Array)

    Deserialized members present in any of the sets



133
134
135
136
137
# File 'lib/familia/data_type/types/unsorted_set.rb', line 133

def union(*other_sets)
  keys = extract_keys(other_sets)
  elements = dbclient.sunion(dbkey, *keys)
  deserialize_values(*elements)
end

#unionstore(destination, *other_sets) ⇒ Integer Also known as: union_store

Stores the union of this set with other sets into a destination key.

Parameters:

  • destination (UnsortedSet, String)

    Destination set (as UnsortedSet instance or raw key)

  • other_sets (Array<UnsortedSet, String>)

    Other sets to union with

Returns:

  • (Integer)

    Number of elements in the resulting set



204
205
206
207
208
209
210
# File 'lib/familia/data_type/types/unsorted_set.rb', line 204

def unionstore(destination, *other_sets)
  dest_key = extract_key(destination)
  keys = extract_keys(other_sets)
  result = dbclient.sunionstore(dest_key, dbkey, *keys)
  update_expiration
  result
end