Skip to content

Commit 1f5e8fe

Browse files
committed
Merge pull request #4494
bc42503 Use unordered_map for CCoinsViewCache with salted hash (Pieter Wuille)
2 parents bdd5b58 + bc42503 commit 1f5e8fe

File tree

4 files changed

+66
-4
lines changed

4 files changed

+66
-4
lines changed

src/coins.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include "coins.h"
66

7+
#include "random.h"
8+
79
#include <assert.h>
810

911
// calculate number of bytes for the bitmask, and its number of non-zero bytes
@@ -69,6 +71,8 @@ void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
6971
bool CCoinsViewBacked::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
7072
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); }
7173

74+
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
75+
7276
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { }
7377

7478
bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
@@ -84,8 +88,8 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
8488
}
8589

8690
CCoinsMap::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
87-
CCoinsMap::iterator it = cacheCoins.lower_bound(txid);
88-
if (it != cacheCoins.end() && it->first == txid)
91+
CCoinsMap::iterator it = cacheCoins.find(txid);
92+
if (it != cacheCoins.end())
8993
return it;
9094
CCoins tmp;
9195
if (!base->GetCoins(txid,tmp))

src/coins.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <stdint.h>
1414

1515
#include <boost/foreach.hpp>
16+
#include <boost/unordered_map.hpp>
1617

1718
/** pruned version of CTransaction: only retains metadata and unspent transaction outputs
1819
*
@@ -239,7 +240,19 @@ class CCoins
239240
}
240241
};
241242

242-
typedef std::map<uint256,CCoins> CCoinsMap;
243+
class CCoinsKeyHasher
244+
{
245+
private:
246+
uint256 salt;
247+
248+
public:
249+
CCoinsKeyHasher();
250+
uint64_t operator()(const uint256& key) const {
251+
return key.GetHash(salt);
252+
}
253+
};
254+
255+
typedef boost::unordered_map<uint256, CCoins, CCoinsKeyHasher> CCoinsMap;
243256

244257
struct CCoinsStats
245258
{

src/uint256.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,3 +290,46 @@ uint32_t uint256::GetCompact(bool fNegative) const
290290
nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
291291
return nCompact;
292292
}
293+
294+
static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
295+
{
296+
// Taken from lookup3, by Bob Jenkins.
297+
a -= c; a ^= ((c << 4) | (c >> 28)); c += b;
298+
b -= a; b ^= ((a << 6) | (a >> 26)); a += c;
299+
c -= b; c ^= ((b << 8) | (b >> 24)); b += a;
300+
a -= c; a ^= ((c << 16) | (c >> 16)); c += b;
301+
b -= a; b ^= ((a << 19) | (a >> 13)); a += c;
302+
c -= b; c ^= ((b << 4) | (b >> 28)); b += a;
303+
}
304+
305+
static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c)
306+
{
307+
// Taken from lookup3, by Bob Jenkins.
308+
c ^= b; c -= ((b << 14) | (b >> 18));
309+
a ^= c; a -= ((c << 11) | (c >> 21));
310+
b ^= a; b -= ((a << 25) | (a >> 7));
311+
c ^= b; c -= ((b << 16) | (b >> 16));
312+
a ^= c; a -= ((c << 4) | (c >> 28));
313+
b ^= a; b -= ((a << 14) | (a >> 18));
314+
c ^= b; c -= ((b << 24) | (b >> 8));
315+
}
316+
317+
uint64_t uint256::GetHash(const uint256 &salt) const
318+
{
319+
uint32_t a, b, c;
320+
a = b = c = 0xdeadbeef + (WIDTH << 2);
321+
322+
a += pn[0] ^ salt.pn[0];
323+
b += pn[1] ^ salt.pn[1];
324+
c += pn[2] ^ salt.pn[2];
325+
HashMix(a, b, c);
326+
a += pn[3] ^ salt.pn[3];
327+
b += pn[4] ^ salt.pn[4];
328+
c += pn[5] ^ salt.pn[5];
329+
HashMix(a, b, c);
330+
a += pn[6] ^ salt.pn[6];
331+
b += pn[7] ^ salt.pn[7];
332+
HashFinal(a, b, c);
333+
334+
return ((((uint64_t)b) << 32) | c);
335+
}

src/uint256.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class uint_error : public std::runtime_error {
2121
template<unsigned int BITS>
2222
class base_uint
2323
{
24-
private:
24+
protected:
2525
enum { WIDTH=BITS/32 };
2626
uint32_t pn[WIDTH];
2727
public:
@@ -322,6 +322,8 @@ class uint256 : public base_uint<256> {
322322
// implementation accident.
323323
uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
324324
uint32_t GetCompact(bool fNegative = false) const;
325+
326+
uint64_t GetHash(const uint256& salt) const;
325327
};
326328

327329
#endif

0 commit comments

Comments
 (0)