Skip to content

Commit 6b037ce

Browse files
committed
txgraph: Cache oversizedness of graphs (optimization)
1 parent 8c70688 commit 6b037ce

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

src/txgraph.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ class TxGraphImpl final : public TxGraph
230230
/** Total number of transactions in this graph (sum of all transaction counts in all
231231
* Clusters, and for staging also those inherited from the main ClusterSet). */
232232
GraphIndex m_txcount{0};
233+
/** Whether this graph is oversized (if known). This roughly matches
234+
* m_group_data->m_group_oversized, but may be known even if m_group_data is not. */
235+
std::optional<bool> m_oversized{false};
233236

234237
ClusterSet() noexcept = default;
235238
};
@@ -1204,6 +1207,7 @@ void TxGraphImpl::GroupClusters(int level) noexcept
12041207
}
12051208
Assume(an_deps_it == an_deps.end());
12061209
Assume(an_clusters_it == an_clusters.end());
1210+
clusterset.m_oversized = clusterset.m_group_data->m_group_oversized;
12071211
Compact();
12081212
}
12091213

@@ -1237,6 +1241,8 @@ void TxGraphImpl::Merge(std::span<Cluster*> to_merge) noexcept
12371241
void TxGraphImpl::ApplyDependencies(int level) noexcept
12381242
{
12391243
auto& clusterset = GetClusterSet(level);
1244+
// Do not bother computing groups if we already know the result will be oversized.
1245+
if (clusterset.m_oversized == true) return;
12401246
// Compute the groups of to-be-merged Clusters (which also applies all removals, and splits).
12411247
GroupClusters(level);
12421248
Assume(clusterset.m_group_data.has_value());
@@ -1348,6 +1354,7 @@ void TxGraphImpl::RemoveTransaction(const Ref& arg) noexcept
13481354
clusterset.m_to_remove.push_back(GetRefIndex(arg));
13491355
// Wipe m_group_data (as it will need to be recomputed).
13501356
clusterset.m_group_data.reset();
1357+
if (clusterset.m_oversized == true) clusterset.m_oversized = std::nullopt;
13511358
}
13521359

13531360
void TxGraphImpl::AddDependency(const Ref& parent, const Ref& child) noexcept
@@ -1370,6 +1377,7 @@ void TxGraphImpl::AddDependency(const Ref& parent, const Ref& child) noexcept
13701377
clusterset.m_deps_to_add.emplace_back(GetRefIndex(parent), GetRefIndex(child));
13711378
// Wipe m_group_data (as it will need to be recomputed).
13721379
clusterset.m_group_data.reset();
1380+
if (clusterset.m_oversized == false) clusterset.m_oversized = std::nullopt;
13731381
}
13741382

13751383
bool TxGraphImpl::Exists(const Ref& arg, bool main_only) noexcept
@@ -1539,12 +1547,17 @@ FeePerWeight TxGraphImpl::GetMainChunkFeerate(const Ref& arg) noexcept
15391547
bool TxGraphImpl::IsOversized(bool main_only) noexcept
15401548
{
15411549
size_t level = GetSpecifiedLevel(main_only);
1550+
auto& clusterset = GetClusterSet(level);
1551+
if (clusterset.m_oversized.has_value()) {
1552+
// Return cached value if known.
1553+
return *clusterset.m_oversized;
1554+
}
15421555
// Find which Clusters will need to be merged together, as that is where the oversize
15431556
// property is assessed.
15441557
GroupClusters(level);
1545-
auto& clusterset = GetClusterSet(level);
15461558
Assume(clusterset.m_group_data.has_value());
1547-
return clusterset.m_group_data->m_group_oversized;
1559+
clusterset.m_oversized = clusterset.m_group_data->m_group_oversized;
1560+
return *clusterset.m_oversized;
15481561
}
15491562

15501563
void TxGraphImpl::StartStaging() noexcept
@@ -1553,8 +1566,10 @@ void TxGraphImpl::StartStaging() noexcept
15531566
Assume(!m_staging_clusterset.has_value());
15541567
// Apply all remaining dependencies in main before creating a staging graph. Once staging
15551568
// exists, we cannot merge Clusters anymore (because of interference with Clusters being
1556-
// pulled into staging), so to make sure all inspectors are available (if not oversized),
1557-
// do all merging work now. This also involves applying all removals.
1569+
// pulled into staging), so to make sure all inspectors are available (if not oversized), do
1570+
// all merging work now. Call SplitAll() first, so that even if ApplyDependencies does not do
1571+
// any thing due to knowing the result is oversized, splitting is still performed.
1572+
SplitAll(0);
15581573
ApplyDependencies(0);
15591574
// Construct the staging ClusterSet.
15601575
m_staging_clusterset.emplace();
@@ -1563,6 +1578,8 @@ void TxGraphImpl::StartStaging() noexcept
15631578
m_staging_clusterset->m_txcount = m_main_clusterset.m_txcount;
15641579
m_staging_clusterset->m_deps_to_add = m_main_clusterset.m_deps_to_add;
15651580
m_staging_clusterset->m_group_data = m_main_clusterset.m_group_data;
1581+
m_staging_clusterset->m_oversized = m_main_clusterset.m_oversized;
1582+
Assume(m_staging_clusterset->m_oversized.has_value());
15661583
}
15671584

15681585
void TxGraphImpl::AbortStaging() noexcept
@@ -1612,6 +1629,7 @@ void TxGraphImpl::CommitStaging() noexcept
16121629
m_main_clusterset.m_deps_to_add = std::move(m_staging_clusterset->m_deps_to_add);
16131630
m_main_clusterset.m_to_remove = std::move(m_staging_clusterset->m_to_remove);
16141631
m_main_clusterset.m_group_data = std::move(m_staging_clusterset->m_group_data);
1632+
m_main_clusterset.m_oversized = std::move(m_staging_clusterset->m_oversized);
16151633
m_main_clusterset.m_txcount = std::move(m_staging_clusterset->m_txcount);
16161634
// Delete the old staging graph, after all its information was moved to main.
16171635
m_staging_clusterset.reset();
@@ -1789,6 +1807,11 @@ void TxGraphImpl::SanityCheck() const
17891807
if (!clusterset.m_deps_to_add.empty()) compact_possible = false;
17901808
if (!clusterset.m_to_remove.empty()) compact_possible = false;
17911809
if (!clusterset.m_removed.empty()) compact_possible = false;
1810+
1811+
// If m_group_data exists, its m_group_oversized must match m_oversized.
1812+
if (clusterset.m_group_data.has_value()) {
1813+
assert(clusterset.m_oversized == clusterset.m_group_data->m_group_oversized);
1814+
}
17921815
}
17931816

17941817
// Verify that the contents of m_unlinked matches what was expected based on the Entry vector.

0 commit comments

Comments
 (0)