00001 #include "hash.h"
00002 #include "iostream"
00003
00004 UInt_t hash_utils::murmurhash2::operator() (const void * key, int len) const
00005 {
00006
00007
00008 const UInt_t m = 0x5bd1e995;
00009 const Int_t r = 24;
00010
00011
00012 UInt_t h = fSeed ^ len;
00013
00014
00015 const Byte_t* data = (const Byte_t*) key;
00016
00017 while(len >= 4){
00018 UInt_t k = *(UInt_t *)data;
00019
00020 k *= m;
00021 k ^= k >> r;
00022 k *= m;
00023
00024 h *= m;
00025 h ^= k;
00026
00027 data += 4;
00028 len -= 4;
00029 }
00030
00031
00032
00033 switch(len) {
00034 case 3: h ^= data[2] << 16;
00035 case 2: h ^= data[1] << 8;
00036 case 1: h ^= data[0];
00037 h *= m;
00038 };
00039
00040
00041
00042 h ^= h >> 13;
00043 h *= m;
00044 h ^= h >> 15;
00045
00046 return h;
00047 }
00048
00049
00050 using hash_utils::MurmurHash3;
00051
00052
00053 void MurmurHash3::Add(MsgPtr_t msg_ptr, Length_t len)
00054 {
00055 fSize += len;
00056
00057 while(len >= 4) {
00058 UInt_t k = *(reinterpret_cast<const UInt_t*>(msg_ptr));
00059 mmix(fHash, k);
00060 msg_ptr += 4;
00061 len -= 4;
00062 }
00063
00064 MixTail(msg_ptr,len);
00065 }
00066
00067
00068
00069
00070
00071 MurmurHash3::Hash_t MurmurHash3::End()
00072 {
00073 if (fTail) mmix(fHash, fTail);
00074 fHash ^= fSize;
00075 final_mix(fHash);
00076 return fHash;
00077 }
00078
00079
00080
00081
00082
00083 void MurmurHash3::MixTail(MsgPtr_t& data, Length_t& len)
00084 {
00085 while( len && ((len<4) || fCount)) {
00086 fTail |= (*data++) << (fCount * 8);
00087 fCount++;
00088 len--;
00089
00090 if(fCount == 4){
00091 mmix(fHash, fTail);
00092 fTail = 0;
00093 fCount = 0;
00094 }
00095 }
00096 }
00097
00098
00099