Skip to content

Commit b1637a9

Browse files
committed
txgraph: avoid holes in DepGraph positions (mem optimization)
1 parent 2b1d302 commit b1637a9

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

src/txgraph.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,9 +1001,12 @@ bool Cluster::Split(TxGraphImpl& graph, int level) noexcept
10011001
// Iterate over the connected components of this Cluster's m_depgraph.
10021002
while (todo.Any()) {
10031003
auto component = m_depgraph.FindConnectedComponent(todo);
1004-
auto split_quality = component.Count() <= 2 ? QualityLevel::OPTIMAL : new_quality;
1005-
if (first && component == todo) {
1006-
// The existing Cluster is an entire component. Leave it be, but update its quality.
1004+
auto component_size = component.Count();
1005+
auto split_quality = component_size <= 2 ? QualityLevel::OPTIMAL : new_quality;
1006+
if (first && component == todo && SetType::Fill(component_size) == component) {
1007+
// The existing Cluster is an entire component, without holes. Leave it be, but update
1008+
// its quality. If there are holes, we continue, so that the Cluster is reconstructed
1009+
// without holes, reducing memory usage.
10071010
Assume(todo == m_depgraph.Positions());
10081011
graph.SetClusterQuality(level, m_quality, m_setindex, split_quality);
10091012
// If this made the quality ACCEPTABLE or OPTIMAL, we need to compute and cache its
@@ -1064,12 +1067,11 @@ void Cluster::Merge(TxGraphImpl& graph, int level, Cluster& other) noexcept
10641067
auto idx = other.m_mapping[pos];
10651068
// Copy the transaction into this Cluster, and remember its position.
10661069
auto new_pos = m_depgraph.AddTransaction(other.m_depgraph.FeeRate(pos));
1070+
// Since this cluster must have been made hole-free before being merged into, all added
1071+
// transactions should appear at the end.
1072+
Assume(new_pos == m_mapping.size());
10671073
remap[pos] = new_pos;
1068-
if (new_pos == m_mapping.size()) {
1069-
m_mapping.push_back(idx);
1070-
} else {
1071-
m_mapping[new_pos] = idx;
1072-
}
1074+
m_mapping.push_back(idx);
10731075
m_linearization.push_back(new_pos);
10741076
// Copy the transaction's dependencies, translating them using remap. Note that since
10751077
// pos iterates over other.m_linearization, which is in topological order, all parents
@@ -2286,6 +2288,10 @@ void Cluster::SanityCheck(const TxGraphImpl& graph, int level) const
22862288
assert(m_depgraph.PositionRange() == m_mapping.size());
22872289
// The linearization for this Cluster must contain every transaction once.
22882290
assert(m_depgraph.TxCount() == m_linearization.size());
2291+
// Unless a split is to be applied, the cluster cannot have any holes.
2292+
if (!NeedsSplitting()) {
2293+
assert(m_depgraph.Positions() == SetType::Fill(m_depgraph.TxCount()));
2294+
}
22892295

22902296
// Compute the chunking of m_linearization.
22912297
LinearizationChunking linchunking(m_depgraph, m_linearization);

0 commit comments

Comments
 (0)