Class: Familia::SortedSet

Inherits:
DataType show all
Defined in:
lib/familia/data_type/types/sorted_set.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

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::Commands

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

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

#<<(val) ⇒ Integer

Note:

This is a non-standard operation for sorted sets as it doesn't allow specifying a custom score. Use add or []= for more control.

Adds a new element to the sorted set with the current timestamp as the score.

This method provides a convenient way to add elements to the sorted set without explicitly specifying a score. It uses the current Unix timestamp as the score, which effectively sorts elements by their insertion time.

Examples:

sorted_set << "new_element"

Parameters:

  • val (Object)

    The value to be added to the sorted set.

Returns:

  • (Integer)

    Returns 1 if the element is new and added, 0 if the element already existed and the score was updated.



34
35
36
# File 'lib/familia/data_type/types/sorted_set.rb', line 34

def <<(val)
  add(val)
end

#[]=(val, score) ⇒ Object

NOTE: The argument order is the reverse of #add. We do this to more naturally align with how the [] and []= methods are used.

e.g. obj.metrics[VALUE] = SCORE obj.metrics[VALUE] # => SCORE



45
46
47
# File 'lib/familia/data_type/types/sorted_set.rb', line 45

def []=(val, score)
  add val, score
end

#add(val, score = nil) ⇒ Object Also known as: add_element



49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/familia/data_type/types/sorted_set.rb', line 49

def add(val, score = nil)
  # TODO: Support some or all of the ZADD options.
  # XX: Only update existing elements. Don't add new ones.
  # NX: Only add new elements. Don't update existing ones.
  # LT: Only update if new score < current score. Doesn't prevent adding.
  # GT: Only update if new score > current score. Doesn't prevent adding.
  # CH: Return total changed elements (new + updated) instead of just new.
  # INCR: Acts like ZINCRBY. Only one score-element pair allowed.
  # Note: GT, LT and NX options are mutually exclusive.
  score ||= Familia.now
  ret = dbclient.zadd dbkey, score, serialize_value(val)
  update_expiration
  ret
end

#at(idx) ⇒ Object



231
232
233
# File 'lib/familia/data_type/types/sorted_set.rb', line 231

def at(idx)
  range(idx, idx).first
end

#collectObject



121
122
123
# File 'lib/familia/data_type/types/sorted_set.rb', line 121

def collect(&)
  members.collect(&)
end

#collectrawObject



137
138
139
# File 'lib/familia/data_type/types/sorted_set.rb', line 137

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

#decrement(val, by = 1) ⇒ Object Also known as: decr, decrby



211
212
213
# File 'lib/familia/data_type/types/sorted_set.rb', line 211

def decrement(val, by = 1)
  increment val, -by
end

#eachObject



113
114
115
# File 'lib/familia/data_type/types/sorted_set.rb', line 113

def each(&)
  members.each(&)
end

#each_with_indexObject



117
118
119
# File 'lib/familia/data_type/types/sorted_set.rb', line 117

def each_with_index(&)
  members.each_with_index(&)
end

#eachrawObject



129
130
131
# File 'lib/familia/data_type/types/sorted_set.rb', line 129

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

#eachraw_with_indexObject



133
134
135
# File 'lib/familia/data_type/types/sorted_set.rb', line 133

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

#element_countInteger Also known as: size, length, count

Returns the number of elements in the sorted set

Returns:

  • (Integer)

    number of elements



7
8
9
# File 'lib/familia/data_type/types/sorted_set.rb', line 7

def element_count
  dbclient.zcard dbkey
end

#empty?Boolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/familia/data_type/types/sorted_set.rb', line 14

def empty?
  element_count.zero?
end

#firstObject

Return the first element in the list. Redis: ZRANGE(0)



236
237
238
# File 'lib/familia/data_type/types/sorted_set.rb', line 236

def first
  at(0)
end

#increment(val, by = 1) ⇒ Object Also known as: incr, incrby



