in folly/hash/SpookyHashV2.cpp [45:156]
void SpookyHashV2::Short(
const void *message,
size_t length,
uint64_t *hash1,
uint64_t *hash2)
{
uint64_t buf[2*sc_numVars];
union
{
const uint8_t *p8;
uint32_t *p32;
uint64_t *p64;
size_t i;
} u;
u.p8 = (const uint8_t *)message;
if (!kHasUnalignedAccess && (u.i & 0x7))
{
memcpy(buf, message, length);
u.p64 = buf;
}
size_t remainder = length%32;
uint64_t a=*hash1;
uint64_t b=*hash2;
uint64_t c=sc_const;
uint64_t d=sc_const;
if (length > 15)
{
const uint64_t *end = u.p64 + (length/32)*4;
// handle all complete sets of 32 bytes
for (; u.p64 < end; u.p64 += 4)
{
c += u.p64[0];
d += u.p64[1];
ShortMix(a,b,c,d);
a += u.p64[2];
b += u.p64[3];
}
//Handle the case of 16+ remaining bytes.
if (remainder >= 16)
{
c += u.p64[0];
d += u.p64[1];
ShortMix(a,b,c,d);
u.p64 += 2;
remainder -= 16;
}
}
// Handle the last 0..15 bytes, and its length
d += ((uint64_t)length) << 56;
switch (remainder)
{
case 15:
d += ((uint64_t)u.p8[14]) << 48;
FOLLY_FALLTHROUGH;
case 14:
d += ((uint64_t)u.p8[13]) << 40;
FOLLY_FALLTHROUGH;
case 13:
d += ((uint64_t)u.p8[12]) << 32;
FOLLY_FALLTHROUGH;
case 12:
d += u.p32[2];
c += u.p64[0];
break;
case 11:
d += ((uint64_t)u.p8[10]) << 16;
FOLLY_FALLTHROUGH;
case 10:
d += ((uint64_t)u.p8[9]) << 8;
FOLLY_FALLTHROUGH;
case 9:
d += (uint64_t)u.p8[8];
FOLLY_FALLTHROUGH;
case 8:
c += u.p64[0];
break;
case 7:
c += ((uint64_t)u.p8[6]) << 48;
FOLLY_FALLTHROUGH;
case 6:
c += ((uint64_t)u.p8[5]) << 40;
FOLLY_FALLTHROUGH;
case 5:
c += ((uint64_t)u.p8[4]) << 32;
FOLLY_FALLTHROUGH;
case 4:
c += u.p32[0];
break;
case 3:
c += ((uint64_t)u.p8[2]) << 16;
FOLLY_FALLTHROUGH;
case 2:
c += ((uint64_t)u.p8[1]) << 8;
FOLLY_FALLTHROUGH;
case 1:
c += (uint64_t)u.p8[0];
break;
case 0:
c += sc_const;
d += sc_const;
}
ShortEnd(a,b,c,d);
*hash1 = a;
*hash2 = b;
}