Class: Redis::Bitops::SparseBitmap
- Defined in:
- lib/redis/bitops/sparse_bitmap.rb
Overview
A sparse bitmap using multiple key to store its data to save memory.
Note: When adding new public methods, revise the LazyEvaluation module.
Instance Method Summary collapse
-
#bitcount ⇒ Object
Returns the number of set bits.
-
#bitmap_factory ⇒ Object
Returns lambda creating SparseBitmap objects using @redis as the connection.
-
#bitop(op, *operands, result) ⇒ Object
Redis BITOP operator ‘op’ (one of :and, :or, :xor or :not) on operands (bitmaps).
- #chunk_key(i) ⇒ Object
- #chunk_keys ⇒ Object
-
#copy_to(dest) ⇒ Object
Copy this bitmap to ‘dest’ bitmap.
-
#delete! ⇒ Object
Deletes the bitmap and all its keys.
-
#initialize(root_key, redis, bytes_per_chunk = nil) ⇒ SparseBitmap
constructor
Creates a new sparse bitmap stored in ‘redis’ under ‘root_key’.
Methods inherited from Bitmap
Constructor Details
#initialize(root_key, redis, bytes_per_chunk = nil) ⇒ SparseBitmap
Creates a new sparse bitmap stored in ‘redis’ under ‘root_key’.
14 15 16 17 |
# File 'lib/redis/bitops/sparse_bitmap.rb', line 14 def initialize(root_key, redis, bytes_per_chunk = nil) @bytes_per_chunk = bytes_per_chunk || Redis::Bitops.configuration.default_bytes_per_chunk super(root_key, redis) end |
Instance Method Details
#bitcount ⇒ Object
Returns the number of set bits.
21 22 23 |
# File 'lib/redis/bitops/sparse_bitmap.rb', line 21 def bitcount chunk_keys.map { |key| @redis.bitcount(key) }.reduce(:+) || 0 end |
#bitmap_factory ⇒ Object
Returns lambda creating SparseBitmap objects using @redis as the connection.
62 63 64 |
# File 'lib/redis/bitops/sparse_bitmap.rb', line 62 def bitmap_factory lambda { |key| @redis.sparse_bitmap(key, @bytes_per_chunk) } end |
#bitop(op, *operands, result) ⇒ Object
Redis BITOP operator ‘op’ (one of :and, :or, :xor or :not) on operands (bitmaps). The result is stored in ‘result’.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/redis/bitops/sparse_bitmap.rb', line 37 def bitop(op, *operands, result) # TODO: Optimization is possible for AND. We can use an intersection of each operand # chunk numbers to minimize the number of database accesses. all_keys = self.chunk_keys + (operands.map(&:chunk_keys).flatten! || []) unique_chunk_numbers = Set.new(chunk_numbers(all_keys)) maybe_multi(level: :bitmap, watch: all_keys) do unique_chunk_numbers.each do |i| @redis.bitop(op, result.chunk_key(i), self.chunk_key(i), *operands.map { |o| o.chunk_key(i) }) end end result end |
#chunk_key(i) ⇒ Object
56 57 58 |
# File 'lib/redis/bitops/sparse_bitmap.rb', line 56 def chunk_key(i) "#{@root_key}:chunk:#{i}" end |
#chunk_keys ⇒ Object
52 53 54 |
# File 'lib/redis/bitops/sparse_bitmap.rb', line 52 def chunk_keys @redis.keys("#{@root_key}:chunk:*") end |
#copy_to(dest) ⇒ Object
Copy this bitmap to ‘dest’ bitmap.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/redis/bitops/sparse_bitmap.rb', line 68 def copy_to(dest) # Copies all source chunks to destination chunks and deletes remaining destination chunk keys. source_keys = self.chunk_keys dest_keys = dest.chunk_keys maybe_multi(level: :bitmap, watch: source_keys + dest_keys) do source_chunks = Set.new(chunk_numbers(source_keys)) source_chunks.each do |i| copy(chunk_key(i), dest.chunk_key(i)) end dest_chunks = Set.new(chunk_numbers(dest_keys)) (dest_chunks - source_chunks).each do |i| @redis.del(dest.chunk_key(i)) end end end |
#delete! ⇒ Object
Deletes the bitmap and all its keys.
27 28 29 30 31 32 |
# File 'lib/redis/bitops/sparse_bitmap.rb', line 27 def delete! chunk_keys.each do |key| @redis.del(key) end super end |