Class: Familia::SortedSet

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

Instance Attribute Summary

Attributes inherited from RedisType

#dump_method, #keystring, #load_method, #opts, #parent

Attributes included from Features

#features_enabled

Instance Method Summary collapse

Methods inherited from RedisType

#class?, #db, inherited, #initialize, #parent?, #parent_class?, #parent_instance?, #redis, #rediskey, register, #uri, valid_keys_only

Methods included from Features

#feature

Methods included from RedisType::Serialization

#from_redis, #multi_from_redis, #multi_from_redis_with_nil, #to_redis

Methods included from RedisType::Commands

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

Methods included from Base

add_feature, #generate_id, #update_expiration, #uuid

Constructor Details

This class inherits a constructor from Familia::RedisType

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.



31
32
33
# File 'lib/familia/types/sorted_set.rb', line 31

def <<(val)
  add(Time.now.to_i, 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


42
43
44
# File 'lib/familia/types/sorted_set.rb', line 42

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

#add(score, val) ⇒ Object



46
47
48
49
50
# File 'lib/familia/types/sorted_set.rb', line 46

def add(score, val)
  ret = redis.zadd rediskey, score, to_redis(val)
  update_expiration
  ret
end

#at(idx) ⇒ Object



217
218
219
# File 'lib/familia/types/sorted_set.rb', line 217

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

#collect(&blk) ⇒ Object



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

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

#collectraw(&blk) ⇒ Object



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

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

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



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

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

#delete(val) ⇒ Object Also known as: remove, rem, del



204
205
206
207
208
209
210
211
212
# File 'lib/familia/types/sorted_set.rb', line 204

def delete(val)
  Familia.trace :DELETE, redis, "#{val}<#{val.class}>", caller(1..1) 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.
  redis.zrem rediskey, to_redis(val, strict_values: false)
end

#each(&blk) ⇒ Object



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

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

#each_with_index(&blk) ⇒ Object



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

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

#eachraw(&blk) ⇒ Object



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

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

#eachraw_with_index(&blk) ⇒ Object



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

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

#empty?Boolean

Returns:

  • (Boolean)


10
11
12
# File 'lib/familia/types/sorted_set.rb', line 10

def empty?
  size.zero?
end

#firstObject

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



222
223
224
# File 'lib/familia/types/sorted_set.rb', line 222

def first
  at(0)
end

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



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

def increment(val, by = 1)
  redis.zincrby(rediskey, by, val).to_i
end

#lastObject

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



227
228
229
# File 'lib/familia/types/sorted_set.rb', line 227

def last
  at(-1)
end

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

Returns:

  • (Boolean)


58
59
60
61
# File 'lib/familia/types/sorted_set.rb', line 58

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

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



76
77
78
79
80
# File 'lib/familia/types/sorted_set.rb', line 76

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

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



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

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

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



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

def range(sidx, eidx, opts = {})
  echo :range, caller(1..1).first if Familia.debug
  elements = rangeraw(sidx, eidx, opts)
  multi_from_redis(*elements)
end

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

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



160
161
162
163
164
# File 'lib/familia/types/sorted_set.rb', line 160

def rangebyscore(sscore, escore, opts = {})
  echo :rangebyscore, caller(1..1).first if Familia.debug
  elements = rangebyscoreraw(sscore, escore, opts)
  multi_from_redis(*elements)
end

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



166
167
168
169
# File 'lib/familia/types/sorted_set.rb', line 166

def rangebyscoreraw(sscore, escore, opts = {})
  echo :rangebyscoreraw, caller(1..1).first if Familia.debug
  redis.zrangebyscore(rediskey, sscore, escore, **opts)
end

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



138
139
140
141
142
143
144
145
146
147
# File 'lib/familia/types/sorted_set.rb', line 138

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
  # redis.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)
  #
  redis.zrange(rediskey, sidx, eidx, **opts)
end

#rank(v) ⇒ Object

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



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

def rank(v)
  ret = redis.zrank rediskey, to_redis(v, strict_values: false)
  ret&.to_i
end

#remrangebyrank(srank, erank) ⇒ Object



184
185
186
# File 'lib/familia/types/sorted_set.rb', line 184

def remrangebyrank(srank, erank)
  redis.zremrangebyrank rediskey, srank, erank
end

#remrangebyscore(sscore, escore) ⇒ Object



188
189
190
# File 'lib/familia/types/sorted_set.rb', line 188

def remrangebyscore(sscore, escore)
  redis.zremrangebyscore rediskey, sscore, escore
end

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



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

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

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



95
96
97
98
# File 'lib/familia/types/sorted_set.rb', line 95

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

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



149
150
151
152
153
# File 'lib/familia/types/sorted_set.rb', line 149

def revrange(sidx, eidx, opts = {})
  echo :revrange, caller(1..1).first if Familia.debug
  elements = revrangeraw(sidx, eidx, opts)
  multi_from_redis(*elements)
end

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

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



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

def revrangebyscore(sscore, escore, opts = {})
  echo :revrangebyscore, caller(1..1).first if Familia.debug
  elements = revrangebyscoreraw(sscore, escore, opts)
  multi_from_redis(*elements)
end

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



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

def revrangebyscoreraw(sscore, escore, opts = {})
  echo :revrangebyscoreraw, caller(1..1).first if Familia.debug
  opts[:with_scores] = true if opts[:withscores]
  redis.zrevrangebyscore(rediskey, sscore, escore, opts)
end

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



155
156
157
# File 'lib/familia/types/sorted_set.rb', line 155

def revrangeraw(sidx, eidx, opts = {})
  redis.zrevrange(rediskey, sidx, eidx, **opts)
end

#revrank(v) ⇒ Object

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



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

def revrank(v)
  ret = redis.zrevrank rediskey, to_redis(v, strict_values: false)
  ret&.to_i
end

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



52
53
54
55
# File 'lib/familia/types/sorted_set.rb', line 52

def score(val)
  ret = redis.zscore rediskey, to_redis(val, strict_values: false)
  ret&.to_f
end

#select(&blk) ⇒ Object



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

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

#selectraw(&blk) ⇒ Object



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

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

#sizeObject Also known as: length



5
6
7
# File 'lib/familia/types/sorted_set.rb', line 5

def size
  redis.zcard rediskey
end