mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
txgraph: Reuse discarded chunkindex entries (optimization)
This commit is contained in:
parent
82054fa25f
commit
e3d3ad9723
1 changed files with 49 additions and 22 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <util/bitset.h>
|
||||
#include <util/check.h>
|
||||
#include <util/feefrac.h>
|
||||
#include <util/vector.h>
|
||||
|
||||
#include <compare>
|
||||
#include <memory>
|
||||
|
@ -312,6 +313,8 @@ private:
|
|||
ChunkIndex m_main_chunkindex;
|
||||
/** Number of index-observing objects in existence (BlockBuilderImpls). */
|
||||
size_t m_main_chunkindex_observers{0};
|
||||
/** Cache of discarded ChunkIndex node handles to re-use, avoiding additional allocation. */
|
||||
std::vector<ChunkIndex::node_type> m_main_chunkindex_discarded;
|
||||
|
||||
/** A Locator that describes whether, where, and in which Cluster an Entry appears.
|
||||
* Every Entry has MAX_LEVELS locators, as it may appear in one Cluster per level.
|
||||
|
@ -431,6 +434,10 @@ public:
|
|||
void ClearLocator(int level, GraphIndex index) noexcept;
|
||||
/** Find which Clusters in main conflict with ones in staging. */
|
||||
std::vector<Cluster*> GetConflicts() const noexcept;
|
||||
/** Clear an Entry's ChunkData. */
|
||||
void ClearChunkData(Entry& entry) noexcept;
|
||||
/** Give an Entry a ChunkData object. */
|
||||
void CreateChunkData(GraphIndex idx, LinearizationIndex chunk_count) noexcept;
|
||||
|
||||
// Functions for handling Refs.
|
||||
|
||||
|
@ -584,6 +591,37 @@ public:
|
|||
void Skip() noexcept final;
|
||||
};
|
||||
|
||||
void TxGraphImpl::ClearChunkData(Entry& entry) noexcept
|
||||
{
|
||||
if (entry.m_main_chunkindex_iterator != m_main_chunkindex.end()) {
|
||||
Assume(m_main_chunkindex_observers == 0);
|
||||
// If the Entry has a non-empty m_main_chunkindex_iterator, extract it, and move the handle
|
||||
// to the cache of discarded chunkindex entries.
|
||||
m_main_chunkindex_discarded.emplace_back(m_main_chunkindex.extract(entry.m_main_chunkindex_iterator));
|
||||
entry.m_main_chunkindex_iterator = m_main_chunkindex.end();
|
||||
}
|
||||
}
|
||||
|
||||
void TxGraphImpl::CreateChunkData(GraphIndex idx, LinearizationIndex chunk_count) noexcept
|
||||
{
|
||||
auto& entry = m_entries[idx];
|
||||
if (!m_main_chunkindex_discarded.empty()) {
|
||||
// Reuse an discarded node handle.
|
||||
auto& node = m_main_chunkindex_discarded.back().value();
|
||||
node.m_graph_index = idx;
|
||||
node.m_chunk_count = chunk_count;
|
||||
auto insert_result = m_main_chunkindex.insert(std::move(m_main_chunkindex_discarded.back()));
|
||||
Assume(insert_result.inserted);
|
||||
entry.m_main_chunkindex_iterator = insert_result.position;
|
||||
m_main_chunkindex_discarded.pop_back();
|
||||
} else {
|
||||
// Construct a new entry.
|
||||
auto emplace_result = m_main_chunkindex.emplace(idx, chunk_count);
|
||||
Assume(emplace_result.second);
|
||||
entry.m_main_chunkindex_iterator = emplace_result.first;
|
||||
}
|
||||
}
|
||||
|
||||
void TxGraphImpl::ClearLocator(int level, GraphIndex idx) noexcept
|
||||
{
|
||||
auto& entry = m_entries[idx];
|
||||
|
@ -606,11 +644,7 @@ void TxGraphImpl::ClearLocator(int level, GraphIndex idx) noexcept
|
|||
--m_staging_clusterset->m_txcount;
|
||||
}
|
||||
}
|
||||
if (level == 0 && entry.m_main_chunkindex_iterator != m_main_chunkindex.end()) {
|
||||
Assume(m_main_chunkindex_observers == 0);
|
||||
m_main_chunkindex.erase(entry.m_main_chunkindex_iterator);
|
||||
entry.m_main_chunkindex_iterator = m_main_chunkindex.end();
|
||||
}
|
||||
if (level == 0) ClearChunkData(entry);
|
||||
}
|
||||
|
||||
void Cluster::Updated(TxGraphImpl& graph) noexcept
|
||||
|
@ -618,13 +652,9 @@ void Cluster::Updated(TxGraphImpl& graph) noexcept
|
|||
// Update all the Locators for this Cluster's Entry objects.
|
||||
for (DepGraphIndex idx : m_linearization) {
|
||||
auto& entry = graph.m_entries[m_mapping[idx]];
|
||||
if (m_level == 0 && entry.m_main_chunkindex_iterator != graph.m_main_chunkindex.end()) {
|
||||
// Destroy any potential ChunkData prior to modifying the Cluster (as that could
|
||||
// invalidate its ordering).
|
||||
Assume(graph.m_main_chunkindex_observers == 0);
|
||||
graph.m_main_chunkindex.erase(entry.m_main_chunkindex_iterator);
|
||||
entry.m_main_chunkindex_iterator = graph.m_main_chunkindex.end();
|
||||
}
|
||||
// Discard any potential ChunkData prior to modifying the Cluster (as that could
|
||||
// invalidate its ordering).
|
||||
if (m_level == 0) graph.ClearChunkData(entry);
|
||||
entry.m_locator[m_level].SetPresent(this, idx);
|
||||
}
|
||||
// If this is for the main graph (level = 0), and the Cluster's quality is ACCEPTABLE or
|
||||
|
@ -651,9 +681,7 @@ void Cluster::Updated(TxGraphImpl& graph) noexcept
|
|||
chunk.transactions.Reset(idx);
|
||||
if (chunk.transactions.None()) {
|
||||
// Last transaction in the chunk.
|
||||
auto [it, inserted] = graph.m_main_chunkindex.emplace(graph_idx, chunk_count);
|
||||
Assume(inserted);
|
||||
entry.m_main_chunkindex_iterator = it;
|
||||
graph.CreateChunkData(graph_idx, chunk_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -912,13 +940,9 @@ void Cluster::Merge(TxGraphImpl& graph, Cluster& other) noexcept
|
|||
// feerates, as Updated() will be invoked by Cluster::ApplyDependencies on the resulting
|
||||
// merged Cluster later anyway).
|
||||
auto& entry = graph.m_entries[idx];
|
||||
if (m_level == 0 && entry.m_main_chunkindex_iterator != graph.m_main_chunkindex.end()) {
|
||||
// Destroy any potential ChunkData prior to modifying the Cluster (as that could
|
||||
// invalidate its ordering).
|
||||
Assume(graph.m_main_chunkindex_observers == 0);
|
||||
graph.m_main_chunkindex.erase(entry.m_main_chunkindex_iterator);
|
||||
entry.m_main_chunkindex_iterator = graph.m_main_chunkindex.end();
|
||||
}
|
||||
// Discard any potential ChunkData prior to modifying the Cluster (as that could
|
||||
// invalidate its ordering).
|
||||
if (m_level == 0) graph.ClearChunkData(entry);
|
||||
entry.m_locator[m_level].SetPresent(this, new_pos);
|
||||
}
|
||||
// Purge the other Cluster, now that everything has been moved.
|
||||
|
@ -1161,6 +1185,9 @@ void TxGraphImpl::Compact() noexcept
|
|||
if (!m_staging_clusterset->m_removed.empty()) return;
|
||||
}
|
||||
|
||||
// Release memory used by discarded ChunkData index entries.
|
||||
ClearShrink(m_main_chunkindex_discarded);
|
||||
|
||||
// Sort the GraphIndexes that need to be cleaned up. They are sorted in reverse, so the last
|
||||
// ones get processed first. This means earlier-processed GraphIndexes will not cause moving of
|
||||
// later-processed ones during the "swap with end of m_entries" step below (which might
|
||||
|
|
Loading…
Add table
Reference in a new issue