aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2013-02-22 09:01:30 -0800
committerGavin Andresen <gavinandresen@gmail.com>2013-02-22 09:01:30 -0800
commitcc67f1e2b40950749637a14aa4a623731aee8eb7 (patch)
tree59c025e589bc3857bb639e99221fff72fc703e6b /src
parentb8f4e42e1bd9f80690d61dc2ab86edb14b2ecb40 (diff)
parentf369d02c51077ffa1644954d0478e93966e1bb72 (diff)
downloadbitcoin-cc67f1e2b40950749637a14aa4a623731aee8eb7.tar.xz
Merge pull request #2221 from sipa/perfo
Various performance tweaks to CCoinsView
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp37
-rw-r--r--src/main.h35
-rw-r--r--src/txdb.cpp6
-rw-r--r--src/txdb.h6
4 files changed, 47 insertions, 37 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 9edd9a2990..794913d282 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -162,9 +162,9 @@ void static ResendWalletTransactions()
// CCoinsView implementations
//
-bool CCoinsView::GetCoins(uint256 txid, CCoins &coins) { return false; }
-bool CCoinsView::SetCoins(uint256 txid, const CCoins &coins) { return false; }
-bool CCoinsView::HaveCoins(uint256 txid) { return false; }
+bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) { return false; }
+bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return false; }
+bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
CBlockIndex *CCoinsView::GetBestBlock() { return NULL; }
bool CCoinsView::SetBestBlock(CBlockIndex *pindex) { return false; }
bool CCoinsView::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) { return false; }
@@ -172,9 +172,9 @@ bool CCoinsView::GetStats(CCoinsStats &stats) { return false; }
CCoinsViewBacked::CCoinsViewBacked(CCoinsView &viewIn) : base(&viewIn) { }
-bool CCoinsViewBacked::GetCoins(uint256 txid, CCoins &coins) { return base->GetCoins(txid, coins); }
-bool CCoinsViewBacked::SetCoins(uint256 txid, const CCoins &coins) { return base->SetCoins(txid, coins); }
-bool CCoinsViewBacked::HaveCoins(uint256 txid) { return base->HaveCoins(txid); }
+bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) { return base->GetCoins(txid, coins); }
+bool CCoinsViewBacked::SetCoins(const uint256 &txid, const CCoins &coins) { return base->SetCoins(txid, coins); }
+bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(txid); }
CBlockIndex *CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
bool CCoinsViewBacked::SetBestBlock(CBlockIndex *pindex) { return base->SetBestBlock(pindex); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
@@ -183,7 +183,7 @@ bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stat
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), pindexTip(NULL) { }
-bool CCoinsViewCache::GetCoins(uint256 txid, CCoins &coins) {
+bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
if (cacheCoins.count(txid)) {
coins = cacheCoins[txid];
return true;
@@ -195,29 +195,30 @@ bool CCoinsViewCache::GetCoins(uint256 txid, CCoins &coins) {
return false;
}
-std::map<uint256,CCoins>::iterator CCoinsViewCache::FetchCoins(uint256 txid) {
- std::map<uint256,CCoins>::iterator it = cacheCoins.find(txid);
- if (it != cacheCoins.end())
+std::map<uint256,CCoins>::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
+ std::map<uint256,CCoins>::iterator it = cacheCoins.lower_bound(txid);
+ if (it != cacheCoins.end() && it->first == txid)
return it;
CCoins tmp;
if (!base->GetCoins(txid,tmp))
- return it;
- std::pair<std::map<uint256,CCoins>::iterator,bool> ret = cacheCoins.insert(std::make_pair(txid, tmp));
- return ret.first;
+ return cacheCoins.end();
+ std::map<uint256,CCoins>::iterator ret = cacheCoins.insert(it, std::make_pair(txid, CCoins()));
+ tmp.swap(ret->second);
+ return ret;
}
-CCoins &CCoinsViewCache::GetCoins(uint256 txid) {
+CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) {
std::map<uint256,CCoins>::iterator it = FetchCoins(txid);
assert(it != cacheCoins.end());
return it->second;
}
-bool CCoinsViewCache::SetCoins(uint256 txid, const CCoins &coins) {
+bool CCoinsViewCache::SetCoins(const uint256 &txid, const CCoins &coins) {
cacheCoins[txid] = coins;
return true;
}
-bool CCoinsViewCache::HaveCoins(uint256 txid) {
+bool CCoinsViewCache::HaveCoins(const uint256 &txid) {
return FetchCoins(txid) != cacheCoins.end();
}
@@ -254,7 +255,7 @@ unsigned int CCoinsViewCache::GetCacheSize() {
It does not check for spendings by memory pool transactions. */
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
-bool CCoinsViewMemPool::GetCoins(uint256 txid, CCoins &coins) {
+bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) {
if (base->GetCoins(txid, coins))
return true;
if (mempool.exists(txid)) {
@@ -265,7 +266,7 @@ bool CCoinsViewMemPool::GetCoins(uint256 txid, CCoins &coins) {
return false;
}
-bool CCoinsViewMemPool::HaveCoins(uint256 txid) {
+bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) {
return mempool.exists(txid) || base->HaveCoins(txid);
}
diff --git a/src/main.h b/src/main.h
index 4a217d1746..c1af0c3706 100644
--- a/src/main.h
+++ b/src/main.h
@@ -909,6 +909,15 @@ public:
void Cleanup() {
while (vout.size() > 0 && vout.back().IsNull())
vout.pop_back();
+ if (vout.empty())
+ std::vector<CTxOut>().swap(vout);
+ }
+
+ void swap(CCoins &to) {
+ std::swap(to.fCoinBase, fCoinBase);
+ to.vout.swap(vout);
+ std::swap(to.nHeight, nHeight);
+ std::swap(to.nVersion, nVersion);
}
// equality test
@@ -2109,14 +2118,14 @@ class CCoinsView
{
public:
// Retrieve the CCoins (unspent transaction outputs) for a given txid
- virtual bool GetCoins(uint256 txid, CCoins &coins);
+ virtual bool GetCoins(const uint256 &txid, CCoins &coins);
// Modify the CCoins for a given txid
- virtual bool SetCoins(uint256 txid, const CCoins &coins);
+ virtual bool SetCoins(const uint256 &txid, const CCoins &coins);
// Just check whether we have data for a given txid.
// This may (but cannot always) return true for fully spent transactions
- virtual bool HaveCoins(uint256 txid);
+ virtual bool HaveCoins(const uint256 &txid);
// Retrieve the block index whose state this CCoinsView currently represents
virtual CBlockIndex *GetBestBlock();
@@ -2142,9 +2151,9 @@ protected:
public:
CCoinsViewBacked(CCoinsView &viewIn);
- bool GetCoins(uint256 txid, CCoins &coins);
- bool SetCoins(uint256 txid, const CCoins &coins);
- bool HaveCoins(uint256 txid);
+ bool GetCoins(const uint256 &txid, CCoins &coins);
+ bool SetCoins(const uint256 &txid, const CCoins &coins);
+ bool HaveCoins(const uint256 &txid);
CBlockIndex *GetBestBlock();
bool SetBestBlock(CBlockIndex *pindex);
void SetBackend(CCoinsView &viewIn);
@@ -2163,9 +2172,9 @@ public:
CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false);
// Standard CCoinsView methods
- bool GetCoins(uint256 txid, CCoins &coins);
- bool SetCoins(uint256 txid, const CCoins &coins);
- bool HaveCoins(uint256 txid);
+ bool GetCoins(const uint256 &txid, CCoins &coins);
+ bool SetCoins(const uint256 &txid, const CCoins &coins);
+ bool HaveCoins(const uint256 &txid);
CBlockIndex *GetBestBlock();
bool SetBestBlock(CBlockIndex *pindex);
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex);
@@ -2173,7 +2182,7 @@ public:
// Return a modifiable reference to a CCoins. Check HaveCoins first.
// Many methods explicitly require a CCoinsViewCache because of this method, to reduce
// copying.
- CCoins &GetCoins(uint256 txid);
+ CCoins &GetCoins(const uint256 &txid);
// Push the modifications applied to this cache to its base.
// Failure to call this method before destruction will cause the changes to be forgotten.
@@ -2183,7 +2192,7 @@ public:
unsigned int GetCacheSize();
private:
- std::map<uint256,CCoins>::iterator FetchCoins(uint256 txid);
+ std::map<uint256,CCoins>::iterator FetchCoins(const uint256 &txid);
};
/** CCoinsView that brings transactions from a memorypool into view.
@@ -2195,8 +2204,8 @@ protected:
public:
CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn);
- bool GetCoins(uint256 txid, CCoins &coins);
- bool HaveCoins(uint256 txid);
+ bool GetCoins(const uint256 &txid, CCoins &coins);
+ bool HaveCoins(const uint256 &txid);
};
/** Global variable that points to the active CCoinsView (protected by cs_main) */
diff --git a/src/txdb.cpp b/src/txdb.cpp
index 8c01158254..ae7aceb7f1 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -22,17 +22,17 @@ void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) {
}
-bool CCoinsViewDB::GetCoins(uint256 txid, CCoins &coins) {
+bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) {
return db.Read(make_pair('c', txid), coins);
}
-bool CCoinsViewDB::SetCoins(uint256 txid, const CCoins &coins) {
+bool CCoinsViewDB::SetCoins(const uint256 &txid, const CCoins &coins) {
CLevelDBBatch batch;
BatchWriteCoins(batch, txid, coins);
return db.WriteBatch(batch);
}
-bool CCoinsViewDB::HaveCoins(uint256 txid) {
+bool CCoinsViewDB::HaveCoins(const uint256 &txid) {
return db.Exists(make_pair('c', txid));
}
diff --git a/src/txdb.h b/src/txdb.h
index eb8f574e46..f59fc5da86 100644
--- a/src/txdb.h
+++ b/src/txdb.h
@@ -16,9 +16,9 @@ protected:
public:
CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
- bool GetCoins(uint256 txid, CCoins &coins);
- bool SetCoins(uint256 txid, const CCoins &coins);
- bool HaveCoins(uint256 txid);
+ bool GetCoins(const uint256 &txid, CCoins &coins);
+ bool SetCoins(const uint256 &txid, const CCoins &coins);
+ bool HaveCoins(const uint256 &txid);
CBlockIndex *GetBestBlock();
bool SetBestBlock(CBlockIndex *pindex);
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex);