Browse Source

Merge pull request #4494

bc42503 Use unordered_map for CCoinsViewCache with salted hash (Pieter Wuille)
0.10
Wladimir J. van der Laan 10 years ago
parent
commit
1f5e8fe804
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 8
      src/coins.cpp
  2. 15
      src/coins.h
  3. 43
      src/uint256.cpp
  4. 4
      src/uint256.h

8
src/coins.cpp

@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
#include "coins.h"
#include "random.h"
#include <assert.h>
// 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; } @@ -69,6 +71,8 @@ void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
bool CCoinsViewBacked::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); }
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { }
bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
@ -84,8 +88,8 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) { @@ -84,8 +88,8 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
}
CCoinsMap::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
CCoinsMap::iterator it = cacheCoins.lower_bound(txid);
if (it != cacheCoins.end() && it->first == txid)
CCoinsMap::iterator it = cacheCoins.find(txid);
if (it != cacheCoins.end())
return it;
CCoins tmp;
if (!base->GetCoins(txid,tmp))

15
src/coins.h

@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
#include <stdint.h>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
/** pruned version of CTransaction: only retains metadata and unspent transaction outputs
*
@ -239,7 +240,19 @@ public: @@ -239,7 +240,19 @@ public:
}
};
typedef std::map<uint256,CCoins> CCoinsMap;
class CCoinsKeyHasher
{
private:
uint256 salt;
public:
CCoinsKeyHasher();
uint64_t operator()(const uint256& key) const {
return key.GetHash(salt);
}
};
typedef boost::unordered_map<uint256, CCoins, CCoinsKeyHasher> CCoinsMap;
struct CCoinsStats
{

43
src/uint256.cpp

@ -290,3 +290,46 @@ uint32_t uint256::GetCompact(bool fNegative) const @@ -290,3 +290,46 @@ uint32_t uint256::GetCompact(bool fNegative) const
nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
return nCompact;
}
static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
{
// Taken from lookup3, by Bob Jenkins.
a -= c; a ^= ((c << 4) | (c >> 28)); c += b;
b -= a; b ^= ((a << 6) | (a >> 26)); a += c;
c -= b; c ^= ((b << 8) | (b >> 24)); b += a;
a -= c; a ^= ((c << 16) | (c >> 16)); c += b;
b -= a; b ^= ((a << 19) | (a >> 13)); a += c;
c -= b; c ^= ((b << 4) | (b >> 28)); b += a;
}
static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c)
{
// Taken from lookup3, by Bob Jenkins.
c ^= b; c -= ((b << 14) | (b >> 18));
a ^= c; a -= ((c << 11) | (c >> 21));
b ^= a; b -= ((a << 25) | (a >> 7));
c ^= b; c -= ((b << 16) | (b >> 16));
a ^= c; a -= ((c << 4) | (c >> 28));
b ^= a; b -= ((a << 14) | (a >> 18));
c ^= b; c -= ((b << 24) | (b >> 8));
}
uint64_t uint256::GetHash(const uint256 &salt) const
{
uint32_t a, b, c;
a = b = c = 0xdeadbeef + (WIDTH << 2);
a += pn[0] ^ salt.pn[0];
b += pn[1] ^ salt.pn[1];
c += pn[2] ^ salt.pn[2];
HashMix(a, b, c);
a += pn[3] ^ salt.pn[3];
b += pn[4] ^ salt.pn[4];
c += pn[5] ^ salt.pn[5];
HashMix(a, b, c);
a += pn[6] ^ salt.pn[6];
b += pn[7] ^ salt.pn[7];
HashFinal(a, b, c);
return ((((uint64_t)b) << 32) | c);
}

4
src/uint256.h

@ -21,7 +21,7 @@ public: @@ -21,7 +21,7 @@ public:
template<unsigned int BITS>
class base_uint
{
private:
protected:
enum { WIDTH=BITS/32 };
uint32_t pn[WIDTH];
public:
@ -322,6 +322,8 @@ public: @@ -322,6 +322,8 @@ public:
// implementation accident.
uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
uint32_t GetCompact(bool fNegative = false) const;
uint64_t GetHash(const uint256& salt) const;
};
#endif

Loading…
Cancel
Save