205
206
207
# File 'lib/familia/data_type/types/sorted_set.rb', line 205

def increment(val, by = 1)
  dbclient.zincrby(dbkey, by, val).to_i
end

#lastObject

Return the last element in the list. Redis: ZRANGE(-1)



241
242
243
# File 'lib/familia/data_type/types/sorted_set.rb', line 241

def last
  at(-1)
end

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

Returns:

  • (Boolean)


71
72
73
74
# File 'lib/familia/data_type/types/sorted_set.rb', line 71

def member?(val)
  Familia.trace :MEMBER, nil, "#{val}<#{val.class}>" if Familia.debug?
  !rank(val).nil?
end

#members(count = -1,, opts = {}) ⇒ Object Also known as: to_a, all



89
90
91
92
93
# File 'lib/familia/data_type/types/sorted_set.rb', line 89

def members(count = -1, opts = {})
  count -= 1 if count.positive?
  elements = membersraw count, opts
  deserialize_values(*elements)
end

#membersraw(count = -1,, opts = {}) ⇒ Object



97
98
99
100
# File 'lib/familia/data_type/types/sorted_set.rb', line 97

def membersraw(count = -1, opts = {})
  count -= 1 if count.positive?
  rangeraw 0, count, opts
end

#range(sidx, eidx, opts = {}) ⇒ Object



145
146
147
148
149
# File 'lib/familia/data_type/types/sorted_set.rb', line 145

def range(sidx, eidx, opts = {})
  echo :range, Familia.pretty_stack(limit: 1) if Familia.debug
  elements = rangeraw(sidx, eidx, opts)
  deserialize_values(*elements)
end

#rangebyscore(sscore, escore, opts = {}) ⇒ Object

e.g. obj.metrics.rangebyscore (now-12.hours), now, :limit => [0, 10]



173
174
175
176
177
# File 'lib/familia/data_type/types/sorted_set.rb', line 173

def rangebyscore(sscore, escore, opts = {})
  echo :rangebyscore, Familia.pretty_stack(limit: 1) if Familia.debug
  elements = rangebyscoreraw(sscore, escore, opts)
  deserialize_values(*elements)
end

#rangebyscoreraw(sscore, escore, opts = {}) ⇒ Object



179
180
181
182
# File 'lib/familia/data_type/types/sorted_set.rb', line 179

def rangebyscoreraw(sscore, escore, opts = {})
  echo :rangebyscoreraw, Familia.pretty_stack(limit: 1) if Familia.debug
  dbclient.zrangebyscore(dbkey, sscore, escore, **opts)
end

#rangeraw(sidx, eidx, opts = {}) ⇒ Object



151
152
153
154
155
156
157
158
159
160
# File 'lib/familia/data_type/types/sorted_set.rb', line 151

def rangeraw(sidx, eidx, opts = {})
  # NOTE: :withscores (no underscore) is the correct naming for the
  # redis-4.x gem. We pass :withscores through explicitly b/c
  # dbclient.zrange et al only accept that one optional argument.
  # Passing `opts`` through leads to an ArgumentError:
  #
  #   sorted_sets.rb:374:in `zrevrange': wrong number of arguments (given 4, expected 3) (ArgumentError)
  #
  dbclient.zrange(dbkey, sidx, eidx, **opts)
end

#rank(v) ⇒ Object

rank of member +v+ when ordered lowest to highest (starts at 0)



78
79
80
81
# File 'lib/familia/data_type/types/sorted_set.rb', line 78

def rank(v)
  ret = dbclient.zrank dbkey, serialize_value(v, strict_values: false)
  ret&.to_i
end

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

Removes a member from the sorted set

Parameters:

  • value

    The value to remove from the sorted set

Returns:

  • (Integer)

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



220
221
222
223
224
225
226
227
228
# File 'lib/familia/data_type/types/sorted_set.rb', line 220

