Class: Redis::Connection::Memory

Inherits:
Object
  • Object
show all
Includes:
CommandHelper
Defined in:
lib/redis/connection/memory.rb

Defined Under Namespace

Classes: ExpiringHash, ZSet

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connected = false) ⇒ Memory

Returns a new instance of Memory.



68
69
70
71
72
73
# File 'lib/redis/connection/memory.rb', line 68

def initialize(connected = false)
  @data = ExpiringHash.new
  @connected = connected
  @replies = []
  @buffer = nil
end

Class Method Details

.connect(options = {}) ⇒ Object



83
84
85
# File 'lib/redis/connection/memory.rb', line 83

def self.connect(options = {})
  self.instances[options] ||= self.new(true)
end

.instancesObject



79
80
81
# File 'lib/redis/connection/memory.rb', line 79

def self.instances
  @instances ||= {}
end

Instance Method Details

#[](key) ⇒ Object



596
597
598
# File 'lib/redis/connection/memory.rb', line 596

def [](key)
  get(key)
end

#[]=(key, value) ⇒ Object



600
601
602
# File 'lib/redis/connection/memory.rb', line 600

def []=(key, value)
  set(key, value)
end

#append(key, value) ⇒ Object



192
193
194
195
# File 'lib/redis/connection/memory.rb', line 192

def append(key, value)
  @data[key] = (@data[key] || "")
  @data[key] = @data[key] + value.to_s
end

#auth(password) ⇒ Object



137
138
139
# File 'lib/redis/connection/memory.rb', line 137

def auth(password)
  "OK"
end

#bgreriteaofObject



164
# File 'lib/redis/connection/memory.rb', line 164

def bgreriteaof ; end

#bgsaveObject



162
# File 'lib/redis/connection/memory.rb', line 162

def bgsave ; end

#connect_unix(path, timeout) ⇒ Object



87
88
89
# File 'lib/redis/connection/memory.rb', line 87

def connect_unix(path, timeout)
  @connected = true
end

#connected?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/redis/connection/memory.rb', line 75

def connected?
  @connected
end

#dbsizeObject



245
246
247
# File 'lib/redis/connection/memory.rb', line 245

def dbsize
  @data.keys.count
end

#decr(key) ⇒ Object



661
662
663
664
# File 'lib/redis/connection/memory.rb', line 661

def decr(key)
  @data.merge!({ key => (@data[key].to_i - 1).to_s || "-1"})
  @data[key].to_i
end

#decrby(key, by) ⇒ Object



666
667
668
669
# File 'lib/redis/connection/memory.rb', line 666

def decrby(key, by)
  @data.merge!({ key => ((@data[key].to_i - by.to_i) || (by.to_i * -1)).to_s })
  @data[key].to_i
end

#del(*keys) ⇒ Object

Raises:

  • (Redis::CommandError)


465
466
467
468
469
470
471
472
473
# File 'lib/redis/connection/memory.rb', line 465

def del(*keys)
  keys = keys.flatten(1)
  raise Redis::CommandError, "ERR wrong number of arguments for 'del' command" if keys.empty?
  old_count = @data.keys.size
  keys.each do |key|
    @data.delete(key)
  end
  deleted_count = old_count - @data.keys.size
end

#disconnectObject



91
92
93
94
# File 'lib/redis/connection/memory.rb', line 91

def disconnect
  @connected = false
  nil
end

#echo(string) ⇒ Object



233
234
235
# File 'lib/redis/connection/memory.rb', line 233

def echo(string)
  string
end

#execObject



687
688
689
690
691
# File 'lib/redis/connection/memory.rb', line 687

def exec
  buffer = @buffer
  @buffer = nil
  buffer
end

#exists(key) ⇒ Object



249
250
251
# File 'lib/redis/connection/memory.rb', line 249

def exists(key)
  @data.key?(key)
end

#expire(key, ttl) ⇒ Object



500
501
502
503
504
# File 'lib/redis/connection/memory.rb', line 500

def expire(key, ttl)
  return unless @data[key]
  @data.expires[key] = Time.now + ttl
  true
end

#expireat(key, timestamp) ⇒ Object



