c_jhash.h
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #ifndef _C_JHASH_H
00025 #define _C_JHASH_H
00026 
00027 #include <stdint.h>
00028 
00029 #define c_hashsize(n) ((uint8_t) 1 << (n))
00030 #define c_hashmask(n) (xhashsize(n) - 1)
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 #define _c_mix(a,b,c) \
00059 { \
00060   a -= b; a -= c; a ^= (c>>13); \
00061   b -= c; b -= a; b ^= (a<<8); \
00062   c -= a; c -= b; c ^= (b>>13); \
00063   a -= b; a -= c; a ^= (c>>12);  \
00064   b -= c; b -= a; b ^= (a<<16); \
00065   c -= a; c -= b; c ^= (b>>5); \
00066   a -= b; a -= c; a ^= (c>>3);  \
00067   b -= c; b -= a; b ^= (a<<10); \
00068   c -= a; c -= b; c ^= (b>>15); \
00069 }
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 #define _c_mix64(a,b,c) \
00090 { \
00091   a -= b; a -= c; a ^= (c>>43); \
00092   b -= c; b -= a; b ^= (a<<9); \
00093   c -= a; c -= b; c ^= (b>>8); \
00094   a -= b; a -= c; a ^= (c>>38); \
00095   b -= c; b -= a; b ^= (a<<23); \
00096   c -= a; c -= b; c ^= (b>>5); \
00097   a -= b; a -= c; a ^= (c>>35); \
00098   b -= c; b -= a; b ^= (a<<49); \
00099   c -= a; c -= b; c ^= (b>>11); \
00100   a -= b; a -= c; a ^= (c>>12); \
00101   b -= c; b -= a; b ^= (a<<18); \
00102   c -= a; c -= b; c ^= (b>>22); \
00103 }
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 static inline uint32_t c_jhash(const uint8_t *k, uint32_t length, uint32_t initval) {
00128    uint32_t a,b,c,len;
00129 
00130    
00131    len = length;
00132    a = b = 0x9e3779b9; 
00133    c = initval; 
00134 
00135    while (len >= 12) {
00136       a += (k[0] +((uint32_t)k[1]<<8) +((uint32_t)k[2]<<16) +((uint32_t)k[3]<<24));
00137       b += (k[4] +((uint32_t)k[5]<<8) +((uint32_t)k[6]<<16) +((uint32_t)k[7]<<24));
00138       c += (k[8] +((uint32_t)k[9]<<8) +((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24));
00139       _c_mix(a,b,c);
00140       k += 12; len -= 12;
00141    }
00142 
00143    
00144    c += length;
00145    
00146    switch(len) {
00147      case 11: c+=((uint32_t)k[10]<<24);
00148      case 10: c+=((uint32_t)k[9]<<16);
00149      case 9 : c+=((uint32_t)k[8]<<8);
00150      
00151      case 8 : b+=((uint32_t)k[7]<<24);
00152      case 7 : b+=((uint32_t)k[6]<<16);
00153      case 6 : b+=((uint32_t)k[5]<<8);
00154      case 5 : b+=k[4];
00155      case 4 : a+=((uint32_t)k[3]<<24);
00156      case 3 : a+=((uint32_t)k[2]<<16);
00157      case 2 : a+=((uint32_t)k[1]<<8);
00158      case 1 : a+=k[0];
00159      
00160    }
00161    _c_mix(a,b,c);
00162 
00163    return c;
00164 }
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 static inline uint64_t c_jhash64(const uint8_t *k, uint64_t length, uint64_t intval) {
00187   uint64_t a,b,c,len;
00188 
00189   
00190   len = length;
00191   a = b = intval; 
00192   c = 0x9e3779b97f4a7c13LL; 
00193 
00194   
00195   while (len >= 24)
00196   {
00197     a += (k[0]        +((uint64_t)k[ 1]<< 8)+((uint64_t)k[ 2]<<16)+((uint64_t)k[ 3]<<24)
00198      +((uint64_t)k[4 ]<<32)+((uint64_t)k[ 5]<<40)+((uint64_t)k[ 6]<<48)+((uint64_t)k[ 7]<<56));
00199     b += (k[8]        +((uint64_t)k[ 9]<< 8)+((uint64_t)k[10]<<16)+((uint64_t)k[11]<<24)
00200      +((uint64_t)k[12]<<32)+((uint64_t)k[13]<<40)+((uint64_t)k[14]<<48)+((uint64_t)k[15]<<56));
00201     c += (k[16]       +((uint64_t)k[17]<< 8)+((uint64_t)k[18]<<16)+((uint64_t)k[19]<<24)
00202      +((uint64_t)k[20]<<32)+((uint64_t)k[21]<<40)+((uint64_t)k[22]<<48)+((uint64_t)k[23]<<56));
00203     _c_mix64(a,b,c);
00204     k += 24; len -= 24;
00205   }
00206 
00207   
00208   c += length;
00209   switch(len) {
00210     case 23: c+=((uint64_t)k[22]<<56);
00211     case 22: c+=((uint64_t)k[21]<<48);
00212     case 21: c+=((uint64_t)k[20]<<40);
00213     case 20: c+=((uint64_t)k[19]<<32);
00214     case 19: c+=((uint64_t)k[18]<<24);
00215     case 18: c+=((uint64_t)k[17]<<16);
00216     case 17: c+=((uint64_t)k[16]<<8);
00217     
00218     case 16: b+=((uint64_t)k[15]<<56);
00219     case 15: b+=((uint64_t)k[14]<<48);
00220     case 14: b+=((uint64_t)k[13]<<40);
00221     case 13: b+=((uint64_t)k[12]<<32);
00222     case 12: b+=((uint64_t)k[11]<<24);
00223     case 11: b+=((uint64_t)k[10]<<16);
00224     case 10: b+=((uint64_t)k[ 9]<<8);
00225     case  9: b+=((uint64_t)k[ 8]);
00226     case  8: a+=((uint64_t)k[ 7]<<56);
00227     case  7: a+=((uint64_t)k[ 6]<<48);
00228     case  6: a+=((uint64_t)k[ 5]<<40);
00229     case  5: a+=((uint64_t)k[ 4]<<32);
00230     case  4: a+=((uint64_t)k[ 3]<<24);
00231     case  3: a+=((uint64_t)k[ 2]<<16);
00232     case  2: a+=((uint64_t)k[ 1]<<8);
00233     case  1: a+=((uint64_t)k[ 0]);
00234     
00235   }
00236   _c_mix64(a,b,c);
00237 
00238   return c;
00239 }
00240 
00241 
00242 
00243 
00244 #endif 
00245