module Rubbis::State::StateCommands
Public Instance Methods
del(key)
click to toggle source
# File lib/rubbis/state.rb, line 188 def del(key) touch! key if data.delete(key) log << ['del', key] end expires.delete(key) end
echo(text)
click to toggle source
# File lib/rubbis/state.rb, line 92 def echo(text) text end
exists(key)
click to toggle source
# File lib/rubbis/state.rb, line 233 def exists(key) if data[key] 1 else 0 end end
expire(key, secs)
click to toggle source
# File lib/rubbis/state.rb, line 108 def expire(key, secs) pexpire(key, secs.to_i * 1000) end
expire_keys!(n: 100, threshold: 0.25, rng: Random.new)
click to toggle source
# File lib/rubbis/state.rb, line 142 def expire_keys!(n: 100, threshold: 0.25, rng: Random.new) begin expired = expires.keys.sample(n, random: rng).count do |key| get(key) end end while expired > n * threshold end
get(key)
click to toggle source
# File lib/rubbis/state.rb, line 181 def get(key) expiry = expires[key] del(key) if expiry && expiry <= clock.now data[key] end
hget(*args)
click to toggle source
# File lib/rubbis/state.rb, line 206 def hget(*args) hash, key = *args return Error.incorrect_args("hget") unless hash && key value = get(hash) value[key] if value end
hincrby(hash, key, amount)
click to toggle source
# File lib/rubbis/state.rb, line 225 def hincrby(hash, key, amount) value = get(hash) if value existing = value[key] value[key] = existing.to_i + amount.to_i end end
hmget(hash, *keys)
click to toggle source
# File lib/rubbis/state.rb, line 216 def hmget(hash, *keys) existing = get(hash) || {} if existing.is_a?(Hash) existing.values_at(*keys) else Error.type_error end end
hset(*args)
click to toggle source
# File lib/rubbis/state.rb, line 196 def hset(*args) hash, key, value = *args return Error.incorrect_args("hset") unless hash && key && value touch! key data[hash] ||= {} data[hash][key] = value :ok end
keys(pattern)
click to toggle source
# File lib/rubbis/state.rb, line 241 def keys(pattern) if pattern == '*' result = data.keys result else raise 'unimplemented' end end
llen(key)
click to toggle source
# File lib/rubbis/state.rb, line 299 def llen(key) list = get(key) list ||= data[key] = [] list.length end
lpush(key, value)
click to toggle source
# File lib/rubbis/state.rb, line 287 def lpush(key, value) list = get(key) list ||= data[key] = [] if list_watches.fetch(key, []).any? ready_keys << key end touch! key list.unshift value list.length end
lrange(key, start, stop)
click to toggle source
# File lib/rubbis/state.rb, line 306 def lrange(key, start, stop) list = get(key) if list list[start.to_i..stop.to_i] else [] end end
minimal_log()
click to toggle source
# File lib/rubbis/state.rb, line 116 def minimal_log data.map do |key, value| case value when String [['set', key, value]] when Array value.reverse.map do |v| ['lpush', key, v] end else raise 'unimplemented' end end.reduce(:+) + expires.map do |key, value| ['pexpireat', key, (value * 1000).to_i.to_s] end end
pexpire(key, ms)
click to toggle source
# File lib/rubbis/state.rb, line 112 def pexpire(key, ms) pexpireat(key, clock.now * 1000.0 + ms.to_i) end
pexpireat(key, value)
click to toggle source
# File lib/rubbis/state.rb, line 132 def pexpireat(key, value) if get(key) expires[key] = value.to_i / 1000.0 log << ['pexpireat', key, value.to_i.round.to_s] 1 else 0 end end
ping()
click to toggle source
# File lib/rubbis/state.rb, line 88 def ping :pong end
process_list_watches!()
click to toggle source
# File lib/rubbis/state.rb, line 150 def process_list_watches! ready_keys.each do |key| list = get(key) watches = list_watches.fetch(key, []) while list.any? && watches.any? op, client = *watches.shift client.respond!(op.call) if client.active? end end ready_keys.clear end
publish(channel, message)
click to toggle source
# File lib/rubbis/state.rb, line 82 def publish(channel, message) subscribers_for(channel).each do |client| client.respond! ["message", channel, message] end.length end
rpop(key)
click to toggle source
# File lib/rubbis/state.rb, line 316 def rpop(key) list = get(key) list ||= data[key] = [] touch! key list.pop end
rpoplpush(pop_key, push_key)
click to toggle source
# File lib/rubbis/state.rb, line 325 def rpoplpush(pop_key, push_key) item = rpop(pop_key) return unless item lpush push_key, item item end
set(*args)
click to toggle source
# File lib/rubbis/state.rb, line 164 def set(*args) key, value ,modifier = *args return Error.incorrect_args("set") unless key && value exists = data.has_key?(key) nx = modifier == "NX" xx = modifier == "XX" if (!nx && !xx) || (nx && !exists) || (xx && exists) touch! key log << ['set', key, value] data[key] = value :ok end end
unsubscribe_all(client)
click to toggle source
# File lib/rubbis/state.rb, line 102 def unsubscribe_all(client) (channels.delete(client) || Set.new).each do |channel| subscribers.delete channel end end
watch(key, &block)
click to toggle source
# File lib/rubbis/state.rb, line 96 def watch(key, &block) watches[key] ||= [] watches[key] << block if block :ok end
zadd(key, score, member)
click to toggle source
# File lib/rubbis/state.rb, line 251 def zadd(key, score, member) score = score.to_f value = get(key) || data[key] = ZSet.new value.add(score, member) end
zrange(key, start, stop)
click to toggle source
# File lib/rubbis/state.rb, line 259 def zrange(key, start, stop) value = get(key) if value value.range(start.to_i, stop.to_i) else [] end end
zrank(key, member)
click to toggle source
# File lib/rubbis/state.rb, line 268 def zrank(key, member) value = get(key) if value value.rank(member) else -1 end end
zscore(key, member)
click to toggle source
# File lib/rubbis/state.rb, line 277 def zscore(key, member) value = get(key) if value value.score(member) else -1 end end