514
515
516
517
# File 'lib/redis/connection/memory.rb', line 514

def expireat(key, timestamp)
  @data.expires[key] = Time.at(timestamp)
  true
end

#flushallObject



133
134
135
# File 'lib/redis/connection/memory.rb', line 133

def flushall
  flushdb
end

#flushdbObject

NOT IMPLEMENTED:

  • blpop

  • brpop

  • brpoplpush

  • discard

  • move

  • subscribe

  • psubscribe

  • publish

  • zremrangebyrank

  • zunionstore



129
130
131
# File 'lib/redis/connection/memory.rb', line 129

def flushdb
  @data = ExpiringHash.new
end

#get(key) ⇒ Object



166
167
168
# File 'lib/redis/connection/memory.rb', line 166

def get(key)
  @data[key]
end

#getbit(key, offset) ⇒ Object



170
171
172
173
# File 'lib/redis/connection/memory.rb', line 170

def getbit(key, offset)
  return unless @data[key]
  @data[key].unpack('B*')[0].split("")[offset].to_i
end

#getrange(key, start, ending) ⇒ Object Also known as: substr



175
176
177
178
# File 'lib/redis/connection/memory.rb', line 175

def getrange(key, start, ending)
  return unless @data[key]
  @data[key][start..ending]
end

#getset(key, value) ⇒ Object



181
182
183
184
185
# File 'lib/redis/connection/memory.rb', line 181

def getset(key, value)
  old_value = @data[key]
  @data[key] = value
  return old_value
end

#hdel(key, field) ⇒ Object



212
213
214
215
216
# File 'lib/redis/connection/memory.rb', line 212

def hdel(key, field)
  data_type_check(key, Hash)
  @data[key] && @data[key].delete(field)
  remove_key_for_empty_collection(key)
end

#hexists(key, field) ⇒ Object



588
589
590
591
592
# File 'lib/redis/connection/memory.rb', line 588

def hexists(key, field)
  data_type_check(key, Hash)
  return false unless @data[key]
  @data[key].key?(field)
end

#hget(key, field) ⇒ Object



207
208
209
210
# File 'lib/redis/connection/memory.rb', line 207

def hget(key, field)
  data_type_check(key, Hash)
  @data[key] && @data[key][field.to_s]
end

#hgetall(key) ⇒ Object



202
203
204
205
# File 'lib/redis/connection/memory.rb', line 202

def hgetall(key)
  data_type_check(key, Hash)
  @data[key].to_a.flatten || {}
end

#hincrby(key, field, increment) ⇒ Object



578
579
580
581
582
583
584
585
586
# File 'lib/redis/connection/memory.rb', line 578

def hincrby(key, field, increment)
  data_type_check(key, Hash)
  if @data[key]
    @data[key][field] = (@data[key][field.to_s].to_i + increment.to_i).to_s
  else
    @data[key] = { field => increment.to_s }
  end
  @data[key][field].to_i
end

#hkeys(key) ⇒ Object



218
219
220
221
222
# File 'lib/redis/connection/memory.rb', line 218

def hkeys(key)
  data_type_check(key, Hash)
  return [] if @data[key].nil?
  @data[key].keys
end

#hlen(key) ⇒ Object



566
567
568
569
570
# File 'lib/redis/connection/memory.rb', line 566

def hlen(key)
  data_type_check(key, Hash)
  return 0 unless @data[key]
  @data[key].size
end

#hmget(key, *fields) ⇒ Object

Raises:

  • (Redis::CommandError)


552
553
554
555
556
557
558
559
560
561
562
563
564
# File 'lib/redis/connection/memory.rb', line 552

def hmget(key, *fields)
  raise Redis::CommandError, "wrong number of arguments for 'hmget' command" if fields.empty?
  data_type_check(key, Hash)
  values = []
  fields.map do |field|
    field = field.to_s
    if @data[key]
      @data[key][field]
    else
      nil
    end
  end
end

#hmset(key, *fields) ⇒ Object

Raises:

  • (Redis::CommandError)


543
544
545
546
547
548
549
550
# File 'lib/redis/connection/memory.rb', line 543

