Blame jenkins_hash.c

Packit Service 584ef9
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
Packit Service 584ef9
/*
Packit Service 584ef9
 * Hash table
Packit Service 584ef9
 *
Packit Service 584ef9
 * The hash function used here is by Bob Jenkins, 1996:
Packit Service 584ef9
 *    <http://burtleburtle.net/bob/hash/doobs.html>
Packit Service 584ef9
 *       "By Bob Jenkins, 1996.  bob_jenkins@burtleburtle.net.
Packit Service 584ef9
 *       You may use this code any way you wish, private, educational,
Packit Service 584ef9
 *       or commercial.  It's free."
Packit Service 584ef9
 *
Packit Service 584ef9
 */
Packit Service 584ef9
#include "memcached.h"
Packit Service 584ef9
#include "jenkins_hash.h"
Packit Service 584ef9
Packit Service 584ef9
/*
Packit Service 584ef9
 * Since the hash function does bit manipulation, it needs to know
Packit Service 584ef9
 * whether it's big or little-endian. ENDIAN_LITTLE and ENDIAN_BIG
Packit Service 584ef9
 * are set in the configure script.
Packit Service 584ef9
 */
Packit Service 584ef9
#if ENDIAN_BIG == 1
Packit Service 584ef9
# define HASH_LITTLE_ENDIAN 0
Packit Service 584ef9
# define HASH_BIG_ENDIAN 1
Packit Service 584ef9
#else
Packit Service 584ef9
# if ENDIAN_LITTLE == 1
Packit Service 584ef9
#  define HASH_LITTLE_ENDIAN 1
Packit Service 584ef9
#  define HASH_BIG_ENDIAN 0
Packit Service 584ef9
# else
Packit Service 584ef9
#  define HASH_LITTLE_ENDIAN 0
Packit Service 584ef9
#  define HASH_BIG_ENDIAN 0
Packit Service 584ef9
# endif
Packit Service 584ef9
#endif
Packit Service 584ef9
Packit Service 584ef9
#define rot(x,k) (((x)<<(k)) ^ ((x)>>(32-(k))))
Packit Service 584ef9
Packit Service 584ef9
/*
Packit Service 584ef9
-------------------------------------------------------------------------------
Packit Service 584ef9
mix -- mix 3 32-bit values reversibly.
Packit Service 584ef9
Packit Service 584ef9
This is reversible, so any information in (a,b,c) before mix() is
Packit Service 584ef9
still in (a,b,c) after mix().
Packit Service 584ef9
Packit Service 584ef9
If four pairs of (a,b,c) inputs are run through mix(), or through
Packit Service 584ef9
mix() in reverse, there are at least 32 bits of the output that
Packit Service 584ef9
are sometimes the same for one pair and different for another pair.
Packit Service 584ef9
This was tested for:
Packit Service 584ef9
* pairs that differed by one bit, by two bits, in any combination
Packit Service 584ef9
  of top bits of (a,b,c), or in any combination of bottom bits of
Packit Service 584ef9
  (a,b,c).
Packit Service 584ef9
* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
Packit Service 584ef9
  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
Packit Service 584ef9
  is commonly produced by subtraction) look like a single 1-bit
Packit Service 584ef9
  difference.
Packit Service 584ef9
* the base values were pseudorandom, all zero but one bit set, or
Packit Service 584ef9
  all zero plus a counter that starts at zero.
Packit Service 584ef9
Packit Service 584ef9
Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
Packit Service 584ef9
satisfy this are
Packit Service 584ef9
    4  6  8 16 19  4
Packit Service 584ef9
    9 15  3 18 27 15
Packit Service 584ef9
   14  9  3  7 17  3
Packit Service 584ef9
Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
Packit Service 584ef9
for "differ" defined as + with a one-bit base and a two-bit delta.  I
Packit Service 584ef9
used http://burtleburtle.net/bob/hash/avalanche.html to choose
Packit Service 584ef9
the operations, constants, and arrangements of the variables.
Packit Service 584ef9
Packit Service 584ef9
This does not achieve avalanche.  There are input bits of (a,b,c)
Packit Service 584ef9
that fail to affect some output bits of (a,b,c), especially of a.  The
Packit Service 584ef9
most thoroughly mixed value is c, but it doesn't really even achieve
Packit Service 584ef9
avalanche in c.
Packit Service 584ef9
Packit Service 584ef9
This allows some parallelism.  Read-after-writes are good at doubling
Packit Service 584ef9
the number of bits affected, so the goal of mixing pulls in the opposite
Packit Service 584ef9
direction as the goal of parallelism.  I did what I could.  Rotates
Packit Service 584ef9
seem to cost as much as shifts on every machine I could lay my hands
Packit Service 584ef9
on, and rotates are much kinder to the top and bottom bits, so I used
Packit Service 584ef9
rotates.
Packit Service 584ef9
-------------------------------------------------------------------------------
Packit Service 584ef9
*/
Packit Service 584ef9
#define mix(a,b,c) \
Packit Service 584ef9
{ \
Packit Service 584ef9
  a -= c;  a ^= rot(c, 4);  c += b; \
Packit Service 584ef9
  b -= a;  b ^= rot(a, 6);  a += c; \
Packit Service 584ef9
  c -= b;  c ^= rot(b, 8);  b += a; \
Packit Service 584ef9
  a -= c;  a ^= rot(c,16);  c += b; \
Packit Service 584ef9
  b -= a;  b ^= rot(a,19);  a += c; \
Packit Service 584ef9
  c -= b;  c ^= rot(b, 4);  b += a; \
Packit Service 584ef9
}
Packit Service 584ef9
Packit Service 584ef9
/*
Packit Service 584ef9
-------------------------------------------------------------------------------
Packit Service 584ef9
final -- final mixing of 3 32-bit values (a,b,c) into c
Packit Service 584ef9
Packit Service 584ef9
Pairs of (a,b,c) values differing in only a few bits will usually
Packit Service 584ef9
produce values of c that look totally different.  This was tested for
Packit Service 584ef9
* pairs that differed by one bit, by two bits, in any combination
Packit Service 584ef9
  of top bits of (a,b,c), or in any combination of bottom bits of
Packit Service 584ef9
  (a,b,c).
Packit Service 584ef9
* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
Packit Service 584ef9
  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
Packit Service 584ef9
  is commonly produced by subtraction) look like a single 1-bit
Packit Service 584ef9
  difference.
Packit Service 584ef9
* the base values were pseudorandom, all zero but one bit set, or
Packit Service 584ef9
  all zero plus a counter that starts at zero.
Packit Service 584ef9
Packit Service 584ef9
These constants passed:
Packit Service 584ef9
 14 11 25 16 4 14 24
Packit Service 584ef9
 12 14 25 16 4 14 24
Packit Service 584ef9
and these came close:
Packit Service 584ef9
  4  8 15 26 3 22 24
Packit Service 584ef9
 10  8 15 26 3 22 24
Packit Service 584ef9
 11  8 15 26 3 22 24
Packit Service 584ef9
-------------------------------------------------------------------------------
Packit Service 584ef9
*/
Packit Service 584ef9
#define final(a,b,c) \
Packit Service 584ef9
{ \
Packit Service 584ef9
  c ^= b; c -= rot(b,14); \
Packit Service 584ef9
  a ^= c; a -= rot(c,11); \
Packit Service 584ef9
  b ^= a; b -= rot(a,25); \
Packit Service 584ef9
  c ^= b; c -= rot(b,16); \
Packit Service 584ef9
  a ^= c; a -= rot(c,4);  \
Packit Service 584ef9
  b ^= a; b -= rot(a,14); \
Packit Service 584ef9
  c ^= b; c -= rot(b,24); \
Packit Service 584ef9
}
Packit Service 584ef9
Packit Service 584ef9
#if HASH_LITTLE_ENDIAN == 1
Packit Service 584ef9
uint32_t jenkins_hash(
Packit Service 584ef9
  const void *key,       /* the key to hash */
Packit Service 584ef9
  size_t      length)    /* length of the key */
