|
|
@ -23,6 +23,8 @@ vData(min((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM |
|
|
|
// The ideal number of hash functions is filter size * ln(2) / number of elements
|
|
|
|
// The ideal number of hash functions is filter size * ln(2) / number of elements
|
|
|
|
// Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits
|
|
|
|
// Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits
|
|
|
|
// See http://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas
|
|
|
|
// See http://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas
|
|
|
|
|
|
|
|
isFull(false), |
|
|
|
|
|
|
|
isEmpty(false), |
|
|
|
nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)), |
|
|
|
nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)), |
|
|
|
nTweak(nTweakIn), |
|
|
|
nTweak(nTweakIn), |
|
|
|
nFlags(nFlagsIn) |
|
|
|
nFlags(nFlagsIn) |
|
|
@ -37,7 +39,7 @@ inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector< |
|
|
|
|
|
|
|
|
|
|
|
void CBloomFilter::insert(const vector<unsigned char>& vKey) |
|
|
|
void CBloomFilter::insert(const vector<unsigned char>& vKey) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (vData.size() == 1 && vData[0] == 0xff) |
|
|
|
if (isFull) |
|
|
|
return; |
|
|
|
return; |
|
|
|
for (unsigned int i = 0; i < nHashFuncs; i++) |
|
|
|
for (unsigned int i = 0; i < nHashFuncs; i++) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -45,6 +47,7 @@ void CBloomFilter::insert(const vector<unsigned char>& vKey) |
|
|
|
// Sets bit nIndex of vData
|
|
|
|
// Sets bit nIndex of vData
|
|
|
|
vData[nIndex >> 3] |= bit_mask[7 & nIndex]; |
|
|
|
vData[nIndex >> 3] |= bit_mask[7 & nIndex]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
isEmpty = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CBloomFilter::insert(const COutPoint& outpoint) |
|
|
|
void CBloomFilter::insert(const COutPoint& outpoint) |
|
|
@ -63,8 +66,10 @@ void CBloomFilter::insert(const uint256& hash) |
|
|
|
|
|
|
|
|
|
|
|
bool CBloomFilter::contains(const vector<unsigned char>& vKey) const |
|
|
|
bool CBloomFilter::contains(const vector<unsigned char>& vKey) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (vData.size() == 1 && vData[0] == 0xff) |
|
|
|
if (isFull) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
|
|
|
|
if (isEmpty) |
|
|
|
|
|
|
|
return false; |
|
|
|
for (unsigned int i = 0; i < nHashFuncs; i++) |
|
|
|
for (unsigned int i = 0; i < nHashFuncs; i++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
unsigned int nIndex = Hash(i, vKey); |
|
|
|
unsigned int nIndex = Hash(i, vKey); |
|
|
@ -99,6 +104,10 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx, const uint256& ha |
|
|
|
bool fFound = false; |
|
|
|
bool fFound = false; |
|
|
|
// Match if the filter contains the hash of tx
|
|
|
|
// Match if the filter contains the hash of tx
|
|
|
|
// for finding tx when they appear in a block
|
|
|
|
// for finding tx when they appear in a block
|
|
|
|
|
|
|
|
if (isFull) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
if (isEmpty) |
|
|
|
|
|
|
|
return false; |
|
|
|
if (contains(hash)) |
|
|
|
if (contains(hash)) |
|
|
|
fFound = true; |
|
|
|
fFound = true; |
|
|
|
|
|
|
|
|
|
|
@ -158,3 +167,16 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx, const uint256& ha |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CBloomFilter::UpdateEmptyFull() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
bool full = true; |
|
|
|
|
|
|
|
bool empty = true; |
|
|
|
|
|
|
|
for (unsigned int i = 0; i < vData.size(); i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
full &= vData[i] == 0xff; |
|
|
|
|
|
|
|
empty &= vData[i] == 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
isFull = full; |
|
|
|
|
|
|
|
isEmpty = empty; |
|
|
|
|
|
|
|
} |
|
|
|