def hmset(key, *fields)
  raise Redis::CommandError, "wrong number of arguments for 'hmset' command" if fields.empty? || fields.size.odd?
  data_type_check(key, Hash)
  @data[key] ||= {}
  fields.each_slice(2) do |field|
    @data[key][field[0].to_s] = field[1].to_s
  end
end

#hset(key, field, value) ⇒ Object



523
524
525
526
527
528
529
530
531
532
533
534
# File 'lib/redis/connection/memory.rb', line 523

def hset(key, field, value)
  data_type_check(key, Hash)
  field = field.to_s
  if @data[key]
    result = !@data[key].include?(field)
    @data[key][field] = value.to_s
    result
  else
    @data[key] = { field => value.to_s }
    true
  end
end

#hsetnx(key, field, value) ⇒ Object



536
537
538
539
540
541
# File 'lib/redis/connection/memory.rb', line 536

def hsetnx(key, field, value)
  data_type_check(key, Hash)
  field = field.to_s
  return false if @data[key] && @data[key][field]
  hset(key, field, value)
end

#hvals(key) ⇒ Object



572
573
574
575
576
# File 'lib/redis/connection/memory.rb', line 572

def hvals(key)
  data_type_check(key, Hash)
  return [] unless @data[key]
  @data[key].values
end

#incr(key) ⇒ Object



651
652
653
654
# File 'lib/redis/connection/memory.rb', line 651

def incr(key)
  @data.merge!({ key => (@data[key].to_i + 1).to_s || "1"})
  @data[key].to_i
end

#incrby(key, by) ⇒ Object



656
657
658
659
# File 'lib/redis/connection/memory.rb', line 656

def incrby(key, by)
  @data.merge!({ key => (@data[key].to_i + by.to_i).to_s || by })
  @data[key].to_i
end

#infoObject



143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/redis/connection/memory.rb', line 143

def info
  {
    "redis_version" => "0.07",
    "connected_clients" => "1",
    "connected_slaves" => "0",
    "used_memory" => "3187",
    "changes_since_last_save" => "0",
    "last_save_time" => "1237655729",
    "total_connections_received" => "1",
    "total_commands_processed" => "1",
    "uptime_in_seconds" => "36000",
    "uptime_in_days" => 0
  }
end

#keys(pattern = "*") ⇒ Object



224
225
226
227
# File 'lib/redis/connection/memory.rb', line 224

def keys(pattern = "*")
  regexp = Regexp.new(pattern.split("*").map { |r| Regexp.escape(r) }.join(".*"))
  @data.keys.select { |key| key =~ regexp }
end

#lastsaveObject



241
242
243
# File 'lib/redis/connection/memory.rb', line 241

def lastsave
  Time.now.to_i
end

#lindex(key, index) ⇒ Object



270
271
272
273
# File 'lib/redis/connection/memory.rb', line 270

def lindex(key, index)
  data_type_check(key, Array)
  @data[key] && @data[key][index]
end

#linsert(key, where, pivot, value) ⇒ Object



275
276
277
278
279
280
281
282
283
284
# File 'lib/redis/connection/memory.rb', line 275

def linsert(key, where, pivot, value)
  data_type_check(key, Array)
  return unless @data[key]
  index = @data[key].index(pivot)
  case where
    when :before then @data[key].insert(index, value)
    when :after  then @data[key].insert(index + 1, value)
    else raise Redis::CommandError, "ERR syntax error"
  end
end

#llen(key) ⇒ Object



253
254
255
256
257
# File 'lib/redis/connection/memory.rb', line 253

def llen(key)
  data_type_check(key, Array)
  return 0 unless @data[key]
  @data[key].size
end

#lpop(key) ⇒ Object



353
354
355
356
357
# File 'lib/redis/connection/memory.rb', line 353

def lpop(key)
  data_type_check(key, Array)
  return unless @data[key]
  @data[key].shift
end

#lpush(key, value) ⇒ Object



326
327
328
329
330
331
332
333
# File 'lib/redis/connection/memory.rb', line 326

def lpush(key, value)
  data_type_check(key, Array)
  @data[key] ||= []
  [value].flatten.each do |val|
    @data[key].unshift(val.to_s)
  end
  @data[key].size