Packit Service 584ef9
{
Packit Service 584ef9
  uint32_t a,b,c;                                          /* internal state */
Packit Service 584ef9
  union { const void *ptr; size_t i; } u;     /* needed for Mac Powerbook G4 */
Packit Service 584ef9
Packit Service 584ef9
  /* Set up the internal state */
Packit Service 584ef9
  a = b = c = 0xdeadbeef + ((uint32_t)length) + 0;
Packit Service 584ef9
Packit Service 584ef9
  u.ptr = key;
Packit Service 584ef9
  if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
Packit Service 584ef9
    const uint32_t *k = key;                           /* read 32-bit chunks */
Packit Service 584ef9
#ifdef VALGRIND
Packit Service 584ef9
    const uint8_t  *k8;
Packit Service 584ef9
#endif /* ifdef VALGRIND */
Packit Service 584ef9
Packit Service 584ef9
    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
Packit Service 584ef9
    while (length > 12)
Packit Service 584ef9
    {
Packit Service 584ef9
      a += k[0];
Packit Service 584ef9
      b += k[1];
Packit Service 584ef9
      c += k[2];
Packit Service 584ef9
      mix(a,b,c);
Packit Service 584ef9
      length -= 12;
Packit Service 584ef9
      k += 3;
Packit Service 584ef9
    }
Packit Service 584ef9
Packit Service 584ef9
    /*----------------------------- handle the last (probably partial) block */
Packit Service 584ef9
    /*
Packit Service 584ef9
     * "k[2]&0xffffff" actually reads beyond the end of the string, but
Packit Service 584ef9
     * then masks off the part it's not allowed to read.  Because the
Packit Service 584ef9
     * string is aligned, the masked-off tail is in the same word as the
Packit Service 584ef9
     * rest of the string.  Every machine with memory protection I've seen
Packit Service 584ef9
     * does it on word boundaries, so is OK with this.  But VALGRIND will
Packit Service 584ef9
     * still catch it and complain.  The masking trick does make the hash
Packit Service 584ef9
     * noticeably faster for short strings (like English words).
Packit Service 584ef9
     */
Packit Service 584ef9
#ifndef VALGRIND
Packit Service 584ef9
Packit Service 584ef9
    switch(length)
Packit Service 584ef9
    {
Packit Service 584ef9
    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 8 : b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
Packit Service 584ef9
    case 6 : b+=k[1]&0xffff; a+=k[0]; break;
Packit Service 584ef9
    case 5 : b+=k[1]&0xff; a+=k[0]; break;
Packit Service 584ef9
    case 4 : a+=k[0]; break;
Packit Service 584ef9
    case 3 : a+=k[0]&0xffffff; break;
Packit Service 584ef9
    case 2 : a+=k[0]&0xffff; break;
Packit Service 584ef9
    case 1 : a+=k[0]&0xff; break;
Packit Service 584ef9
    case 0 : return c;  /* zero length strings require no mixing */
Packit Service 584ef9
    }
Packit Service 584ef9
Packit Service 584ef9
#else /* make valgrind happy */
Packit Service 584ef9
Packit Service 584ef9
    k8 = (const uint8_t *)k;
Packit Service 584ef9
    switch(length)
Packit Service 584ef9
    {
Packit Service 584ef9
    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 11: c+=((uint32_t)k8[10])<<16;  /* fall through */
Packit Service 584ef9
    case 10: c+=((uint32_t)k8[9])<<8;    /* fall through */
Packit Service 584ef9
    case 9 : c+=k8[8];                   /* fall through */
Packit Service 584ef9
    case 8 : b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 7 : b+=((uint32_t)k8[6])<<16;   /* fall through */
Packit Service 584ef9
    case 6 : b+=((uint32_t)k8[5])<<8;    /* fall through */
Packit Service 584ef9
    case 5 : b+=k8[4];                   /* fall through */
Packit Service 584ef9
    case 4 : a+=k[0]; break;
Packit Service 584ef9
    case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */
Packit Service 584ef9
    case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */
Packit Service 584ef9
    case 1 : a+=k8[0]; break;
Packit Service 584ef9
    case 0 : return c;  /* zero length strings require no mixing */
Packit Service 584ef9
    }
Packit Service 584ef9
Packit Service 584ef9
#endif /* !valgrind */
Packit Service 584ef9
Packit Service 584ef9
  } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