def remove_element(value)
  Familia.trace :REMOVE_ELEMENT, nil, "#{value}<#{value.class}>" if Familia.debug?
  # We use `strict_values: false` here to allow for the deletion of values
  # that are in the sorted set. If it's a horreum object, the value is
  # the identifier and not a serialized version of the object. So either
  # the value exists in the sorted set or it doesn't -- we don't need to
  # raise an error if it's not found.
  dbclient.zrem dbkey, serialize_value(value, strict_values: false)
end

#remrangebyrank(srank, erank) ⇒ Object



197
198
199
# File 'lib/familia/data_type/types/sorted_set.rb', line 197

def remrangebyrank(srank, erank)
  dbclient.zremrangebyrank dbkey, srank, erank
end

#remrangebyscore(sscore, escore) ⇒ Object



201
202
203
# File 'lib/familia/data_type/types/sorted_set.rb', line 201

def remrangebyscore(sscore, escore)
  dbclient.zremrangebyscore dbkey, sscore, escore
end

#revmembers(count = -1,, opts = {}) ⇒ Object



102
103
104
105
106
# File 'lib/familia/data_type/types/sorted_set.rb', line 102

def revmembers(count = -1, opts = {})
  count -= 1 if count.positive?
  elements = revmembersraw count, opts
  deserialize_values(*elements)
end

#revmembersraw(count = -1,, opts = {}) ⇒ Object



108
109
110
111
# File 'lib/familia/data_type/types/sorted_set.rb', line 108

def revmembersraw(count = -1, opts = {})
  count -= 1 if count.positive?
  revrangeraw 0, count, opts
end

#revrange(sidx, eidx, opts = {}) ⇒ Object



162
163
164
165
166
# File 'lib/familia/data_type/types/sorted_set.rb', line 162

def revrange(sidx, eidx, opts = {})
  echo :revrange, Familia.pretty_stack(limit: 1) if Familia.debug
  elements = revrangeraw(sidx, eidx, opts)
  deserialize_values(*elements)
end

#revrangebyscore(sscore, escore, opts = {}) ⇒ Object

e.g. obj.metrics.revrangebyscore (now-12.hours), now, :limit => [0, 10]



185
186
187
188
189
# File 'lib/familia/data_type/types/sorted_set.rb', line 185

def revrangebyscore(sscore, escore, opts = {})
  echo :revrangebyscore, Familia.pretty_stack(limit: 1) if Familia.debug
  elements = revrangebyscoreraw(sscore, escore, opts)
  deserialize_values(*elements)
end

#revrangebyscoreraw(sscore, escore, opts = {}) ⇒ Object



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

def revrangebyscoreraw(sscore, escore, opts = {})
  echo :revrangebyscoreraw, Familia.pretty_stack(limit: 1) if Familia.debug
  opts[:with_scores] = true if opts[:withscores]
  dbclient.zrevrangebyscore(dbkey, sscore, escore, opts)
end

#revrangeraw(sidx, eidx, opts = {}) ⇒ Object



168
169
170
# File 'lib/familia/data_type/types/sorted_set.rb', line 168

def revrangeraw(sidx, eidx, opts = {})
  dbclient.zrevrange(dbkey, sidx, eidx, **opts)
end

#revrank(v) ⇒ Object

rank of member +v+ when ordered highest to lowest (starts at 0)



84
85
86
87
# File 'lib/familia/data_type/types/sorted_set.rb', line 84

def revrank(v)
  ret = dbclient.zrevrank dbkey, serialize_value(v, strict_values: false)
  ret&.to_i
end

#score(val) ⇒ Object Also known as: []



65
66
67
68
# File 'lib/familia/data_type/types/sorted_set.rb', line 65

def score(val)
  ret = dbclient.zscore dbkey, serialize_value(val, strict_values: false)
  ret&.to_f
end

#selectObject



125
126
127
# File 'lib/familia/data_type/types/sorted_set.rb', line 125

def select(&)
  members.select(&)
end

#selectrawObject



141
142
143
# File 'lib/familia/data_type/types/sorted_set.rb', line 141

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