mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-05-31 16:24:48 +02:00
coins: pass linked list of flagged entries to BatchWrite
BatchWrite now iterates through the linked list of flagged entries instead of the entire coinsCache map. Co-Authored-By: l0rinc <pap.lorinc@gmail.com>
This commit is contained in:
@@ -55,9 +55,9 @@ public:
|
||||
|
||||
uint256 GetBestBlock() const override { return hashBestBlock_; }
|
||||
|
||||
bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock, bool erase = true) override
|
||||
bool BatchWrite(CoinsViewCacheCursor& cursor, const uint256& hashBlock) override
|
||||
{
|
||||
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end(); it = erase ? mapCoins.erase(it) : std::next(it)) {
|
||||
for (auto it{cursor.Begin()}; it != cursor.End(); it = cursor.NextAndMaybeErase(*it)){
|
||||
if (it->second.IsDirty()) {
|
||||
// Same optimization used in CCoinsViewDB is to only write dirty entries.
|
||||
map_[it->first] = it->second.coin;
|
||||
@@ -618,8 +618,9 @@ void WriteCoinsViewEntry(CCoinsView& view, CAmount value, char flags)
|
||||
sentinel.second.SelfRef(sentinel);
|
||||
CCoinsMapMemoryResource resource;
|
||||
CCoinsMap map{0, CCoinsMap::hasher{}, CCoinsMap::key_equal{}, &resource};
|
||||
InsertCoinsMapEntry(map, sentinel, value, flags);
|
||||
BOOST_CHECK(view.BatchWrite(map, {}));
|
||||
auto usage{InsertCoinsMapEntry(map, sentinel, value, flags)};
|
||||
auto cursor{CoinsViewCacheCursor(usage, sentinel, map, /*will_erase=*/true)};
|
||||
BOOST_CHECK(view.BatchWrite(cursor, {}));
|
||||
}
|
||||
|
||||
class SingleEntryCacheTest
|
||||
|
||||
@@ -122,6 +122,7 @@ FUZZ_TARGET(coins_view, .init = initialize_coins_view)
|
||||
[&] {
|
||||
CoinsCachePair sentinel{};
|
||||
sentinel.second.SelfRef(sentinel);
|
||||
size_t usage{0};
|
||||
CCoinsMapMemoryResource resource;
|
||||
CCoinsMap coins_map{0, SaltedOutpointHasher{/*deterministic=*/true}, CCoinsMap::key_equal{}, &resource};
|
||||
LIMITED_WHILE(good_data && fuzzed_data_provider.ConsumeBool(), 10'000)
|
||||
@@ -140,10 +141,12 @@ FUZZ_TARGET(coins_view, .init = initialize_coins_view)
|
||||
}
|
||||
auto it{coins_map.emplace(random_out_point, std::move(coins_cache_entry)).first};
|
||||
it->second.AddFlags(flags, *it, sentinel);
|
||||
usage += it->second.coin.DynamicMemoryUsage();
|
||||
}
|
||||
bool expected_code_path = false;
|
||||
try {
|
||||
coins_view_cache.BatchWrite(coins_map, fuzzed_data_provider.ConsumeBool() ? ConsumeUInt256(fuzzed_data_provider) : coins_view_cache.GetBestBlock());
|
||||
auto cursor{CoinsViewCacheCursor(usage, sentinel, coins_map, /*will_erase=*/true)};
|
||||
coins_view_cache.BatchWrite(cursor, fuzzed_data_provider.ConsumeBool() ? ConsumeUInt256(fuzzed_data_provider) : coins_view_cache.GetBestBlock());
|
||||
expected_code_path = true;
|
||||
} catch (const std::logic_error& e) {
|
||||
if (e.what() == std::string{"FRESH flag misapplied to coin that exists in parent cache"}) {
|
||||
|
||||
@@ -172,13 +172,13 @@ public:
|
||||
std::unique_ptr<CCoinsViewCursor> Cursor() const final { return {}; }
|
||||
size_t EstimateSize() const final { return m_data.size(); }
|
||||
|
||||
bool BatchWrite(CCoinsMap& data, const uint256&, bool erase) final
|
||||
bool BatchWrite(CoinsViewCacheCursor& cursor, const uint256&) final
|
||||
{
|
||||
for (auto it = data.begin(); it != data.end(); it = erase ? data.erase(it) : std::next(it)) {
|
||||
for (auto it{cursor.Begin()}; it != cursor.End(); it = cursor.NextAndMaybeErase(*it)) {
|
||||
if (it->second.IsDirty()) {
|
||||
if (it->second.coin.IsSpent() && (it->first.n % 5) != 4) {
|
||||
m_data.erase(it->first);
|
||||
} else if (erase) {
|
||||
} else if (cursor.WillErase(*it)) {
|
||||
m_data[it->first] = std::move(it->second.coin);
|
||||
} else {
|
||||
m_data[it->first] = it->second.coin;
|
||||
|
||||
Reference in New Issue
Block a user