UINT64 Hash64(const BYTE *k, UINT Length) { UINT a, b, c, LocalLength; /* Set up the internal state */ LocalLength = Length; a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ c = 0x9b9773e9; /*---------------------------------------- handle most of the key */ while (LocalLength >= 12) { a += (k[0] + ((UINT)k[1]<<8) + ((UINT)k[2]<<16) + ((UINT)k[3]<<24)); b += (k[4] + ((UINT)k[5]<<8) + ((UINT)k[6]<<16) + ((UINT)k[7]<<24)); c += (k[8] + ((UINT)k[9]<<8) + ((UINT)k[10]<<16)+ ((UINT)k[11]<<24)); HashMix(a, b, c); k += 12; LocalLength -= 12; } /*------------------------------------- handle the last 11 bytes */ c += Length; switch(LocalLength) /* all the case statements fall through */ { case 11: c += ((UINT)k[10]<<24); case 10: c += ((UINT)k[9]<<16); case 9 : c += ((UINT)k[8]<<8); /* the first byte of c is reserved for the length */ case 8 : b += ((UINT)k[7]<<24); case 7 : b += ((UINT)k[6]<<16); case 6 : b += ((UINT)k[5]<<8); case 5 : b += k[4]; case 4 : a += ((UINT)k[3]<<24); case 3 : a += ((UINT)k[2]<<16); case 2 : a += ((UINT)k[1]<<8); case 1 : a += k[0]; /* case 0: nothing left to add */ } HashMix(a, b, c); /*-------------------------------------------- report the result */ return UINT64(c) + UINT64(UINT64(a) << 32); }
void BloomFilter::insert(size_t hash) { for (size_t i = 0; i < hash_keys_.size(); i++) { uint32_t mix = HashMix(hash_keys_[i], hash); uint32_t index = mix % bit_size_; size_t byte = index / 8; size_t bit = index % 8; // set the bit data_[byte] |= (1 << bit); } }
// Notice that bytes are from left-to-right, whereas bits are taken from right-to-left.. // This is not a problem as long as they are same in insert and exists.. bool BloomFilter::exists(size_t hash) const { for (size_t i= 0; i < hash_keys_.size(); i++) { uint32_t mix = HashMix(hash_keys_[i], hash); uint32_t index = mix % bit_size_; size_t byte = index / 8; size_t bit = index % 8; // check if the bit is set. if (!(data_.at(byte) & (1 << bit))) return false; } return true; }