end

#lpushx(key, value) ⇒ Object



335
336
337
338
339
# File 'lib/redis/connection/memory.rb', line 335

def lpushx(key, value)
  data_type_check(key, Array)
  return unless @data[key]
  lpush(key, value)
end

#lrange(key, startidx, endidx) ⇒ Object



259
260
261
262
# File 'lib/redis/connection/memory.rb', line 259

def lrange(key, startidx, endidx)
  data_type_check(key, Array)
  (@data[key] && @data[key][startidx..endidx]) || []
end

#lrem(key, count, value) ⇒ Object



293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'lib/redis/connection/memory.rb', line 293

def lrem(key, count, value)
  data_type_check(key, Array)
  return unless @data[key]
  old_size = @data[key].size
  diff =
    if count == 0
      @data[key].delete(value)
      old_size - @data[key].size
    else
      array = count > 0 ? @data[key].dup : @data[key].reverse
      count.abs.times{ array.delete_at(array.index(value) || array.length) }
      @data[key] = count > 0 ? array.dup : array.reverse
      old_size - @data[key].size
    end
  remove_key_for_empty_collection(key)
  diff
end

#lset(key, index, value) ⇒ Object

Raises:

  • (RuntimeError)


286
287
288
289
290
291
# File 'lib/redis/connection/memory.rb', line 286

def lset(key, index, value)
  data_type_check(key, Array)
  return unless @data[key]
  raise RuntimeError if index >= @data[key].size
  @data[key][index] = value
end

#ltrim(key, start, stop) ⇒ Object



264
265
266
267
268
# File 'lib/redis/connection/memory.rb', line 264

def ltrim(key, start, stop)
  data_type_check(key, Array)
  return unless @data[key]
  @data[key] = @data[key][start..stop]
end

#mget(*keys) ⇒ Object

Raises:

  • (Redis::CommandError)


187
188
189
190
# File 'lib/redis/connection/memory.rb', line 187

def mget(*keys)
  raise Redis::CommandError, "wrong number of arguments for 'mget' command" if keys.empty?
  @data.values_at(*keys)
end

#monitorObject



158
# File 'lib/redis/connection/memory.rb', line 158

def monitor; end

#mset(*pairs) ⇒ Object



632
633
634
635
636
637
# File 'lib/redis/connection/memory.rb', line 632

def mset(*pairs)
  pairs.each_slice(2) do |pair|
    @data[pair[0].to_s] = pair[1].to_s
  end
  "OK"
end

#msetnx(*pairs) ⇒ Object



639
640
641
642
643
644
645
# File 'lib/redis/connection/memory.rb', line 639

def msetnx(*pairs)
  keys = []
  pairs.each_with_index{|item, index| keys << item.to_s if index % 2 == 0}
  return if keys.any?{|key| @data.key?(key) }
  mset(*pairs)
  true
end

#multiObject



693
694
695
696
697
# File 'lib/redis/connection/memory.rb', line 693

def multi
  @buffer = []
  yield if block_given?
  "OK"
end

#persist(key) ⇒ Object



519
520
521
# File 'lib/redis/connection/memory.rb', line 519

def persist(key)
  !!@data.expires.delete(key)
end

#pingObject



237
238
239
# File 'lib/redis/connection/memory.rb', line 237

def ping
  "PONG"
end

#quitObject



681
# File 'lib/redis/connection/memory.rb', line 681

def quit ; end

#randomkeyObject



229
230
231
# File 'lib/redis/connection/memory.rb', line 229

def randomkey
  @data.keys[rand(dbsize)]
end

#readObject



114
115
116
# File 'lib/redis/connection/memory.rb', line 114

def read
  @replies.shift
end

#rename(key, new_key) ⇒ Object



484
485
486
487
488
489
# File 'lib/redis/connection/memory.rb', line 484

def rename(key, new_key)
  return unless @data[key]
  @data[new_key] = @data[key]
  @data.expires[new_key] = @data.expires[key] if @data.expires.include?(key)
  @data.delete(key)
end

#renamenx(key, new_key) ⇒ Object



