validation: don't reallocate cache for short-lived CCoinsViewCache
A few temporary `CCoinsViewCache`'s are destructed right after the `Flush()`, therefore it is not necessary to call `ReallocateCache` to recreate them right before they're killed anyway. * `Flush()` - retains existing functionality; * `Flush(/*will_reuse_cache=*/false)` - skips destruction and reallocation of the parent cache since it will soon go out of scope anyway; For the `will_reuse_cache` parameter we want to see exactly which ones will reallocate memory and which won't - since both can be valid usages. This change was based on a subset of https://github.com/bitcoin/bitcoin/pull/28945. Co-authored-by: Martin Ankerl <martin.ankerl@gmail.com>
This commit is contained in:
1 parent
c8f5e446dc
commit
0ac969cddf
5 files changed
+12
-16
No files matched your search
+4
-2
@@ -249,12 +249,14 @@ bool CCoinsViewCache::BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &ha
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewCache::Flush() {
|
bool CCoinsViewCache::Flush(bool will_reuse_cache) {
|
||||||
auto cursor{CoinsViewCacheCursor(m_sentinel, cacheCoins, /*will_erase=*/true)};
|
auto cursor{CoinsViewCacheCursor(m_sentinel, cacheCoins, /*will_erase=*/true)};
|
||||||
bool fOk = base->BatchWrite(cursor, hashBlock);
|
bool fOk = base->BatchWrite(cursor, hashBlock);
|
||||||
if (fOk) {
|
if (fOk) {
|
||||||
cacheCoins.clear();
|
cacheCoins.clear();
|
||||||
ReallocateCache();
|
if (will_reuse_cache) {
|
||||||
|
ReallocateCache();
|
||||||
|
}
|
||||||
cachedCoinsUsage = 0;
|
cachedCoinsUsage = 0;
|
||||||
}
|
}
|
||||||
return fOk;
|
return fOk;
|
||||||
|
|||||||
+3
-1
@@ -439,9 +439,11 @@ public:
|
|||||||
* Push the modifications applied to this cache to its base and wipe local state.
|
* Push the modifications applied to this cache to its base and wipe local state.
|
||||||
* Failure to call this method or Sync() before destruction will cause the changes
|
* Failure to call this method or Sync() before destruction will cause the changes
|
||||||
* to be forgotten.
|
* to be forgotten.
|
||||||
|
* If will_reuse_cache is false, the cache will retain the same memory footprint
|
||||||
|
* after flushing and should be destroyed to deallocate.
|
||||||
* If false is returned, the state of this cache (and its backing view) will be undefined.
|
* If false is returned, the state of this cache (and its backing view) will be undefined.
|
||||||
*/
|
*/
|
||||||
bool Flush();
|
bool Flush(bool will_reuse_cache = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Push the modifications applied to this cache to its base while retaining
|
* Push the modifications applied to this cache to its base while retaining
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&] {
|
[&] {
|
||||||
(void)coins_view_cache.Flush();
|
(void)coins_view_cache.Flush(/*will_reuse_cache=*/fuzzed_data_provider.ConsumeBool());
|
||||||
},
|
},
|
||||||
[&] {
|
[&] {
|
||||||
(void)coins_view_cache.Sync();
|
(void)coins_view_cache.Sync();
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ FUZZ_TARGET(coinscache_sim)
|
|||||||
// Apply to simulation data.
|
// Apply to simulation data.
|
||||||
flush();
|
flush();
|
||||||
// Apply to real caches.
|
// Apply to real caches.
|
||||||
caches.back()->Flush();
|
caches.back()->Flush(/*will_reuse_cache=*/provider.ConsumeBool());
|
||||||
},
|
},
|
||||||
|
|
||||||
[&]() { // Sync.
|
[&]() { // Sync.
|
||||||
@@ -402,14 +402,6 @@ FUZZ_TARGET(coinscache_sim)
|
|||||||
caches.back()->Sync();
|
caches.back()->Sync();
|
||||||
},
|
},
|
||||||
|
|
||||||
[&]() { // Flush + ReallocateCache.
|
|
||||||
// Apply to simulation data.
|
|
||||||
flush();
|
|
||||||
// Apply to real caches.
|
|
||||||
caches.back()->Flush();
|
|
||||||
caches.back()->ReallocateCache();
|
|
||||||
},
|
|
||||||
|
|
||||||
[&]() { // GetCacheSize
|
[&]() { // GetCacheSize
|
||||||
(void)caches.back()->GetCacheSize();
|
(void)caches.back()->GetCacheSize();
|
||||||
},
|
},
|
||||||
|
|||||||
+3
-3
@@ -3036,7 +3036,7 @@ bool Chainstate::DisconnectTip(BlockValidationState& state, DisconnectedBlockTra
|
|||||||
LogError("DisconnectTip(): DisconnectBlock %s failed\n", pindexDelete->GetBlockHash().ToString());
|
LogError("DisconnectTip(): DisconnectBlock %s failed\n", pindexDelete->GetBlockHash().ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool flushed = view.Flush();
|
bool flushed = view.Flush(/*will_reuse_cache=*/false); // local CCoinsViewCache goes out of scope
|
||||||
assert(flushed);
|
assert(flushed);
|
||||||
}
|
}
|
||||||
LogDebug(BCLog::BENCH, "- Disconnect block: %.2fms\n",
|
LogDebug(BCLog::BENCH, "- Disconnect block: %.2fms\n",
|
||||||
@@ -3171,7 +3171,7 @@ bool Chainstate::ConnectTip(
|
|||||||
Ticks<MillisecondsDouble>(time_3 - time_2),
|
Ticks<MillisecondsDouble>(time_3 - time_2),
|
||||||
Ticks<SecondsDouble>(m_chainman.time_connect_total),
|
Ticks<SecondsDouble>(m_chainman.time_connect_total),
|
||||||
Ticks<MillisecondsDouble>(m_chainman.time_connect_total) / m_chainman.num_blocks_total);
|
Ticks<MillisecondsDouble>(m_chainman.time_connect_total) / m_chainman.num_blocks_total);
|
||||||
bool flushed = view.Flush();
|
bool flushed = view.Flush(/*will_reuse_cache=*/false); // local CCoinsViewCache goes out of scope
|
||||||
assert(flushed);
|
assert(flushed);
|
||||||
}
|
}
|
||||||
const auto time_4{SteadyClock::now()};
|
const auto time_4{SteadyClock::now()};
|
||||||
@@ -4950,7 +4950,7 @@ bool Chainstate::ReplayBlocks()
|
|||||||
}
|
}
|
||||||
|
|
||||||
cache.SetBestBlock(pindexNew->GetBlockHash());
|
cache.SetBestBlock(pindexNew->GetBlockHash());
|
||||||
cache.Flush();
|
cache.Flush(/*will_reuse_cache=*/false); // local CCoinsViewCache goes out of scope
|
||||||
m_chainman.GetNotifications().progress(bilingual_str{}, 100, false);
|
m_chainman.GetNotifications().progress(bilingual_str{}, 100, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user