Packit Service 584ef9
    const uint16_t *k = key;                           /* read 16-bit chunks */
Packit Service 584ef9
    const uint8_t  *k8;
Packit Service 584ef9
Packit Service 584ef9
    /*--------------- all but last block: aligned reads and different mixing */
Packit Service 584ef9
    while (length > 12)
Packit Service 584ef9
    {
Packit Service 584ef9
      a += k[0] + (((uint32_t)k[1])<<16);
Packit Service 584ef9
      b += k[2] + (((uint32_t)k[3])<<16);
Packit Service 584ef9
      c += k[4] + (((uint32_t)k[5])<<16);
Packit Service 584ef9
      mix(a,b,c);
Packit Service 584ef9
      length -= 12;
Packit Service 584ef9
      k += 6;
Packit Service 584ef9
    }
Packit Service 584ef9
Packit Service 584ef9
    /*----------------------------- handle the last (probably partial) block */
Packit Service 584ef9
    k8 = (const uint8_t *)k;
Packit Service 584ef9
    switch(length)
Packit Service 584ef9
    {
Packit Service 584ef9
    case 12: c+=k[4]+(((uint32_t)k[5])<<16);
Packit Service 584ef9
             b+=k[2]+(((uint32_t)k[3])<<16);
Packit Service 584ef9
             a+=k[0]+(((uint32_t)k[1])<<16);
Packit Service 584ef9
             break;
Packit Service 584ef9
    case 11: c+=((uint32_t)k8[10])<<16;     /* @fallthrough */
Packit Service 584ef9
    case 10: c+=k[4];                       /* @fallthrough@ */
Packit Service 584ef9
             b+=k[2]+(((uint32_t)k[3])<<16);
Packit Service 584ef9
             a+=k[0]+(((uint32_t)k[1])<<16);
Packit Service 584ef9
             break;
Packit Service 584ef9
    case 9 : c+=k8[8];                      /* @fallthrough */
Packit Service 584ef9
    case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
Packit Service 584ef9
             a+=k[0]+(((uint32_t)k[1])<<16);
Packit Service 584ef9
             break;
Packit Service 584ef9
    case 7 : b+=((uint32_t)k8[6])<<16;      /* @fallthrough */
Packit Service 584ef9
    case 6 : b+=k[2];
Packit Service 584ef9
             a+=k[0]+(((uint32_t)k[1])<<16);
Packit Service 584ef9
             break;
Packit Service 584ef9
    case 5 : b+=k8[4];                      /* @fallthrough */
Packit Service 584ef9
    case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
Packit Service 584ef9
             break;
Packit Service 584ef9
    case 3 : a+=((uint32_t)k8[2])<<16;      /* @fallthrough */
Packit Service 584ef9
    case 2 : a+=k[0];
Packit Service 584ef9
             break;
Packit Service 584ef9
    case 1 : a+=k8[0];
Packit Service 584ef9
             break;
Packit Service 584ef9
    case 0 : return c;  /* zero length strings require no mixing */
Packit Service 584ef9
    }
