aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2014-08-24 14:39:38 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2014-08-24 14:47:41 +0200
commit41abb021227568b321be8073eeebb0b9ab654639 (patch)
tree0464515dd0e9dd8d35f7321368eb6a96d8a68e21
parent087eb43cff13e3ba3cc34f047acaab861f723204 (diff)
parentfff7455deda80bf483422dd7d7c2446e93522f2d (diff)
Merge pull request #4683
fff7455 Make CScript::clear() release its memory (Pieter Wuille) b0875eb Allow BatchWrite to destroy its input, reducing copying (Pieter Wuille)
-rw-r--r--src/coins.cpp16
-rw-r--r--src/coins.h10
-rw-r--r--src/script.h6
-rw-r--r--src/txdb.cpp7
-rw-r--r--src/txdb.h2
5 files changed, 27 insertions, 14 deletions
diff --git a/src/coins.cpp b/src/coins.cpp
index fe40911db7..6137b51c55 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -57,7 +57,7 @@ bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return fal
bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
uint256 CCoinsView::GetBestBlock() { return uint256(0); }
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; }
@@ -68,7 +68,7 @@ bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(t
uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); }
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); }
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
@@ -130,17 +130,19 @@ bool CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
return true;
}
-bool CCoinsViewCache::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
- for (CCoinsMap::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
- cacheCoins[it->first] = it->second;
+bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
+ for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
+ cacheCoins[it->first].swap(it->second);
+ CCoinsMap::iterator itOld = it++;
+ mapCoins.erase(itOld);
+ }
hashBlock = hashBlockIn;
return true;
}
bool CCoinsViewCache::Flush() {
bool fOk = base->BatchWrite(cacheCoins, hashBlock);
- if (fOk)
- cacheCoins.clear();
+ cacheCoins.clear();
return fOk;
}
diff --git a/src/coins.h b/src/coins.h
index ff60288163..2b657299e3 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -291,8 +291,9 @@ public:
// Modify the currently active block hash
virtual bool SetBestBlock(const uint256 &hashBlock);
- // Do a bulk modification (multiple SetCoins + one SetBestBlock)
- virtual bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
+ // Do a bulk modification (multiple SetCoins + one SetBestBlock).
+ // The passed mapCoins can be modified.
+ virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
// Calculate statistics about the unspent transaction output set
virtual bool GetStats(CCoinsStats &stats);
@@ -316,7 +317,7 @@ public:
uint256 GetBestBlock();
bool SetBestBlock(const uint256 &hashBlock);
void SetBackend(CCoinsView &viewIn);
- bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
+ bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
bool GetStats(CCoinsStats &stats);
};
@@ -337,7 +338,7 @@ public:
bool HaveCoins(const uint256 &txid);
uint256 GetBestBlock();
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.
// 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.
// 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();
// Calculate the size of the cache (in number of transactions)
diff --git a/src/script.h b/src/script.h
index 7cb863d1c9..1e2cc94efe 100644
--- a/src/script.h
+++ b/src/script.h
@@ -730,6 +730,12 @@ public:
{
return CScriptID(Hash160(*this));
}
+
+ void clear()
+ {
+ // The default std::vector::clear() does not release memory.
+ std::vector<unsigned char>().swap(*this);
+ }
};
/** Compact serializer for scripts.
diff --git a/src/txdb.cpp b/src/txdb.cpp
index d3d05c58d7..7c0683aaf3 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -54,12 +54,15 @@ bool CCoinsViewDB::SetBestBlock(const uint256 &hashBlock) {
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());
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);
+ CCoinsMap::iterator itOld = it++;
+ mapCoins.erase(itOld);
+ }
if (hashBlock != uint256(0))
BatchWriteHashBestChain(batch, hashBlock);
diff --git a/src/txdb.h b/src/txdb.h
index 7d670c2542..099f151776 100644
--- a/src/txdb.h
+++ b/src/txdb.h
@@ -37,7 +37,7 @@ public:
bool HaveCoins(const uint256 &txid);
uint256 GetBestBlock();
bool SetBestBlock(const uint256 &hashBlock);
- bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
+ bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
bool GetStats(CCoinsStats &stats);
};