491
492
493
494
495
496
497
498
# File 'lib/redis/connection/memory.rb', line 491

def renamenx(key, new_key)
  if exists(new_key)
    false
  else
    rename(key, new_key)
    true
  end
end

#rpop(key) ⇒ Object



341
342
343
344
345
# File 'lib/redis/connection/memory.rb', line 341

def rpop(key)
  data_type_check(key, Array)
  return unless @data[key]
  @data[key].pop
end

#rpoplpush(key1, key2) ⇒ Object



347
348
349
350
351
# File 'lib/redis/connection/memory.rb', line 347

def rpoplpush(key1, key2)
  data_type_check(key1, Array)
  elem = rpop(key1)
  lpush(key2, elem)
end

#rpush(key, value) ⇒ Object



311
312
313
314
315
316
317
318
# File 'lib/redis/connection/memory.rb', line 311

def rpush(key, value)
  data_type_check(key, Array)
  @data[key] ||= []
  [value].flatten.each do |val|
    @data[key].push(val.to_s)
  end
  @data[key].size
end

#rpushx(key, value) ⇒ Object



320
321
322
323
324
# File 'lib/redis/connection/memory.rb', line 320

def rpushx(key, value)
  data_type_check(key, Array)
  return unless @data[key]
  rpush(key, value)
end

#sadd(key, value) ⇒ Object



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/redis/connection/memory.rb', line 371

def sadd(key, value)
  data_type_check(key, ::Set)
  value = Array(value)

  result = if @data[key]
    old_set = @data[key].dup
    @data[key].merge(value.map(&:to_s))
    (@data[key] - old_set).size
  else
    @data[key] = ::Set.new(value.map(&:to_s))
    @data[key].size
  end

  # 0 = false, 1 = true, 2+ untouched
  return result == 1 if result < 2
  result
end

#saveObject



160
# File 'lib/redis/connection/memory.rb', line 160

def save; end

#scard(key) ⇒ Object



410
411
412
413
414
# File 'lib/redis/connection/memory.rb', line 410

def scard(key)
  data_type_check(key, ::Set)
  return 0 unless @data[key]
  @data[key].size
end

#sdiff(key1, *keys) ⇒ Object



445
446
447
448
449
450
451
# File 'lib/redis/connection/memory.rb', line 445

def sdiff(key1, *keys)
  [key1, *keys].each { |k| data_type_check(k, ::Set) }
  keys = keys.map { |k| @data[k] || ::Set.new }
  keys.inject(@data[key1]) do |memo, set|
    memo - set
  end.to_a
end

#sdiffstore(destination, key1, *keys) ⇒ Object



453
454
455
456
457
# File 'lib/redis/connection/memory.rb', line 453

def sdiffstore(destination, key1, *keys)
  data_type_check(destination, ::Set)
  result = sdiff(key1, *keys)
  @data[destination] = ::Set.new(result)
end

#select(index) ⇒ Object



141
# File 'lib/redis/connection/memory.rb', line 141

def select(index) ; end

#set(key, value) ⇒ Object



604
605
606
607
# File 'lib/redis/connection/memory.rb', line 604

def set(key, value)
  @data[key] = value.to_s
  "OK"
end

#setbit(key, offset, bit) ⇒ Object



609
610
611
612
613
614
615
616
617
618
619
# File 'lib/redis/connection/memory.rb', line 609

def setbit(key, offset, bit)
  old_val = @data[key] ? @data[key].unpack('B*')[0].split("") : []
  size_increment = [((offset/8)+1)*8-old_val.length, 0].max
  old_val += Array.new(size_increment).map{"0"}
  original_val = old_val[offset]
  old_val[offset] = bit.to_s
  new_val = ""
  old_val.each_slice(8){|b| new_val = new_val + b.join("").to_i(2).chr }
  @data[key] = new_val
  original_val
end

#setex(key, seconds, value) ⇒ Object



621
622
623
624
# File 'lib/redis/connection/memory.rb', line 621

def setex(key, seconds, value)
  @data[key] = value.to_s
  expire(key, seconds)
end

#setnx(key, value) ⇒ Object



475
476
477
478
479
480
481
482
# File 'lib/redis/connection/memory.rb', line 475