Packit Service 584ef9
Packit Service 584ef9
  } else {                        /* need to read the key one byte at a time */
Packit Service 584ef9
    const uint8_t *k = key;
Packit Service 584ef9
Packit Service 584ef9
    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
Packit Service 584ef9
    while (length > 12)
Packit Service 584ef9
    {
Packit Service 584ef9
      a += k[0];
Packit Service 584ef9
      a += ((uint32_t)k[1])<<8;
Packit Service 584ef9
      a += ((uint32_t)k[2])<<16;
Packit Service 584ef9
      a += ((uint32_t)k[3])<<24;
Packit Service 584ef9
      b += k[4];
Packit Service 584ef9
      b += ((uint32_t)k[5])<<8;
Packit Service 584ef9
      b += ((uint32_t)k[6])<<16;
Packit Service 584ef9
      b += ((uint32_t)k[7])<<24;
Packit Service 584ef9
      c += k[8];
Packit Service 584ef9
      c += ((uint32_t)k[9])<<8;
Packit Service 584ef9
      c += ((uint32_t)k[10])<<16;
Packit Service 584ef9
      c += ((uint32_t)k[11])<<24;
Packit Service 584ef9
      mix(a,b,c);
Packit Service 584ef9
      length -= 12;
Packit Service 584ef9
      k += 12;
Packit Service 584ef9
    }
Packit Service 584ef9
Packit Service 584ef9
    /*-------------------------------- last block: affect all 32 bits of (c) */
Packit Service 584ef9
    switch(length)                   /* all the case statements fall through */
Packit Service 584ef9
    {
Packit Service 584ef9
    case 12: c+=((uint32_t)k[11])<<24;
Packit Service 584ef9
    case 11: c+=((uint32_t)k[10])<<16;
Packit Service 584ef9
    case 10: c+=((uint32_t)k[9])<<8;
Packit Service 584ef9
    case 9 : c+=k[8];
Packit Service 584ef9
    case 8 : b+=((uint32_t)k[7])<<24;
Packit Service 584ef9
    case 7 : b+=((uint32_t)k[6])<<16;
Packit Service 584ef9
    case 6 : b+=((uint32_t)k[5])<<8;
Packit Service 584ef9
    case 5 : b+=k[4];
Packit Service 584ef9
    case 4 : a+=((uint32_t)k[3])<<24;
Packit Service 584ef9
    case 3 : a+=((uint32_t)k[2])<<16;
Packit Service 584ef9
    case 2 : a+=((uint32_t)k[1])<<8;
Packit Service 584ef9
    case 1 : a+=k[0];
Packit Service 584ef9
             break;
Packit Service 584ef9
    case 0 : return c;  /* zero length strings require no mixing */
Packit Service 584ef9
    }
Packit Service 584ef9
  }
