in util-hashing/src/main/scala/com/twitter/hashing/Hashable.scala [246:311]
def apply(key: Array[Byte]): Long = {
var a, b, c = 0xdeadbeef + key.length
def rot(x: Int, k: Int) = (((x) << (k)) | ((x) >> (32 - (k))))
def mix(): Unit = {
a -= c; a ^= rot(c, 4); c += b
b -= a; b ^= rot(a, 6); a += c
c -= b; c ^= rot(b, 8); b += a
a -= c; a ^= rot(c, 16); c += b
b -= a; b ^= rot(a, 19); a += c
c -= b; c ^= rot(b, 4); b += a
}
def fin(): Unit = {
c ^= b; c -= rot(b, 14); a ^= c; a -= rot(c, 11)
b ^= a; b -= rot(a, 25); c ^= b; c -= rot(b, 16)
a ^= c; a -= rot(c, 4); b ^= a; b -= rot(a, 14)
c ^= b; c -= rot(b, 24)
}
var block = 0
val numBlocks = (key.length - 1) / 12
while (block < numBlocks) {
val offset = block * 12
a += key(offset)
a += key(offset + 1) << 8
a += key(offset + 2) << 16
a += key(offset + 3) << 24
b += key(offset + 4)
b += key(offset + 5) << 8
b += key(offset + 6) << 16
b += key(offset + 7) << 24
c += key(offset + 8)
c += key(offset + 9) << 8
c += key(offset + 10) << 16
c += key(offset + 11) << 24
mix()
block += 1
}
val remaining = key.length - (numBlocks * 12)
val offset = numBlocks * 12
if (remaining > 0) a += key(offset)
if (remaining > 1) a += key(offset + 1) << 8
if (remaining > 2) a += key(offset + 2) << 16
if (remaining > 3) a += key(offset + 3) << 24
if (remaining > 4) b += key(offset + 4)
if (remaining > 5) b += key(offset + 5) << 8
if (remaining > 6) b += key(offset + 6) << 16
if (remaining > 7) b += key(offset + 7) << 24
if (remaining > 8) c += key(offset + 8)
if (remaining > 9) c += key(offset + 9) << 8
if (remaining > 10) c += key(offset + 10) << 16
if (remaining > 11) c += key(offset + 11) << 24
if (key.length > 0) fin()
(b.toLong << 32) + c.toLong
}