def setnx(key, value)
  if exists(key)
    false
  else
    set(key, value)
    true
  end
end

#setrange(key, offset, value) ⇒ Object



626
627
628
629
630
# File 'lib/redis/connection/memory.rb', line 626

def setrange(key, offset, value)
  return unless @data[key]
  s = @data[key][offset,value.size]
  @data[key][s] = value
end

#shutdownObject



683
# File 'lib/redis/connection/memory.rb', line 683

def shutdown; end

#sinter(*keys) ⇒ Object



416
417
418
419
420
421
422
423
# File 'lib/redis/connection/memory.rb', line 416

def sinter(*keys)
  keys.each { |k| data_type_check(k, ::Set) }
  return ::Set.new if keys.any? { |k| @data[k].nil? }
  keys = keys.map { |k| @data[k] || ::Set.new }
  keys.inject do |set, key|
    set & key
  end.to_a
end

#sinterstore(destination, *keys) ⇒ Object



425
426
427
428
429
# File 'lib/redis/connection/memory.rb', line 425

def sinterstore(destination, *keys)
  data_type_check(destination, ::Set)
  result = sinter(*keys)
  @data[destination] = ::Set.new(result)
end

#sismember(key, value) ⇒ Object



365
366
367
368
369
# File 'lib/redis/connection/memory.rb', line 365

def sismember(key, value)
  data_type_check(key, ::Set)
  return false unless @data[key]
  @data[key].include?(value.to_s)
end

#slaveof(host, port) ⇒ Object



685
# File 'lib/redis/connection/memory.rb', line 685

def slaveof(host, port) ; end

#smembers(key) ⇒ Object



359
360
361
362
363
# File 'lib/redis/connection/memory.rb', line 359

def smembers(key)
  data_type_check(key, ::Set)
  return [] unless @data[key]
  @data[key].to_a.reverse
end

#smove(source, destination, value) ⇒ Object



396
397
398
399
400
401
# File 'lib/redis/connection/memory.rb', line 396

def smove(source, destination, value)
  data_type_check(destination, ::Set)
  result = self.srem(source, value)
  self.sadd(destination, value) if result
  result
end

#sort(key) ⇒ Object



647
648
649
# File 'lib/redis/connection/memory.rb', line 647

def sort(key)
  # TODO: Implement
end

#spop(key) ⇒ Object



403
404
405
406
407
408
# File 'lib/redis/connection/memory.rb', line 403

def spop(key)
  data_type_check(key, ::Set)
  elem = srandmember(key)
  srem(key, elem)
  elem
end

#srandmember(key) ⇒ Object



459
460
461
462
463
# File 'lib/redis/connection/memory.rb', line 459

def srandmember(key)
  data_type_check(key, ::Set)
  return nil unless @data[key]
  @data[key].to_a[rand(@data[key].size)]
end

#srem(key, value) ⇒ Object



389
390
391
392
393
394
# File 'lib/redis/connection/memory.rb', line 389

def srem(key, value)
  data_type_check(key, ::Set)
  deleted = !!(@data[key] && @data[key].delete?(value.to_s))
  remove_key_for_empty_collection(key)
  deleted
end

#strlen(key) ⇒ Object



197
198
199
200
# File 'lib/redis/connection/memory.rb', line 197

def strlen(key)
  return unless @data[key]
  @data[key].size
end

#sunion(*keys) ⇒ Object



431
432
433
434
435
436
437
# File 'lib/redis/connection/memory.rb', line 431

def sunion(*keys)
  keys.each { |k| data_type_check(k, ::Set) }
  keys = keys.map { |k| @data[k] || ::Set.new }
  keys.inject(::Set.new) do |set, key|
    set | key
  end.to_a
end

#sunionstore(destination, *keys) ⇒ Object



439
440
441
442
443
# File 'lib/redis/connection/memory.rb', line 439

def sunionstore(destination, *keys)
  data_type_check(destination, ::Set)
  result = sunion(*keys)
  @data[destination] = ::Set.new(result)
end

#syncObject



594
# File 'lib/redis/connection/memory.rb', line 594

def sync ; end

