class Murmur

only usefull to hash strings

Public Class Methods

Hash64A(key) click to toggle source

64bit processors

# File lib/blobsterix/helper/murmur.rb, line 28
def self.Hash64A (key)
  len = key.size
  seed = 11

  m = 0xc6a4a7935bd1e995
  r = 47

  h = seed ^ len;

  data = String.new(key)

  while len >= 8
    k = data.slice!(0..7).unpack("Q")[0]

    k = force_overflow_unsigned_64(k * m)
    k ^= k >> r
    k = force_overflow_unsigned_64(k * m)

    h ^= k;
    h = force_overflow_unsigned_64(h * m)

    len-=8
  end

  h ^= data.slice(6).to_i << 48 if len == 7
  h ^= data.slice(5).to_i << 40 if len >= 6
  h ^= data.slice(4).to_i << 32 if len >= 5
  h ^= data.slice(3).to_i << 24 if len >= 4
  h ^= data.slice(2).to_i << 16 if len >= 3
  h ^= data.slice(1).to_i << 8 if len >= 2
  h ^= data.slice(0).to_i if len >= 1

  h = force_overflow_unsigned_64(h * m) if len

  h ^= h >> r
  h = force_overflow_unsigned_64(h * m)
  h ^= h >> r

  h
end
Hash64B(key) click to toggle source

32bit processors

# File lib/blobsterix/helper/murmur.rb, line 75
def self.Hash64B(key)
  len = key.size
  seed = 11

  m = 0x5bd1e995 #1540483477
  r = 24

  h1 = seed ^ len
  h2 = 0

  data = String.new(key)#.force_encoding('ASCII-8BIT')
  
  while len >= 8
    k1 = data.slice!(0..3).unpack("I")[0]

    k1 = force_overflow_unsigned(k1 * m)
    k1 ^= k1 >> r

    k1 = force_overflow_unsigned(k1 * m)
    h1 = force_overflow_unsigned(h1 * m)

    h1 ^= k1
    len -= 4


    k2 = data.slice!(0..3).unpack("I")[0]

    k2 = force_overflow_unsigned(k2 * m)
    k2 ^= k2 >> r

    k2 = force_overflow_unsigned(k2 * m)
    h2 = force_overflow_unsigned(h2 * m)

    h2 ^= k2
    len -= 4
  end

  if len >= 4
    k1 = data.slice!(0..3).unpack("I")[0]

    k1 = force_overflow_unsigned(k1 * m)
    k1 ^= k1 >> r

    k1 = force_overflow_unsigned(k1 * m)
    h1 = force_overflow_unsigned(h1 * m)

    h1 ^= k1
    len -= 4
  end

  h2 ^= (get_num(data[2]) << 16) if len == 3
  h2 ^= (get_num(data[1]) << 8).to_i if len >= 2
  h2 ^= (get_num(data[0])) if len >= 1

  h2 = force_overflow_unsigned(h2 * m) if len > 0

  h1 ^= h2 >> 18
  h1 = force_overflow_unsigned(h1 * m)

  h2 ^= h1 >> 22
  h2 = force_overflow_unsigned(h2 * m)

  h1 ^= h2 >> 17
  h1 = force_overflow_unsigned(h1 * m)

  h = h1
  h = (h << 32) | h2

  h
end
force_overflow_signed(i) click to toggle source
# File lib/blobsterix/helper/murmur.rb, line 3
def self.force_overflow_signed(i)
  force_overflow_unsigned(i + 2**31) - 2**31
end
force_overflow_unsigned(i) click to toggle source
# File lib/blobsterix/helper/murmur.rb, line 19
def self.force_overflow_unsigned(i)
  i % 2**32   # or equivalently: i & 0xffffffff
end
force_overflow_unsigned_16(i) click to toggle source
# File lib/blobsterix/helper/murmur.rb, line 7
def self.force_overflow_unsigned_16(i)
  i % 2**16   # or equivalently: i & 0xffffffff
end
force_overflow_unsigned_18(i) click to toggle source
# File lib/blobsterix/helper/murmur.rb, line 11
def self.force_overflow_unsigned_18(i)
  i % 2**18   # or equivalently: i & 0xffffffff
end
force_overflow_unsigned_20(i) click to toggle source
# File lib/blobsterix/helper/murmur.rb, line 15
def self.force_overflow_unsigned_20(i)
  i % 2**20   # or equivalently: i & 0xffffffff
end
force_overflow_unsigned_64(i) click to toggle source
# File lib/blobsterix/helper/murmur.rb, line 23
def self.force_overflow_unsigned_64(i)
  i % 2**64   # or equivalently: i & 0xffffffff
end
get_num(num) click to toggle source
# File lib/blobsterix/helper/murmur.rb, line 69
def self.get_num(num)
  return num if num.class == Fixnum
  num.to_s.unpack("C")[0]
end
map_filename(filename, *additional) click to toggle source
# File lib/blobsterix/helper/murmur.rb, line 146
def self.map_filename(filename, *additional)
  hash = Murmur.force_overflow_unsigned_20(Murmur.Hash64B(filename))
  bits =  hash.to_s(2)
  parts = []
  2.times { |index|
    len = 10
    len = bits.length if len >= bits.length
    value = bits.slice!(0, len).to_i(2).to_s(16).rjust(3,"0")
    parts.push(value)
  }
  parts = parts+additional
  parts.join("/")
end