rpm  5.4.4
rpmio/lookup3.c
Go to the documentation of this file.
00001 /* -------------------------------------------------------------------- */
00002 /*
00003  * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
00004  * 
00005  * These are functions for producing 32-bit hashes for hash table lookup.
00006  * jlu32w(), jlu32l(), jlu32lpair(), jlu32b(), _JLU3_MIX(), and _JLU3_FINAL() 
00007  * are externally useful functions.  Routines to test the hash are included 
00008  * if SELF_TEST is defined.  You can use this free for any purpose.  It's in
00009  * the public domain.  It has no warranty.
00010  * 
00011  * You probably want to use jlu32l().  jlu32l() and jlu32b()
00012  * hash byte arrays.  jlu32l() is is faster than jlu32b() on
00013  * little-endian machines.  Intel and AMD are little-endian machines.
00014  * On second thought, you probably want jlu32lpair(), which is identical to
00015  * jlu32l() except it returns two 32-bit hashes for the price of one.  
00016  * You could implement jlu32bpair() if you wanted but I haven't bothered here.
00017  * 
00018  * If you want to find a hash of, say, exactly 7 integers, do
00019  *   a = i1;  b = i2;  c = i3;
00020  *   _JLU3_MIX(a,b,c);
00021  *   a += i4; b += i5; c += i6;
00022  *   _JLU3_MIX(a,b,c);
00023  *   a += i7;
00024  *   _JLU3_FINAL(a,b,c);
00025  * then use c as the hash value.  If you have a variable size array of
00026  * 4-byte integers to hash, use jlu32w().  If you have a byte array (like
00027  * a character string), use jlu32l().  If you have several byte arrays, or
00028  * a mix of things, see the comments above jlu32l().  
00029  * 
00030  * Why is this so big?  I read 12 bytes at a time into 3 4-byte integers, 
00031  * then mix those integers.  This is fast (you can do a lot more thorough
00032  * mixing with 12*3 instructions on 3 integers than you can with 3 instructions
00033  * on 1 byte), but shoehorning those bytes into integers efficiently is messy.
00034 */
00035 /* -------------------------------------------------------------------- */
00036 
00037 #include "system.h"
00038 #include "rpmiotypes.h"
00039 #include "debug.h"
00040 
00041 #undef  UNLIKELY
00042 #ifdef WITH_VALGRIND
00043 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
00044 #  define UNLIKELY(value) __builtin_expect((value), 0) && (value > 0 || (value = RUNNING_ON_VALGRIND))
00045 #else
00046 #  define UNLIKELY(value) (value) && (value > 0 || (value = RUNNING_ON_VALGRIND))
00047 #endif
00048 static int _running_on_valgrind = -1;
00049 #endif
00050 
00051 #if defined(_JLU3_SELFTEST)
00052 # define _JLU3_jlu32w           1
00053 # define _JLU3_jlu32l           1
00054 # define _JLU3_jlu32lpair       1
00055 # define _JLU3_jlu32b           1
00056 #endif
00057 
00058 /*@-redef@*/
00059 /*@unchecked@*/
00060 static const union _dbswap {
00061     const rpmuint32_t ui;
00062     const unsigned char uc[4];
00063 } endian = { .ui = 0x11223344 };
00064 # define HASH_LITTLE_ENDIAN     (endian.uc[0] == (unsigned char) 0x44)
00065 # define HASH_BIG_ENDIAN        (endian.uc[0] == (unsigned char) 0x11)
00066 /*@=redef@*/
00067 
00068 #ifndef ROTL32
00069 # define ROTL32(x, s) (((x) << (s)) | ((x) >> (32 - (s))))
00070 #endif
00071 
00072 /* NOTE: The _size parameter should be in bytes. */
00073 #define _JLU3_INIT(_h, _size)   (0xdeadbeef + ((rpmuint32_t)(_size)) + (_h))
00074 
00075 /* -------------------------------------------------------------------- */
00076 /*
00077  * _JLU3_MIX -- mix 3 32-bit values reversibly.
00078  * 
00079  * This is reversible, so any information in (a,b,c) before _JLU3_MIX() is
00080  * still in (a,b,c) after _JLU3_MIX().
00081  * 
00082  * If four pairs of (a,b,c) inputs are run through _JLU3_MIX(), or through
00083  * _JLU3_MIX() in reverse, there are at least 32 bits of the output that
00084  * are sometimes the same for one pair and different for another pair.
00085  * This was tested for:
00086  * * pairs that differed by one bit, by two bits, in any combination
00087  *   of top bits of (a,b,c), or in any combination of bottom bits of
00088  *   (a,b,c).
00089  * * "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
00090  *   the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
00091  *   is commonly produced by subtraction) look like a single 1-bit
00092  *   difference.
00093  * * the base values were pseudorandom, all zero but one bit set, or 
00094  *   all zero plus a counter that starts at zero.
00095  * 
00096  * Some k values for my "a-=c; a^=ROTL32(c,k); c+=b;" arrangement that
00097  * satisfy this are
00098  *     4  6  8 16 19  4
00099  *     9 15  3 18 27 15
00100  *    14  9  3  7 17  3
00101  * Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
00102  * for "differ" defined as + with a one-bit base and a two-bit delta.  I
00103  * used http://burtleburtle.net/bob/hash/avalanche.html to choose 
00104  * the operations, constants, and arrangements of the variables.
00105  * 
00106  * This does not achieve avalanche.  There are input bits of (a,b,c)
00107  * that fail to affect some output bits of (a,b,c), especially of a.  The
00108  * most thoroughly mixed value is c, but it doesn't really even achieve
00109  * avalanche in c.
00110  * 
00111  * This allows some parallelism.  Read-after-writes are good at doubling
00112  * the number of bits affected, so the goal of mixing pulls in the opposite
00113  * direction as the goal of parallelism.  I did what I could.  Rotates
00114  * seem to cost as much as shifts on every machine I could lay my hands
00115  * on, and rotates are much kinder to the top and bottom bits, so I used
00116  * rotates.
00117  */
00118 /* -------------------------------------------------------------------- */
00119 #define _JLU3_MIX(a,b,c) \
00120 { \
00121   a -= c;  a ^= ROTL32(c, 4);  c += b; \
00122   b -= a;  b ^= ROTL32(a, 6);  a += c; \
00123   c -= b;  c ^= ROTL32(b, 8);  b += a; \
00124   a -= c;  a ^= ROTL32(c,16);  c += b; \
00125   b -= a;  b ^= ROTL32(a,19);  a += c; \
00126   c -= b;  c ^= ROTL32(b, 4);  b += a; \
00127 }
00128 
00129 /* -------------------------------------------------------------------- */
00153 /* -------------------------------------------------------------------- */
00154 #define _JLU3_FINAL(a,b,c) \
00155 { \
00156   c ^= b; c -= ROTL32(b,14); \
00157   a ^= c; a -= ROTL32(c,11); \
00158   b ^= a; b -= ROTL32(a,25); \
00159   c ^= b; c -= ROTL32(b,16); \
00160   a ^= c; a -= ROTL32(c,4);  \
00161   b ^= a; b -= ROTL32(a,14); \
00162   c ^= b; c -= ROTL32(b,24); \
00163 }
00164 
00165 #if defined(_JLU3_jlu32w)
00166 rpmuint32_t jlu32w(rpmuint32_t h, /*@null@*/ const rpmuint32_t *k, size_t size)
00167         /*@*/;
00168 /* -------------------------------------------------------------------- */
00185 /* -------------------------------------------------------------------- */
00186 rpmuint32_t jlu32w(rpmuint32_t h, const rpmuint32_t *k, size_t size)
00187 {
00188     rpmuint32_t a = _JLU3_INIT(h, (size * sizeof(*k)));
00189     rpmuint32_t b = a;
00190     rpmuint32_t c = a;
00191 
00192     if (k == NULL)
00193         goto exit;
00194 
00195     /*----------------------------------------------- handle most of the key */
00196     while (size > 3) {
00197         a += k[0];
00198         b += k[1];
00199         c += k[2];
00200         _JLU3_MIX(a,b,c);
00201         size -= 3;
00202         k += 3;
00203     }
00204 
00205     /*----------------------------------------- handle the last 3 rpmuint32_t's */
00206     switch (size) {
00207     case 3 : c+=k[2];
00208     case 2 : b+=k[1];
00209     case 1 : a+=k[0];
00210         _JLU3_FINAL(a,b,c);
00211         /*@fallthrough@*/
00212     case 0:
00213         break;
00214     }
00215     /*---------------------------------------------------- report the result */
00216 exit:
00217     return c;
00218 }
00219 #endif  /* defined(_JLU3_jlu32w) */
00220 
00221 #if defined(_JLU3_jlu32l)
00222 rpmuint32_t jlu32l(rpmuint32_t h, const void *key, size_t size)
00223         /*@*/;
00224 /* -------------------------------------------------------------------- */
00225 /*
00226  * jlu32l() -- hash a variable-length key into a 32-bit value
00227  *   h       : can be any 4-byte value
00228  *   k       : the key (the unaligned variable-length array of bytes)
00229  *   size    : the size of the key, counting by bytes
00230  * Returns a 32-bit value.  Every bit of the key affects every bit of
00231  * the return value.  Two keys differing by one or two bits will have
00232  * totally different hash values.
00233  * 
00234  * The best hash table sizes are powers of 2.  There is no need to do
00235  * mod a prime (mod is sooo slow!).  If you need less than 32 bits,
00236  * use a bitmask.  For example, if you need only 10 bits, do
00237  *   h = (h & hashmask(10));
00238  * In which case, the hash table should have hashsize(10) elements.
00239  * 
00240  * If you are hashing n strings (rpmuint8_t **)k, do it like this:
00241  *   for (i=0, h=0; i<n; ++i) h = jlu32l(h, k[i], len[i]);
00242  * 
00243  * By Bob Jenkins, 2006.  bob_jenkins@burtleburtle.net.  You may use this
00244  * code any way you wish, private, educational, or commercial.  It's free.
00245  * 
00246  * Use for hash table lookup, or anything where one collision in 2^^32 is
00247  * acceptable.  Do NOT use for cryptographic purposes.
00248  *
00249  * @param h             the previous hash, or an arbitrary value
00250  * @param *k            the key, an array of rpmuint8_t values
00251  * @param size          the size of the key
00252  * @return              the lookup3 hash
00253  */
00254 /* -------------------------------------------------------------------- */
00255 rpmuint32_t jlu32l(rpmuint32_t h, const void *key, size_t size)
00256 {
00257     union { const void *ptr; size_t i; } u;
00258     rpmuint32_t a = _JLU3_INIT(h, size);
00259     rpmuint32_t b = a;
00260     rpmuint32_t c = a;
00261 
00262     if (key == NULL)
00263         goto exit;
00264 
00265     u.ptr = key;
00266     if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
00267         const rpmuint32_t *k = (const rpmuint32_t *)key;        /* read 32-bit chunks */
00268 
00269     /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
00270         while (size > 12) {
00271             a += k[0];
00272             b += k[1];
00273             c += k[2];
00274             _JLU3_MIX(a,b,c);
00275             size -= 12;
00276             k += 3;
00277         }
00278 
00279         /*------------------------- handle the last (probably partial) block */
00280         /* 
00281          * "k[2]&0xffffff" actually reads beyond the end of the string, but
00282          * then masks off the part it's not allowed to read.  Because the
00283          * string is aligned, the masked-off tail is in the same word as the
00284          * rest of the string.  Every machine with memory protection I've seen
00285          * does it on word boundaries, so is OK with this.  But VALGRIND will
00286          * still catch it and complain.  The masking trick does make the hash
00287          * noticably faster for short strings (like English words).
00288          */
00289 #ifdef WITH_VALGRIND
00290       if (UNLIKELY(_running_on_valgrind)) {
00291         const rpmuint8_t  * k8 = (const rpmuint8_t *)k;
00292 
00293         switch (size) {
00294         case 12:        c += k[2]; b+=k[1]; a+=k[0];    break;
00295         case 11:        c += ((rpmuint32_t)k8[10])<<16; /*@fallthrough@*/
00296         case 10:        c += ((rpmuint32_t)k8[9])<<8;   /*@fallthrough@*/
00297         case  9:        c += k8[8];                     /*@fallthrough@*/
00298         case  8:        b += k[1]; a+=k[0];             break;
00299         case  7:        b += ((rpmuint32_t)k8[6])<<16;  /*@fallthrough@*/
00300         case  6:        b += ((rpmuint32_t)k8[5])<<8;   /*@fallthrough@*/
00301         case  5:        b += k8[4];                     /*@fallthrough@*/
00302         case  4:        a += k[0];                      break;
00303         case  3:        a += ((rpmuint32_t)k8[2])<<16;  /*@fallthrough@*/
00304         case  2:        a += ((rpmuint32_t)k8[1])<<8;   /*@fallthrough@*/
00305         case  1:        a += k8[0];                     break;
00306         case  0:        goto exit;
00307         }
00308 
00309       } else
00310 #endif
00311       {
00312         switch (size) {
00313         case 12:        c += k[2]; b+=k[1]; a+=k[0]; break;
00314         case 11:        c += k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
00315         case 10:        c += k[2]&0xffff; b+=k[1]; a+=k[0]; break;
00316         case  9:        c += k[2]&0xff; b+=k[1]; a+=k[0]; break;
00317         case  8:        b += k[1]; a+=k[0]; break;
00318         case  7:        b += k[1]&0xffffff; a+=k[0]; break;
00319         case  6:        b += k[1]&0xffff; a+=k[0]; break;
00320         case  5:        b += k[1]&0xff; a+=k[0]; break;
00321         case  4:        a += k[0]; break;
00322         case  3:        a += k[0]&0xffffff; break;
00323         case  2:        a += k[0]&0xffff; break;
00324         case  1:        a += k[0]&0xff; break;
00325         case  0:        goto exit;
00326         }
00327       }
00328     } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
00329         const rpmuint16_t *k = (const rpmuint16_t *)key;        /* read 16-bit chunks */
00330         const rpmuint8_t  *k8;
00331 
00332         /*----------- all but last block: aligned reads and different mixing */
00333         while (size > 12) {
00334             a += k[0] + (((rpmuint32_t)k[1])<<16);
00335             b += k[2] + (((rpmuint32_t)k[3])<<16);
00336             c += k[4] + (((rpmuint32_t)k[5])<<16);
00337             _JLU3_MIX(a,b,c);
00338             size -= 12;
00339             k += 6;
00340         }
00341 
00342         /*------------------------- handle the last (probably partial) block */
00343         k8 = (const rpmuint8_t *)k;
00344         switch (size) {
00345         case 12:
00346             c += k[4]+(((rpmuint32_t)k[5])<<16);
00347             b += k[2]+(((rpmuint32_t)k[3])<<16);
00348             a += k[0]+(((rpmuint32_t)k[1])<<16);
00349             break;
00350         case 11:
00351             c += ((rpmuint32_t)k8[10])<<16;
00352             /*@fallthrough@*/
00353         case 10:
00354             c += (rpmuint32_t)k[4];
00355             b += k[2]+(((rpmuint32_t)k[3])<<16);
00356             a += k[0]+(((rpmuint32_t)k[1])<<16);
00357             break;
00358         case  9:
00359             c += (rpmuint32_t)k8[8];
00360             /*@fallthrough@*/
00361         case  8:
00362             b += k[2]+(((rpmuint32_t)k[3])<<16);
00363             a += k[0]+(((rpmuint32_t)k[1])<<16);
00364             break;
00365         case  7:
00366             b += ((rpmuint32_t)k8[6])<<16;
00367             /*@fallthrough@*/
00368         case  6:
00369             b += (rpmuint32_t)k[2];
00370             a += k[0]+(((rpmuint32_t)k[1])<<16);
00371             break;
00372         case  5:
00373             b += (rpmuint32_t)k8[4];
00374             /*@fallthrough@*/
00375         case  4:
00376             a += k[0]+(((rpmuint32_t)k[1])<<16);
00377             break;
00378         case  3:
00379             a += ((rpmuint32_t)k8[2])<<16;
00380             /*@fallthrough@*/
00381         case  2:
00382             a += (rpmuint32_t)k[0];
00383             break;
00384         case  1:
00385             a += (rpmuint32_t)k8[0];
00386             break;
00387         case  0:
00388             goto exit;
00389         }
00390 
00391     } else {            /* need to read the key one byte at a time */
00392         const rpmuint8_t *k = (const rpmuint8_t *)key;
00393 
00394         /*----------- all but the last block: affect some 32 bits of (a,b,c) */
00395         while (size > 12) {
00396             a += (rpmuint32_t)k[0];
00397             a += ((rpmuint32_t)k[1])<<8;
00398             a += ((rpmuint32_t)k[2])<<16;
00399             a += ((rpmuint32_t)k[3])<<24;
00400             b += (rpmuint32_t)k[4];
00401             b += ((rpmuint32_t)k[5])<<8;
00402             b += ((rpmuint32_t)k[6])<<16;
00403             b += ((rpmuint32_t)k[7])<<24;
00404             c += (rpmuint32_t)k[8];
00405             c += ((rpmuint32_t)k[9])<<8;
00406             c += ((rpmuint32_t)k[10])<<16;
00407             c += ((rpmuint32_t)k[11])<<24;
00408             _JLU3_MIX(a,b,c);
00409             size -= 12;
00410             k += 12;
00411         }
00412 
00413         /*---------------------------- last block: affect all 32 bits of (c) */
00414         switch (size) {
00415         case 12:        c += ((rpmuint32_t)k[11])<<24;  /*@fallthrough@*/
00416         case 11:        c += ((rpmuint32_t)k[10])<<16;  /*@fallthrough@*/
00417         case 10:        c += ((rpmuint32_t)k[9])<<8;    /*@fallthrough@*/
00418         case  9:        c += (rpmuint32_t)k[8];         /*@fallthrough@*/
00419         case  8:        b += ((rpmuint32_t)k[7])<<24;   /*@fallthrough@*/
00420         case  7:        b += ((rpmuint32_t)k[6])<<16;   /*@fallthrough@*/
00421         case  6:        b += ((rpmuint32_t)k[5])<<8;    /*@fallthrough@*/
00422         case  5:        b += (rpmuint32_t)k[4];         /*@fallthrough@*/
00423         case  4:        a += ((rpmuint32_t)k[3])<<24;   /*@fallthrough@*/
00424         case  3:        a += ((rpmuint32_t)k[2])<<16;   /*@fallthrough@*/
00425         case  2:        a += ((rpmuint32_t)k[1])<<8;    /*@fallthrough@*/
00426         case  1:        a += (rpmuint32_t)k[0];
00427             break;
00428         case  0:
00429             goto exit;
00430         }
00431     }
00432 
00433     _JLU3_FINAL(a,b,c);
00434 
00435 exit:
00436     return c;
00437 }
00438 #endif  /* defined(_JLU3_jlu32l) */
00439 
00440 #if defined(_JLU3_jlu32lpair)
00441 void jlu32lpair(/*@null@*/ const void *key, size_t size,
00442                 rpmuint32_t *pc, rpmuint32_t *pb)
00443         /*@modifies *pc, *pb@*/;
00460 void jlu32lpair(const void *key, size_t size, rpmuint32_t *pc, rpmuint32_t *pb)
00461 {
00462     union { const void *ptr; size_t i; } u;
00463     rpmuint32_t a = _JLU3_INIT(*pc, size);
00464     rpmuint32_t b = a;
00465     rpmuint32_t c = a;
00466 
00467     if (key == NULL)
00468         goto exit;
00469 
00470     c += *pb;   /* Add the secondary hash. */
00471 
00472     u.ptr = key;
00473     if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
00474         const rpmuint32_t *k = (const rpmuint32_t *)key;        /* read 32-bit chunks */
00475 
00476         /*-- all but last block: aligned reads and affect 32 bits of (a,b,c) */
00477         while (size > 12) {
00478             a += k[0];
00479             b += k[1];
00480             c += k[2];
00481             _JLU3_MIX(a,b,c);
00482             size -= 12;
00483             k += 3;
00484         }
00485         /*------------------------- handle the last (probably partial) block */
00486         /* 
00487          * "k[2]&0xffffff" actually reads beyond the end of the string, but
00488          * then masks off the part it's not allowed to read.  Because the
00489          * string is aligned, the masked-off tail is in the same word as the
00490          * rest of the string.  Every machine with memory protection I've seen
00491          * does it on word boundaries, so is OK with this.  But VALGRIND will
00492          * still catch it and complain.  The masking trick does make the hash
00493          * noticably faster for short strings (like English words).
00494          */
00495 #ifdef WITH_VALGRIND
00496       if (UNLIKELY(_running_on_valgrind)) {
00497         const rpmuint8_t  * k8 = (const rpmuint8_t *)k;
00498 
00499         switch (size) {
00500         case 12:        c += k[2]; b+=k[1]; a+=k[0];    break;
00501         case 11:        c += ((rpmuint32_t)k8[10])<<16; /*@fallthrough@*/
00502         case 10:        c += ((rpmuint32_t)k8[9])<<8;   /*@fallthrough@*/
00503         case  9:        c += k8[8];                     /*@fallthrough@*/
00504         case  8:        b += k[1]; a+=k[0];             break;
00505         case  7:        b += ((rpmuint32_t)k8[6])<<16;  /*@fallthrough@*/
00506         case  6:        b += ((rpmuint32_t)k8[5])<<8;   /*@fallthrough@*/
00507         case  5:        b += k8[4];                     /*@fallthrough@*/
00508         case  4:        a += k[0];                      break;
00509         case  3:        a += ((rpmuint32_t)k8[2])<<16;  /*@fallthrough@*/
00510         case  2:        a += ((rpmuint32_t)k8[1])<<8;   /*@fallthrough@*/
00511         case  1:        a += k8[0];                     break;
00512         case  0:        goto exit;
00513         }
00514 
00515       } else
00516 #endif
00517       {
00518         switch (size) {
00519         case 12:        c += k[2]; b+=k[1]; a+=k[0]; break;
00520         case 11:        c += k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
00521         case 10:        c += k[2]&0xffff; b+=k[1]; a+=k[0]; break;
00522         case  9:        c += k[2]&0xff; b+=k[1]; a+=k[0]; break;
00523         case  8:        b += k[1]; a+=k[0]; break;
00524         case  7:        b += k[1]&0xffffff; a+=k[0]; break;
00525         case  6:        b += k[1]&0xffff; a+=k[0]; break;
00526         case  5:        b += k[1]&0xff; a+=k[0]; break;
00527         case  4:        a += k[0]; break;
00528         case  3:        a += k[0]&0xffffff; break;
00529         case  2:        a += k[0]&0xffff; break;
00530         case  1:        a += k[0]&0xff; break;
00531         case  0:        goto exit;
00532         }
00533       } 
00534     } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
00535         const rpmuint16_t *k = (const rpmuint16_t *)key;        /* read 16-bit chunks */
00536         const rpmuint8_t  *k8;
00537 
00538         /*----------- all but last block: aligned reads and different mixing */
00539         while (size > 12) {
00540             a += k[0] + (((rpmuint32_t)k[1])<<16);
00541             b += k[2] + (((rpmuint32_t)k[3])<<16);
00542             c += k[4] + (((rpmuint32_t)k[5])<<16);
00543             _JLU3_MIX(a,b,c);
00544             size -= 12;
00545             k += 6;
00546         }
00547 
00548         /*------------------------- handle the last (probably partial) block */
00549         k8 = (const rpmuint8_t *)k;
00550         switch (size) {
00551         case 12:
00552             c += k[4]+(((rpmuint32_t)k[5])<<16);
00553             b += k[2]+(((rpmuint32_t)k[3])<<16);
00554             a += k[0]+(((rpmuint32_t)k[1])<<16);
00555             break;
00556         case 11:
00557             c += ((rpmuint32_t)k8[10])<<16;
00558             /*@fallthrough@*/
00559         case 10:
00560             c += k[4];
00561             b += k[2]+(((rpmuint32_t)k[3])<<16);
00562             a += k[0]+(((rpmuint32_t)k[1])<<16);
00563             break;
00564         case  9:
00565             c += k8[8];
00566             /*@fallthrough@*/
00567         case  8:
00568             b += k[2]+(((rpmuint32_t)k[3])<<16);
00569             a += k[0]+(((rpmuint32_t)k[1])<<16);
00570             break;
00571         case  7:
00572             b += ((rpmuint32_t)k8[6])<<16;
00573             /*@fallthrough@*/
00574         case  6:
00575             b += k[2];
00576             a += k[0]+(((rpmuint32_t)k[1])<<16);
00577             break;
00578         case  5:
00579             b += k8[4];
00580             /*@fallthrough@*/
00581         case  4:
00582             a += k[0]+(((rpmuint32_t)k[1])<<16);
00583             break;
00584         case  3:
00585             a += ((rpmuint32_t)k8[2])<<16;
00586             /*@fallthrough@*/
00587         case  2:
00588             a += k[0];
00589             break;
00590         case  1:
00591             a += k8[0];
00592             break;
00593         case  0:
00594             goto exit;
00595         }
00596 
00597     } else {            /* need to read the key one byte at a time */
00598         const rpmuint8_t *k = (const rpmuint8_t *)key;
00599 
00600         /*----------- all but the last block: affect some 32 bits of (a,b,c) */
00601         while (size > 12) {
00602             a += k[0];
00603             a += ((rpmuint32_t)k[1])<<8;
00604             a += ((rpmuint32_t)k[2])<<16;
00605             a += ((rpmuint32_t)k[3])<<24;
00606             b += k[4];
00607             b += ((rpmuint32_t)k[5])<<8;
00608             b += ((rpmuint32_t)k[6])<<16;
00609             b += ((rpmuint32_t)k[7])<<24;
00610             c += k[8];
00611             c += ((rpmuint32_t)k[9])<<8;
00612             c += ((rpmuint32_t)k[10])<<16;
00613             c += ((rpmuint32_t)k[11])<<24;
00614             _JLU3_MIX(a,b,c);
00615             size -= 12;
00616             k += 12;
00617         }
00618 
00619         /*---------------------------- last block: affect all 32 bits of (c) */
00620         switch (size) {
00621         case 12:        c += ((rpmuint32_t)k[11])<<24;  /*@fallthrough@*/
00622         case 11:        c += ((rpmuint32_t)k[10])<<16;  /*@fallthrough@*/
00623         case 10:        c += ((rpmuint32_t)k[9])<<8;    /*@fallthrough@*/
00624         case  9:        c += k[8];                      /*@fallthrough@*/
00625         case  8:        b += ((rpmuint32_t)k[7])<<24;   /*@fallthrough@*/
00626         case  7:        b += ((rpmuint32_t)k[6])<<16;   /*@fallthrough@*/
00627         case  6:        b += ((rpmuint32_t)k[5])<<8;    /*@fallthrough@*/
00628         case  5:        b += k[4];                      /*@fallthrough@*/
00629         case  4:        a += ((rpmuint32_t)k[3])<<24;   /*@fallthrough@*/
00630         case  3:        a += ((rpmuint32_t)k[2])<<16;   /*@fallthrough@*/
00631         case  2:        a += ((rpmuint32_t)k[1])<<8;    /*@fallthrough@*/
00632         case  1:        a += k[0];                      /*@fallthrough@*/
00633             break;
00634         case  0:
00635             goto exit;
00636         }
00637     }
00638 
00639     _JLU3_FINAL(a,b,c);
00640 
00641 exit:
00642     *pc = c;
00643     *pb = b;
00644     return;
00645 }
00646 #endif  /* defined(_JLU3_jlu32lpair) */
00647 
00648 #if defined(_JLU3_jlu32b)
00649 rpmuint32_t jlu32b(rpmuint32_t h, /*@null@*/ const void *key, size_t size)
00650         /*@*/;
00651 /*
00652  * jlu32b():
00653  * This is the same as jlu32w() on big-endian machines.  It is different
00654  * from jlu32l() on all machines.  jlu32b() takes advantage of
00655  * big-endian byte ordering. 
00656  *
00657  * @param h             the previous hash, or an arbitrary value
00658  * @param *k            the key, an array of rpmuint8_t values
00659  * @param size          the size of the key
00660  * @return              the lookup3 hash
00661  */
00662 rpmuint32_t jlu32b(rpmuint32_t h, const void *key, size_t size)
00663 {
00664     union { const void *ptr; size_t i; } u;
00665     rpmuint32_t a = _JLU3_INIT(h, size);
00666     rpmuint32_t b = a;
00667     rpmuint32_t c = a;
00668 
00669     if (key == NULL)
00670         return h;
00671 
00672     u.ptr = key;
00673     if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) {
00674         const rpmuint32_t *k = (const rpmuint32_t *)key;        /* read 32-bit chunks */
00675 
00676         /*-- all but last block: aligned reads and affect 32 bits of (a,b,c) */
00677         while (size > 12) {
00678             a += k[0];
00679             b += k[1];
00680             c += k[2];
00681             _JLU3_MIX(a,b,c);
00682             size -= 12;
00683             k += 3;
00684         }
00685 
00686         /*------------------------- handle the last (probably partial) block */
00687         /* 
00688          * "k[2]<<8" actually reads beyond the end of the string, but
00689          * then shifts out the part it's not allowed to read.  Because the
00690          * string is aligned, the illegal read is in the same word as the
00691          * rest of the string.  Every machine with memory protection I've seen
00692          * does it on word boundaries, so is OK with this.  But VALGRIND will
00693          * still catch it and complain.  The masking trick does make the hash
00694          * noticably faster for short strings (like English words).
00695          */
00696 #ifdef WITH_VALGRIND
00697       if (UNLIKELY(_running_on_valgrind)) {
00698         const rpmuint8_t  * k8 = (const rpmuint8_t *)k;
00699 
00700         switch (size) { /* all the case statements fall through */
00701         case 12:        c += k[2]; b+=k[1]; a+=k[0];    break;
00702         case 11:        c += ((rpmuint32_t)k8[10])<<8;  /*@fallthrough@*/
00703         case 10:        c += ((rpmuint32_t)k8[9])<<16;  /*@fallthrough@*/
00704         case  9:        c += ((rpmuint32_t)k8[8])<<24;  /*@fallthrough@*/
00705         case  8:        b += k[1]; a+=k[0];             break;
00706         case  7:        b += ((rpmuint32_t)k8[6])<<8;   /*@fallthrough@*/
00707         case  6:        b += ((rpmuint32_t)k8[5])<<16;  /*@fallthrough@*/
00708         case  5:        b += ((rpmuint32_t)k8[4])<<24;  /*@fallthrough@*/
00709         case  4:        a += k[0];                      break;
00710         case  3:        a += ((rpmuint32_t)k8[2])<<8;   /*@fallthrough@*/
00711         case  2:        a += ((rpmuint32_t)k8[1])<<16;  /*@fallthrough@*/
00712         case  1:        a += ((rpmuint32_t)k8[0])<<24;  break;
00713         case  0:        goto exit;
00714         }
00715 
00716       } else
00717 #endif
00718       {
00719         switch (size) {
00720         case 12:        c += k[2]; b+=k[1]; a+=k[0]; break;
00721         case 11:        c += k[2]&0xffffff00; b+=k[1]; a+=k[0]; break;
00722         case 10:        c += k[2]&0xffff0000; b+=k[1]; a+=k[0]; break;
00723         case  9:        c += k[2]&0xff000000; b+=k[1]; a+=k[0]; break;
00724         case  8:        b += k[1]; a+=k[0]; break;
00725         case  7:        b += k[1]&0xffffff00; a+=k[0]; break;
00726         case  6:        b += k[1]&0xffff0000; a+=k[0]; break;
00727         case  5:        b += k[1]&0xff000000; a+=k[0]; break;
00728         case  4:        a += k[0]; break;
00729         case  3:        a += k[0]&0xffffff00; break;
00730         case  2:        a += k[0]&0xffff0000; break;
00731         case  1:        a += k[0]&0xff000000; break;
00732         case  0:        goto exit;
00733         }
00734       }
00735     } else {                        /* need to read the key one byte at a time */
00736         const rpmuint8_t *k = (const rpmuint8_t *)key;
00737 
00738         /*----------- all but the last block: affect some 32 bits of (a,b,c) */
00739         while (size > 12) {
00740             a += ((rpmuint32_t)k[0])<<24;
00741             a += ((rpmuint32_t)k[1])<<16;
00742             a += ((rpmuint32_t)k[2])<<8;
00743             a += ((rpmuint32_t)k[3]);
00744             b += ((rpmuint32_t)k[4])<<24;
00745             b += ((rpmuint32_t)k[5])<<16;
00746             b += ((rpmuint32_t)k[6])<<8;
00747             b += ((rpmuint32_t)k[7]);
00748             c += ((rpmuint32_t)k[8])<<24;
00749             c += ((rpmuint32_t)k[9])<<16;
00750             c += ((rpmuint32_t)k[10])<<8;
00751             c += ((rpmuint32_t)k[11]);
00752             _JLU3_MIX(a,b,c);
00753             size -= 12;
00754             k += 12;
00755         }
00756 
00757         /*---------------------------- last block: affect all 32 bits of (c) */
00758         switch (size) { /* all the case statements fall through */
00759         case 12:        c += k[11];                     /*@fallthrough@*/
00760         case 11:        c += ((rpmuint32_t)k[10])<<8;   /*@fallthrough@*/
00761         case 10:        c += ((rpmuint32_t)k[9])<<16;   /*@fallthrough@*/
00762         case  9:        c += ((rpmuint32_t)k[8])<<24;   /*@fallthrough@*/
00763         case  8:        b += k[7];                      /*@fallthrough@*/
00764         case  7:        b += ((rpmuint32_t)k[6])<<8;    /*@fallthrough@*/
00765         case  6:        b += ((rpmuint32_t)k[5])<<16;   /*@fallthrough@*/
00766         case  5:        b += ((rpmuint32_t)k[4])<<24;   /*@fallthrough@*/
00767         case  4:        a += k[3];                      /*@fallthrough@*/
00768         case  3:        a += ((rpmuint32_t)k[2])<<8;    /*@fallthrough@*/
00769         case  2:        a += ((rpmuint32_t)k[1])<<16;   /*@fallthrough@*/
00770         case  1:        a += ((rpmuint32_t)k[0])<<24;   /*@fallthrough@*/
00771             break;
00772         case  0:
00773             goto exit;
00774         }
00775     }
00776 
00777     _JLU3_FINAL(a,b,c);
00778 
00779 exit:
00780     return c;
00781 }
00782 #endif  /* defined(_JLU3_jlu32b) */
00783 
00784 #if defined(_JLU3_SELFTEST)
00785 
00786 /* used for timings */
00787 static void driver1(void)
00788         /*@*/
00789 {
00790     rpmuint8_t buf[256];
00791     rpmuint32_t i;
00792     rpmuint32_t h=0;
00793     time_t a,z;
00794 
00795     time(&a);
00796     for (i=0; i<256; ++i) buf[i] = 'x';
00797     for (i=0; i<1; ++i) {
00798         h = jlu32l(h, &buf[0], sizeof(buf[0]));
00799     }
00800     time(&z);
00801     if (z-a > 0) printf("time %d %.8x\n", (int)(z-a), h);
00802 }
00803 
00804 /* check that every input bit changes every output bit half the time */
00805 #define HASHSTATE 1
00806 #define HASHLEN   1
00807 #define MAXPAIR 60
00808 #define MAXLEN  70
00809 static void driver2(void)
00810         /*@*/
00811 {
00812     rpmuint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1];
00813     rpmuint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z;
00814     rpmuint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE];
00815     rpmuint32_t x[HASHSTATE],y[HASHSTATE];
00816     rpmuint32_t hlen;
00817 
00818     printf("No more than %d trials should ever be needed \n",MAXPAIR/2);
00819     for (hlen=0; hlen < MAXLEN; ++hlen) {
00820         z=0;
00821         for (i=0; i<hlen; ++i) {        /*-------------- for each input byte, */
00822             for (j=0; j<8; ++j) {       /*--------------- for each input bit, */
00823                 for (m=1; m<8; ++m) {   /*--- for serveral possible initvals, */
00824                     for (l=0; l<HASHSTATE; ++l)
00825                         e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((rpmuint32_t)0);
00826 
00827                     /* check that every output bit is affected by that input bit */
00828                     for (k=0; k<MAXPAIR; k+=2) { 
00829                         rpmuint32_t finished=1;
00830                         /* keys have one bit different */
00831                         for (l=0; l<hlen+1; ++l) {a[l] = b[l] = (rpmuint8_t)0;}
00832                         /* have a and b be two keys differing in only one bit */
00833                         a[i] ^= (k<<j);
00834                         a[i] ^= (k>>(8-j));
00835                         c[0] = jlu32l(m, a, hlen);
00836                         b[i] ^= ((k+1)<<j);
00837                         b[i] ^= ((k+1)>>(8-j));
00838                         d[0] = jlu32l(m, b, hlen);
00839                         /* check every bit is 1, 0, set, and not set at least once */
00840                         for (l=0; l<HASHSTATE; ++l) {
00841                             e[l] &= (c[l]^d[l]);
00842                             f[l] &= ~(c[l]^d[l]);
00843                             g[l] &= c[l];
00844                             h[l] &= ~c[l];
00845                             x[l] &= d[l];
00846                             y[l] &= ~d[l];
00847                             if (e[l]|f[l]|g[l]|h[l]|x[l]|y[l]) finished=0;
00848                         }
00849                         if (finished) break;
00850                     }
00851                     if (k>z) z=k;
00852                     if (k == MAXPAIR) {
00853                         printf("Some bit didn't change: ");
00854                         printf("%.8x %.8x %.8x %.8x %.8x %.8x  ",
00855                                 e[0],f[0],g[0],h[0],x[0],y[0]);
00856                         printf("i %d j %d m %d len %d\n", i, j, m, hlen);
00857                     }
00858                     if (z == MAXPAIR) goto done;
00859                 }
00860             }
00861         }
00862    done:
00863         if (z < MAXPAIR) {
00864             printf("Mix success  %2d bytes  %2d initvals  ",i,m);
00865             printf("required  %d  trials\n", z/2);
00866         }
00867     }
00868     printf("\n");
00869 }
00870 
00871 /* Check for reading beyond the end of the buffer and alignment problems */
00872 static void driver3(void)
00873         /*@*/
00874 {
00875     rpmuint8_t buf[MAXLEN+20], *b;
00876     rpmuint32_t len;
00877     rpmuint8_t q[] = "This is the time for all good men to come to the aid of their country...";
00878     rpmuint32_t h;
00879     rpmuint8_t qq[] = "xThis is the time for all good men to come to the aid of their country...";
00880     rpmuint32_t i;
00881     rpmuint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country...";
00882     rpmuint32_t j;
00883     rpmuint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country...";
00884     rpmuint32_t ref,x,y;
00885     rpmuint8_t *p;
00886     rpmuint32_t m = 13;
00887 
00888     printf("Endianness.  These lines should all be the same (for values filled in):\n");
00889     printf("%.8x                            %.8x                            %.8x\n",
00890         jlu32w(m, (const rpmuint32_t *)q, (sizeof(q)-1)/4),
00891         jlu32w(m, (const rpmuint32_t *)q, (sizeof(q)-5)/4),
00892         jlu32w(m, (const rpmuint32_t *)q, (sizeof(q)-9)/4));
00893     p = q;
00894     printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
00895         jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2),
00896         jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4),
00897         jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6),
00898         jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8),
00899         jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10),
00900         jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12));
00901     p = &qq[1];
00902     printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
00903         jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2),
00904         jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4),
00905         jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6),
00906         jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8),
00907         jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10),
00908         jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12));
00909     p = &qqq[2];
00910     printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
00911         jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2),
00912         jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4),
00913         jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6),
00914         jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8),
00915         jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10),
00916         jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12));
00917     p = &qqqq[3];
00918     printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
00919         jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2),
00920         jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4),
00921         jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6),
00922         jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8),
00923         jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10),
00924         jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12));
00925     printf("\n");
00926     for (h=0, b=buf+1; h<8; ++h, ++b) {
00927         for (i=0; i<MAXLEN; ++i) {
00928             len = i;
00929             for (j=0; j<i; ++j)
00930                 *(b+j)=0;
00931 
00932             /* these should all be equal */
00933             m = 1;
00934             ref = jlu32l(m, b, len);
00935             *(b+i)=(rpmuint8_t)~0;
00936             *(b-1)=(rpmuint8_t)~0;
00937             x = jlu32l(m, b, len);
00938             y = jlu32l(m, b, len);
00939             if ((ref != x) || (ref != y)) 
00940                 printf("alignment error: %.8x %.8x %.8x %d %d\n",ref,x,y, h, i);
00941         }
00942     }
00943 }
00944 
00945 /* check for problems with nulls */
00946 static void driver4(void)
00947         /*@*/
00948 {
00949     rpmuint8_t buf[1];
00950     rpmuint32_t h;
00951     rpmuint32_t i;
00952     rpmuint32_t state[HASHSTATE];
00953 
00954     buf[0] = ~0;
00955     for (i=0; i<HASHSTATE; ++i)
00956         state[i] = 1;
00957     printf("These should all be different\n");
00958     h = 0;
00959     for (i=0; i<8; ++i) {
00960         h = jlu32l(h, buf, 0);
00961         printf("%2ld  0-byte strings, hash is  %.8x\n", (long)i, h);
00962     }
00963 }
00964 
00965 
00966 int main(int argc, char ** argv)
00967 {
00968     driver1();  /* test that the key is hashed: used for timings */
00969     driver2();  /* test that whole key is hashed thoroughly */
00970     driver3();  /* test that nothing but the key is hashed */
00971     driver4();  /* test hashing multiple buffers (all buffers are null) */
00972     return 1;
00973 }
00974 
00975 #endif  /* _JLU3_SELFTEST */