#timeout=(usecs) ⇒ Object



96
97
# File 'lib/redis/connection/memory.rb', line 96

def timeout=(usecs)
end

#ttl(key) ⇒ Object



506
507
508
509
510
511
512
# File 'lib/redis/connection/memory.rb', line 506

def ttl(key)
  if @data.expires.include?(key) && (ttl = @data.expires[key].to_i - Time.now.to_i) > 0
    ttl
  else
    -1
  end
end

#type(key) ⇒ Object



671
672
673
674
675
676
677
678
679
# File 'lib/redis/connection/memory.rb', line 671

def type(key)
  case value = @data[key]
    when nil then "none"
    when String then "string"
    when Hash then "hash"
    when Array then "list"
    when ::Set then "set"
  end
end

#unwatchObject



703
704
705
# File 'lib/redis/connection/memory.rb', line 703

def unwatch
  "OK"
end

#watch(_) ⇒ Object



699
700
701
# File 'lib/redis/connection/memory.rb', line 699

def watch(_)
  "OK"
end

#write(command) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/redis/connection/memory.rb', line 99

def write(command)
  method = command.shift
  reply = send(method, *command)

  if reply == true
    reply = 1
  elsif reply == false
    reply = 0
  end

  @replies << reply
  @buffer << reply if @buffer && method != :multi
  nil
end

#zadd(key, *args) ⇒ Object



707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
# File 'lib/redis/connection/memory.rb', line 707

def zadd(key, *args)
  if !args.first.is_a?(Array)
    if args.size < 2
      raise Redis::CommandError, "ERR wrong number of arguments for 'zadd' command"
    elsif args.size.odd?
      raise Redis::CommandError, "ERR syntax error"
    end
  else
    unless args.all? {|pair| pair.size == 2 }
      raise(Redis::CommandError, "ERR syntax error")
    end
  end

  data_type_check(key, ZSet)
  @data[key] ||= ZSet.new

  if args.size == 2
    score, value = args
    exists = !@data[key].key?(value.to_s)
    @data[key][value.to_s] = score
  else
    # Turn [1, 2, 3, 4] into [[1, 2], [3, 4]] unless it is already
    args = args.each_slice(2).to_a unless args.first.is_a?(Array)
    exists = args.map(&:last).map { |el| @data[key].key?(el.to_s) }.count(false)
    args.each { |score, value| @data[key][value.to_s] = score }
  end

  exists
end

#zcard(key) ⇒ Object



745
746
747
748
# File 'lib/redis/connection/memory.rb', line 745

def zcard(key)
  data_type_check(key, ZSet)
  @data[key] ? @data[key].size : 0
end

#zcount(key, min, max) ⇒ Object



755
756
757
758
759
# File 'lib/redis/connection/memory.rb', line 755

def zcount(key, min, max)
  data_type_check(key, ZSet)
  return 0 unless @data[key]
  zrange_select_by_score(key, min, max).size
end

#zincrby(key, num, value) ⇒ Object



761
762
763
764
765
766
767
# File 'lib/redis/connection/memory.rb', line 761

def zincrby(key, num, value)
  data_type_check(key, ZSet)
  @data[key] ||= ZSet.new
  @data[key][value.to_s] ||= 0
  @data[key][value.to_s] += num
  @data[key][value.to_s].to_s
end

#zinterstore(out, _, *keys) ⇒ Object



844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
# File 'lib/redis/connection/memory.rb', line 844

def zinterstore(out, _, *keys)
  data_type_check(out, ZSet)

  hashes = keys.map do |src|
    case @data[src]
    when ::Set
      # Every value has a score of 1
      Hash[@data[src].map {|k,v| [k, 1]}]
    when Hash
      @data[src]
    else
      {}
    end
  end

  @data[out] = ZSet.new
  values = hashes.inject([]) {|r, h| r.empty? ? h.keys : r & h.keys }
  values.each do |value|
    @data[out][value] = hashes.inject(0) {|n, h| n + h[value].to_i }
  end

  @data[out].size
end

#zrange(key, start, stop, with_scores = nil) ⇒ Object



779
780
781
782
783
784
785
786
787
788
# File 'lib/redis/connection/memory.rb', line 779

