Skip to content

Commit

Permalink
Allow BatchWrite to destroy its input, reducing copying
Browse files Browse the repository at this point in the history
  • Loading branch information
sipa committed Aug 24, 2014
1 parent 5cd00bc commit b0875eb
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 14 deletions.
16 changes: 9 additions & 7 deletions src/coins.cpp
Expand Up @@ -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; }




Expand All @@ -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()) {}
Expand Down Expand Up @@ -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;
} }


Expand Down
10 changes: 6 additions & 4 deletions src/coins.h
Expand Up @@ -291,8 +291,9 @@ class CCoinsView
// 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);
Expand All @@ -316,7 +317,7 @@ class CCoinsViewBacked : public CCoinsView
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);
}; };


Expand All @@ -337,7 +338,7 @@ class CCoinsViewCache : public CCoinsViewBacked
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
Expand All @@ -346,6 +347,7 @@ class CCoinsViewCache : public CCoinsViewBacked


// 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)
Expand Down
7 changes: 5 additions & 2 deletions src/txdb.cpp
Expand Up @@ -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);


Expand Down
2 changes: 1 addition & 1 deletion src/txdb.h
Expand Up @@ -37,7 +37,7 @@ class CCoinsViewDB : public CCoinsView
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);
}; };


Expand Down

0 comments on commit b0875eb

Please sign in to comment.