Sha256: 00ac11bb80a75052cece27798031ecb2de24de113a5749d78e89a7fc92dcc9fd

Contents?: true

Size: 1.1 KB

Versions: 6

Compression:

Stored size: 1.1 KB

Contents

require "zlib"

module ActiveRecord::Turntable::Algorithm
  class HashSlotAlgorithm < Base
    DEFAULT_HASH_FUNC = ->(key) { Zlib.crc32(key.to_s) }

    attr_reader :hash_func

    def initialize(config = {})
      super
      @hash_func = @config[:hash_func] || DEFAULT_HASH_FUNC
    end

    def choose(shard_maps, key)
      slot = slot_for_key(key, shard_maps.last.range.max)
      shard_map = shard_maps.bsearch { |shard| slot <= shard.range.max }
      raise ActiveRecord::Turntable::CannotSpecifyShardError, "cannot specify shard for key:#{key}" unless shard_map
      shard_map.shard
    end

    def choose_index(shard_maps, key)
      slot = slot_for_key(key, shard_maps.last.range.max)
      (0...shard_maps.size).bsearch { |idx| slot <= shard_maps[idx].range.max } or
        raise ActiveRecord::Turntable::CannotSpecifyShardError, "cannot specify shard for key:#{key}"
    end

    def slot_for_key(key, max)
      hash_func.call(key) % (max + 1)
    end

    def shard_weights(shard_maps, current_sequence_value)
      shard_maps.map { |shard_map| [shard_map.shard, shard_map.range.size] }.to_h
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
activerecord-turntable-4.4.1 lib/active_record/turntable/algorithm/hash_slot_algorithm.rb
activerecord-turntable-4.4.0 lib/active_record/turntable/algorithm/hash_slot_algorithm.rb
activerecord-turntable-4.3.0 lib/active_record/turntable/algorithm/hash_slot_algorithm.rb
activerecord-turntable-4.2.0 lib/active_record/turntable/algorithm/hash_slot_algorithm.rb
activerecord-turntable-4.1.0 lib/active_record/turntable/algorithm/hash_slot_algorithm.rb
activerecord-turntable-4.0.0 lib/active_record/turntable/algorithm/hash_slot_algorithm.rb