def zrange(key, start, stop, with_scores = nil)
  data_type_check(key, ZSet)
  return [] unless @data[key]

  if with_scores
    @data[key].sort_by {|_,v| v }
  else
    @data[key].keys.sort_by {|k| @data[key][k] }
  end[start..stop].flatten.map(&:to_s)
end

#zrangebyscore(key, min, max, *opts) ⇒ Object



801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
# File 'lib/redis/connection/memory.rb', line 801

def zrangebyscore(key, min, max, *opts)
  data_type_check(key, ZSet)
  return [] unless @data[key]

  range = zrange_select_by_score(key, min, max)
  vals = if opts.include?('WITHSCORES')
    range.sort_by {|_,v| v }
  else
    range.keys.sort_by {|k| range[k] }
  end

  limit = get_limit(opts, vals)
  vals = vals[*limit] if limit

  vals.flatten.map(&:to_s)
end

#zrank(key, value) ⇒ Object



769
770
771
772
# File 'lib/redis/connection/memory.rb', line 769

def zrank(key, value)
  data_type_check(key, ZSet)
  @data[key].keys.sort_by {|k| @data[key][k] }.index(value.to_s)
end

#zrem(key, value) ⇒ Object



737
738
739
740
741
742
743
# File 'lib/redis/connection/memory.rb', line 737

def zrem(key, value)
  data_type_check(key, ZSet)
  exists = false
  exists = @data[key].delete(value.to_s) if @data[key]
  remove_key_for_empty_collection(key)
  !!exists
end

#zremrangebyrank(key, start, stop) ⇒ Object



868
869
870
871
872
873
874
# File 'lib/redis/connection/memory.rb', line 868

def zremrangebyrank(key, start, stop)
  sorted_elements = @data[key].sort { |(v_a, r_a), (v_b, r_b)| r_a <=> r_b }
  start = sorted_elements.length if start > sorted_elements.length
  elements_to_delete = sorted_elements[start..stop]
  elements_to_delete.each { |elem, rank| @data[key].delete(elem) }
  elements_to_delete.size
end

#zremrangebyscore(key, min, max) ⇒ Object



835
836
837
838
839
840
841
842
# File 'lib/redis/connection/memory.rb', line 835

def zremrangebyscore(key, min, max)
  data_type_check(key, ZSet)
  return 0 unless @data[key]

  range = zrange_select_by_score(key, min, max)
  range.each {|k,_| @data[key].delete(k) }
  range.size
end

#zrevrange(key, start, stop, with_scores = nil) ⇒ Object



790
791
792
793
794
795
796
797
798
799
# File 'lib/redis/connection/memory.rb', line 790

def zrevrange(key, start, stop, with_scores = nil)
  data_type_check(key, ZSet)
  return [] unless @data[key]

  if with_scores
    @data[key].sort_by {|_,v| -v }
  else
    @data[key].keys.sort_by {|k| -@data[key][k] }
  end[start..stop].flatten.map(&:to_s)
end

#zrevrangebyscore(key, max, min, *opts) ⇒ Object



818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
# File 'lib/redis/connection/memory.rb', line 818

def zrevrangebyscore(key, max, min, *opts)
  data_type_check(key, ZSet)
  return [] unless @data[key]

  range = zrange_select_by_score(key, min, max)
  vals = if opts.include?('WITHSCORES')
    range.sort_by {|_,v| -v }
  else
    range.keys.sort_by {|k| -range[k] }
  end

  limit = get_limit(opts, vals)
  vals = vals[*limit] if limit

  vals.flatten.map(&:to_s)
end

#zrevrank(key, value) ⇒ Object



774
775
776
777
# File 'lib/redis/connection/memory.rb', line 774

def zrevrank(key, value)
  data_type_check(key, ZSet)
  @data[key].keys.sort_by {|k| -@data[key][k] }.index(value.to_s)
end

#zscore(key, value) ⇒ Object



750
751
752
753
# File 'lib/redis/connection/memory.rb', line 750

def zscore(key, value)
  data_type_check(key, ZSet)
  @data[key] && @data[key][value.to_s].to_s
end