Packit Service 584ef9
Packit Service 584ef9
  final(a,b,c);
Packit Service 584ef9
  return c;             /* zero length strings require no mixing */
Packit Service 584ef9
}
Packit Service 584ef9
Packit Service 584ef9
#elif HASH_BIG_ENDIAN == 1
Packit Service 584ef9
/*
Packit Service 584ef9
 * hashbig():
Packit Service 584ef9
 * This is the same as hashword() on big-endian machines.  It is different
Packit Service 584ef9
 * from hashlittle() on all machines.  hashbig() takes advantage of
Packit Service 584ef9
 * big-endian byte ordering.
Packit Service 584ef9
 */
Packit Service 584ef9
uint32_t jenkins_hash( const void *key, size_t length)
Packit Service 584ef9
{
Packit Service 584ef9
  uint32_t a,b,c;
Packit Service 584ef9
  union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */
Packit Service 584ef9
Packit Service 584ef9
  /* Set up the internal state */
Packit Service 584ef9
  a = b = c = 0xdeadbeef + ((uint32_t)length) + 0;
Packit Service 584ef9
Packit Service 584ef9
  u.ptr = key;
Packit Service 584ef9
  if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) {
Packit Service 584ef9
    const uint32_t *k = key;                           /* read 32-bit chunks */
Packit Service 584ef9
#ifdef VALGRIND
Packit Service 584ef9
    const uint8_t  *k8;
Packit Service 584ef9
#endif /* ifdef VALGRIND */
Packit Service 584ef9
Packit Service 584ef9
    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
Packit Service 584ef9
    while (length > 12)
Packit Service 584ef9
    {
Packit Service 584ef9
      a += k[0];
Packit Service 584ef9
      b += k[1];
Packit Service 584ef9
      c += k[2];
Packit Service 584ef9
      mix(a,b,c);
Packit Service 584ef9
      length -= 12;
Packit Service 584ef9
      k += 3;
Packit Service 584ef9
    }
Packit Service 584ef9
Packit Service 584ef9
    /*----------------------------- handle the last (probably partial) block */
Packit Service 584ef9
    /*
Packit Service 584ef9
     * "k[2]<<8" actually reads beyond the end of the string, but
Packit Service 584ef9
     * then shifts out the part it's not allowed to read.  Because the
Packit Service 584ef9
     * string is aligned, the illegal read is in the same word as the
Packit Service 584ef9
     * rest of the string.  Every machine with memory protection I've seen
Packit Service 584ef9
     * does it on word boundaries, so is OK with this.  But VALGRIND will
Packit Service 584ef9
     * still catch it and complain.  The masking trick does make the hash
Packit Service 584ef9
     * noticeably faster for short strings (like English words).
Packit Service 584ef9
     */
Packit Service 584ef9
#ifndef VALGRIND
Packit Service 584ef9
Packit Service 584ef9
    switch(length)
Packit Service 584ef9
    {
Packit Service 584ef9
    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 8 : b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 7 : b+=k[1]&0xffffff00; a+=k[0]; break;
Packit Service 584ef9
    case 6 : b+=k[1]&0xffff0000; a+=k[0]; break;
Packit Service 584ef9
    case 5 : b+=k[1]&0xff000000; a+=k[0]; break;
Packit Service 584ef9
    case 4 : a+=k[0]; break;
Packit Service 584ef9
    case 3 : a+=k[0]&0xffffff00; break;
Packit Service 584ef9
    case 2 : a+=k[0]&0xffff0000; break;
Packit Service 584ef9
    case 1 : a+=k[0]&0xff000000; break;
Packit Service 584ef9
    case 0 : return c;              /* zero length strings require no mixing */
Packit Service 584ef9
    }
Packit Service 584ef9
Packit Service 584ef9
#else  /* make valgrind happy */
Packit Service 584ef9
Packit Service 584ef9
    k8 = (const uint8_t *)k;
Packit Service 584ef9
    switch(length)                   /* all the case statements fall through */
Packit Service 584ef9
    {
Packit Service 584ef9
    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 11: c+=((uint32_t)k8[10])<<8;  /* fall through */
Packit Service 584ef9
    case 10: c+=((uint32_t)k8[9])<<16;  /* fall through */
Packit Service 584ef9
    case 9 : c+=((uint32_t)k8[8])<<24;  /* fall through */
Packit Service 584ef9
    case 8 : b+=k[1]; a+=k[0]; break;
Packit Service 584ef9
    case 7 : b+=((uint32_t)k8[6])<<8;   /* fall through */
Packit Service 584ef9
    case 6 : b+=((uint32_t)k8[5])<<16;  /* fall through */
Packit Service 584ef9
    case 5 : b+=((uint32_t)k8[4])<<24;  /* fall through */
Packit Service 584ef9
    case 4 : a+=k[0]; break;
Packit Service 584ef9
    case 3 : a+=((uint32_t)k8[2])<<8;   /* fall through */
Packit Service 584ef9
    case 2 : a+=((uint32_t)k8[1])<<16;  /* fall through */
Packit Service 584ef9
    case 1 : a+=((uint32_t)k8[0])<<24; break;
Packit Service 584ef9
    case 0 : return c;
Packit Service 584ef9
    }
Packit Service 584ef9
Packit Service 584ef9
#endif /* !VALGRIND */
Packit Service 584ef9
Packit Service 584ef9
  } else {                        /* need to read the key one byte at a time */
Packit Service 584ef9
    const uint8_t *k = key;
Packit Service 584ef9
Packit Service 584ef9
    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
Packit Service 584ef9
    while (length > 12)
Packit Service 584ef9
    {
Packit Service 584ef9
      a += ((uint32_t)k[0])<<24;
Packit Service 584ef9
      a += ((uint32_t)k[1])<<16;
Packit Service 584ef9
      a += ((uint32_t)k[2])<<8;
Packit Service 584ef9
      a += ((uint32_t)k[3]);
Packit Service 584ef9
      b += ((uint32_t)k[4])<<24;
Packit Service 584ef9
      b += ((uint32_t)k[5])<<16;
Packit Service 584ef9
      b += ((uint32_t)k[6])<<8;
Packit Service 584ef9
      b += ((uint32_t)k[7]);
Packit Service 584ef9
      c += ((uint32_t)k[8])<<24;
Packit Service 584ef9
      c += ((uint32_t)k[9])<<16;
Packit Service 584ef9
      c += ((uint32_t)k[10])<<8;
Packit Service 584ef9
      c += ((uint32_t)k[11]);
Packit Service 584ef9
      mix(a,b,c);
Packit Service 584ef9
      length -= 12;
Packit Service 584ef9
      k += 12;
Packit Service 584ef9
    }
Packit Service 584ef9
Packit Service 584ef9
    /*-------------------------------- last block: affect all 32 bits of (c) */
Packit Service 584ef9
    switch(length)                   /* all the case statements fall through */
Packit Service 584ef9
    {
Packit Service 584ef9
    case 12: c+=k[11];
Packit Service 584ef9
    case 11: c+=((uint32_t)k[10])<<8;
Packit Service 584ef9
    case 10: c+=((uint32_t)k[9])<<16;
Packit Service 584ef9
    case 9 : c+=((uint32_t)k[8])<<24;
Packit Service 584ef9
    case 8 : b+=k[7];
Packit Service 584ef9
    case 7 : b+=((uint32_t)k[6])<<8;
Packit Service 584ef9
    case 6 : b+=((uint32_t)k[5])<<16;
Packit Service 584ef9
    case 5 : b+=((uint32_t)k[4])<<24;
Packit Service 584ef9
    case 4 : a+=k[3];
Packit Service 584ef9
    case 3 : a+=((uint32_t)k[2])<<8;
Packit Service 584ef9
    case 2 : a+=((uint32_t)k[1])<<16;
Packit Service 584ef9
    case 1 : a+=((uint32_t)k[0])<<24;
Packit Service 584ef9
             break;
Packit Service 584ef9
    case 0 : return c;
Packit Service 584ef9
    }
Packit Service 584ef9
  }
Packit Service 584ef9
Packit Service 584ef9
  final(a,b,c);
Packit Service 584ef9
  return c;
Packit Service 584ef9
}
Packit Service 584ef9
#else /* HASH_XXX_ENDIAN == 1 */
Packit Service 584ef9
#error Must define HASH_BIG_ENDIAN or HASH_LITTLE_ENDIAN
Packit Service 584ef9
#endif /* HASH_XXX_ENDIAN == 1 */