Allow BatchWrite to destroy its input, reducing copying
This commit is contained in:
parent
5cd00bc8cb
commit
b0875eb3fe
4 changed files with 21 additions and 14 deletions
|
@ -57,7 +57,7 @@ bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return fal
|
||||||
bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
|
bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
|
||||||
uint256 CCoinsView::GetBestBlock() { return uint256(0); }
|
uint256 CCoinsView::GetBestBlock() { return uint256(0); }
|
||||||
bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; }
|
bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; }
|
||||||
bool CCoinsView::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
|
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
|
||||||
bool CCoinsView::GetStats(CCoinsStats &stats) { return false; }
|
bool CCoinsView::GetStats(CCoinsStats &stats) { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(t
|
||||||
uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
|
uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
|
||||||
bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); }
|
bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); }
|
||||||
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
|
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
|
||||||
bool CCoinsViewBacked::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
|
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
|
||||||
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); }
|
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); }
|
||||||
|
|
||||||
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
|
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
|
||||||
|
@ -130,17 +130,19 @@ bool CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewCache::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
|
bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
|
||||||
for (CCoinsMap::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
|
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
|
||||||
cacheCoins[it->first] = it->second;
|
cacheCoins[it->first].swap(it->second);
|
||||||
|
CCoinsMap::iterator itOld = it++;
|
||||||
|
mapCoins.erase(itOld);
|
||||||
|
}
|
||||||
hashBlock = hashBlockIn;
|
hashBlock = hashBlockIn;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewCache::Flush() {
|
bool CCoinsViewCache::Flush() {
|
||||||
bool fOk = base->BatchWrite(cacheCoins, hashBlock);
|
bool fOk = base->BatchWrite(cacheCoins, hashBlock);
|
||||||
if (fOk)
|
cacheCoins.clear();
|
||||||
cacheCoins.clear();
|
|
||||||
return fOk;
|
return fOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/coins.h
10
src/coins.h
|
@ -291,8 +291,9 @@ public:
|
||||||
// Modify the currently active block hash
|
// Modify the currently active block hash
|
||||||
virtual bool SetBestBlock(const uint256 &hashBlock);
|
virtual bool SetBestBlock(const uint256 &hashBlock);
|
||||||
|
|
||||||
// Do a bulk modification (multiple SetCoins + one SetBestBlock)
|
// Do a bulk modification (multiple SetCoins + one SetBestBlock).
|
||||||
virtual bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
|
// The passed mapCoins can be modified.
|
||||||
|
virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
|
||||||
|
|
||||||
// Calculate statistics about the unspent transaction output set
|
// Calculate statistics about the unspent transaction output set
|
||||||
virtual bool GetStats(CCoinsStats &stats);
|
virtual bool GetStats(CCoinsStats &stats);
|
||||||
|
@ -316,7 +317,7 @@ public:
|
||||||
uint256 GetBestBlock();
|
uint256 GetBestBlock();
|
||||||
bool SetBestBlock(const uint256 &hashBlock);
|
bool SetBestBlock(const uint256 &hashBlock);
|
||||||
void SetBackend(CCoinsView &viewIn);
|
void SetBackend(CCoinsView &viewIn);
|
||||||
bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
|
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
|
||||||
bool GetStats(CCoinsStats &stats);
|
bool GetStats(CCoinsStats &stats);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -337,7 +338,7 @@ public:
|
||||||
bool HaveCoins(const uint256 &txid);
|
bool HaveCoins(const uint256 &txid);
|
||||||
uint256 GetBestBlock();
|
uint256 GetBestBlock();
|
||||||
bool SetBestBlock(const uint256 &hashBlock);
|
bool SetBestBlock(const uint256 &hashBlock);
|
||||||
bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
|
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
|
||||||
|
|
||||||
// Return a modifiable reference to a CCoins. Check HaveCoins first.
|
// Return a modifiable reference to a CCoins. Check HaveCoins first.
|
||||||
// Many methods explicitly require a CCoinsViewCache because of this method, to reduce
|
// Many methods explicitly require a CCoinsViewCache because of this method, to reduce
|
||||||
|
@ -346,6 +347,7 @@ public:
|
||||||
|
|
||||||
// Push the modifications applied to this cache to its base.
|
// Push the modifications applied to this cache to its base.
|
||||||
// Failure to call this method before destruction will cause the changes to be forgotten.
|
// Failure to call this method before destruction will cause the changes to be forgotten.
|
||||||
|
// If false is returned, the state of this cache (and its backing view) will be undefined.
|
||||||
bool Flush();
|
bool Flush();
|
||||||
|
|
||||||
// Calculate the size of the cache (in number of transactions)
|
// Calculate the size of the cache (in number of transactions)
|
||||||
|
|
|
@ -54,12 +54,15 @@ bool CCoinsViewDB::SetBestBlock(const uint256 &hashBlock) {
|
||||||
return db.WriteBatch(batch);
|
return db.WriteBatch(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewDB::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) {
|
bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
|
||||||
LogPrint("coindb", "Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size());
|
LogPrint("coindb", "Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size());
|
||||||
|
|
||||||
CLevelDBBatch batch;
|
CLevelDBBatch batch;
|
||||||
for (CCoinsMap::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
|
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
|
||||||
BatchWriteCoins(batch, it->first, it->second);
|
BatchWriteCoins(batch, it->first, it->second);
|
||||||
|
CCoinsMap::iterator itOld = it++;
|
||||||
|
mapCoins.erase(itOld);
|
||||||
|
}
|
||||||
if (hashBlock != uint256(0))
|
if (hashBlock != uint256(0))
|
||||||
BatchWriteHashBestChain(batch, hashBlock);
|
BatchWriteHashBestChain(batch, hashBlock);
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
bool HaveCoins(const uint256 &txid);
|
bool HaveCoins(const uint256 &txid);
|
||||||
uint256 GetBestBlock();
|
uint256 GetBestBlock();
|
||||||
bool SetBestBlock(const uint256 &hashBlock);
|
bool SetBestBlock(const uint256 &hashBlock);
|
||||||
bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
|
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
|
||||||
bool GetStats(CCoinsStats &stats);
|
bool GetStats(CCoinsStats &stats);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue