00001 #ifndef MURMURHASH3_H
00002 #define MURMURHASH3_H
00003
00004 #include "Rtypes.h"
00005 #include <iostream>
00006 namespace hash {
00007 class MurmurHash3;
00008
00010 typedef const Byte_t* MsgPtr_t;
00011
00012 template<typename T>
00013 MsgPtr_t MsgPtr(T* ptr){
00014 return reinterpret_cast<MsgPtr_t>(ptr);};
00015
00016
00017
00018
00019
00020 template<typename T> MsgPtr_t MsgPtr(const T& thing)
00021 {
00022 return reinterpret_cast<MsgPtr_t>(&thing);};
00023 };
00024
00025 class hash::MurmurHash3 {
00026 public:
00027 enum {kDefaultSeed = 0xe086c5ff};
00028
00029 typedef UInt_t Hash_t;
00030 typedef Int_t Length_t;
00031 typedef Byte_t Rot_t;
00032
00033 MurmurHash3(unsigned int seed = kDefaultSeed)
00034 : fHash(seed), fTail(0), fCount(0), fSize(0)
00035 {}
00036
00037 inline void Reset(UInt_t seed = kDefaultSeed)
00038 {
00039 fHash = seed;
00040 fTail = fCount = fSize = 0;
00041 }
00042
00043
00044 void Add(MsgPtr_t msg_ptr, Length_t len);
00045
00046 template<typename T>
00047 MurmurHash3& Add(T* ptr, Length_t len)
00048 {
00049 Add(reinterpret_cast<MsgPtr_t>(ptr), len);
00050 return *this;
00051 }
00052
00053 template<typename T>
00054 MurmurHash3& Add(const T& thing, Length_t len)
00055 {
00056 Add(reinterpret_cast<MsgPtr_t>(&thing), len);
00057 return *this;
00058 }
00059
00060 Hash_t Value() const;
00061
00062 Hash_t End(UInt_t seed = kDefaultSeed);
00063
00064 private:
00065
00066 inline Hash_t& EndImp(Hash_t& hash, UInt_t& tail) const;
00067
00068 void MixTail (MsgPtr_t& data, Length_t& len);
00069
00070 inline UInt_t rot32(UInt_t bits, Rot_t r) const
00071 {
00072 return (bits << r) | (bits >> (32 - r));
00073 }
00074
00075 inline void mmix(Hash_t& h, UInt_t& bits) const
00076 {
00077 bits *= kMply1; bits = rot32(bits, 15); bits *= kMply2;
00078 h ^= bits; h = rot32(h, 13) * 5 + 0xe6546b64;
00079 }
00080
00081 inline void final_mix(Hash_t& h) const
00082 {
00083 h ^= h >> 16; h *= 0x85ebca6b;
00084 h ^= h >> 13; h *= 0xc2b2ae35;
00085 h ^= h >> 16;
00086 }
00087
00088
00089
00090 static const UInt_t kMply1 = 0xcc9e2d51;
00091 static const UInt_t kMply2 = 0x1b873593;
00092
00093
00094
00095
00096
00097
00098
00099 Hash_t fHash;
00100 UInt_t fTail;
00101 UInt_t fCount;
00102 UInt_t fSize;
00103 };
00104
00105 #endif //MURMURHASH3_H;