Sha256: 1fb630c36bb9e621aa6ce9af48cb1ef4603211f82677dc83e3dc1cfcc5cf18d4

Contents?: true

Size: 1.3 KB

Versions: 8

Compression:

Stored size: 1.3 KB

Contents

module FakeRedis
  module BitopCommand
    BIT_OPERATORS = {
      'or'  => :|,
      'and' => :&,
      'xor' => :'^',
      'not' => :~,
    }

    def bitop(operation, destkey, *keys)
      if result = apply(operator(operation), keys)
        set(destkey, result)
        result.length
      else
        0
      end
    rescue ArgumentError => _
      raise_argument_error('bitop')
    end

    private

    def operator(operation)
      BIT_OPERATORS[operation.to_s.downcase]
    end

    def apply(operator, keys)
      case operator
      when :~
        raise ArgumentError if keys.count != 1
        bitwise_not(keys.first)
      when :&, :|, :'^'
        raise ArgumentError if keys.empty?
        bitwise_operation(operator, keys)
      else
        raise ArgumentError
      end
    end

    def bitwise_not(key)
      if value = get(keys.first)
        value.bytes.map { |byte| ~ byte }.pack('c*')
      end
    end

    def bitwise_operation(operation, keys)
      apply_onto, *values = keys.map { |key| get(key) }.reject(&:nil?)
      values.reduce(apply_onto) do |memo, value|
        shorter, longer = [memo, value].sort_by(&:length).map(&:bytes).map(&:to_a)
        longer.each_with_index.map do |byte, index|
          byte.send(operation, shorter[index] || 0)
        end.pack('c*')
      end
    end
  end
end

Version data entries

8 entries across 8 versions & 2 rubygems

Version Path
fakeredis-0.9.2 lib/fakeredis/bitop_command.rb
fakeredis-0.9.1 lib/fakeredis/bitop_command.rb
fakeredis-0.9.0 lib/fakeredis/bitop_command.rb
fakeredis-0.8.0 lib/fakeredis/bitop_command.rb
fakeredis-0.7.0 lib/fakeredis/bitop_command.rb
kuende-fakeredis-0.10.0 lib/fakeredis/bitop_command.rb
fakeredis-0.6.0 lib/fakeredis/bitop_command.rb
kuende-fakeredis-0.6.0 lib/fakeredis/bitop_command.rb