Skip to content

Commit 7680bb8

Browse files
committed
txgraph: keep track of Cluster memory usage (preparation)
1 parent 4ba562e commit 7680bb8

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

src/txgraph.cpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ class Cluster
153153
return m_quality == QualityLevel::NEEDS_SPLIT ||
154154
m_quality == QualityLevel::NEEDS_SPLIT_ACCEPTABLE;
155155
}
156+
/** Total memory usage currently for this Cluster, including all its dynamic memory, plus Cluster
157+
* structure itself, and ClusterSet::m_clusters entry. */
158+
size_t TotalMemoryUsage() const noexcept;
156159
/** Get the number of transactions in this Cluster. */
157160
LinearizationIndex GetTxCount() const noexcept { return m_linearization.size(); }
158161
/** Get the total size of the transactions in this Cluster. */
@@ -308,6 +311,9 @@ class TxGraphImpl final : public TxGraph
308311
GraphIndex m_txcount_oversized{0};
309312
/** Whether this graph is oversized (if known). */
310313
std::optional<bool> m_oversized{false};
314+
/** The combined TotalMemoryUsage of all clusters in this level (only Clusters that
315+
* are materialized; in staging, implicit Clusters from main are not counted), */
316+
size_t m_cluster_usage{0};
311317

312318
ClusterSet() noexcept = default;
313319
};
@@ -703,6 +709,18 @@ void TxGraphImpl::CreateChunkData(GraphIndex idx, LinearizationIndex chunk_count
703709
}
704710
}
705711

712+
size_t Cluster::TotalMemoryUsage() const noexcept
713+
{
714+
return // Dynamic memory allocated in this Cluster.
715+
memusage::DynamicUsage(m_mapping) + memusage::DynamicUsage(m_linearization) +
716+
// Dynamic memory usage inside m_depgraph.
717+
m_depgraph.DynamicMemoryUsage() +
718+
// Memory usage of the allocated Cluster itself.
719+
memusage::MallocUsage(sizeof(Cluster)) +
720+
// Memory usage of the ClusterSet::m_clusters entry.
721+
sizeof(std::unique_ptr<Cluster>);
722+
}
723+
706724
uint64_t Cluster::GetTotalTxSize() const noexcept
707725
{
708726
uint64_t ret{0};
@@ -851,9 +869,11 @@ Cluster* Cluster::CopyToStaging(TxGraphImpl& graph) const noexcept
851869
ptr->m_mapping = m_mapping;
852870
ptr->m_linearization = m_linearization;
853871
// Insert the new Cluster into the graph.
854-
graph.InsertCluster(1, std::move(ret), m_quality);
872+
graph.InsertCluster(/*level=*/1, std::move(ret), m_quality);
855873
// Update its Locators.
856874
ptr->Updated(graph, /*level=*/1);
875+
// Update memory usage.
876+
graph.GetClusterSet(/*level=*/1).m_cluster_usage += ptr->TotalMemoryUsage();
857877
return ptr;
858878
}
859879

@@ -862,6 +882,7 @@ void Cluster::ApplyRemovals(TxGraphImpl& graph, int level, std::span<GraphIndex>
862882
// Iterate over the prefix of to_remove that applies to this cluster.
863883
Assume(!to_remove.empty());
864884
SetType todo;
885+
graph.GetClusterSet(level).m_cluster_usage -= TotalMemoryUsage();
865886
do {
866887
GraphIndex idx = to_remove.front();
867888
Assume(idx < graph.m_entries.size());
@@ -913,12 +934,14 @@ void Cluster::ApplyRemovals(TxGraphImpl& graph, int level, std::span<GraphIndex>
913934
quality = QualityLevel::NEEDS_SPLIT;
914935
}
915936
Compact();
937+
graph.GetClusterSet(level).m_cluster_usage += TotalMemoryUsage();
916938
graph.SetClusterQuality(level, m_quality, m_setindex, quality);
917939
Updated(graph, level);
918940
}
919941

920942
void Cluster::Clear(TxGraphImpl& graph, int level) noexcept
921943
{
944+
graph.GetClusterSet(level).m_cluster_usage -= TotalMemoryUsage();
922945
for (auto i : m_linearization) {
923946
graph.ClearLocator(level, m_mapping[i], m_quality == QualityLevel::OVERSIZED_SINGLETON);
924947
}
@@ -935,6 +958,10 @@ void Cluster::MoveToMain(TxGraphImpl& graph) noexcept
935958
entry.m_locator[1].SetMissing();
936959
}
937960
auto quality = m_quality;
961+
// Subtract memory usage from staging and add it to main.
962+
graph.GetClusterSet(/*level=*/1).m_cluster_usage -= TotalMemoryUsage();
963+
graph.GetClusterSet(/*level=*/0).m_cluster_usage += TotalMemoryUsage();
964+
// Remove cluster itself from staging and add it to main.
938965
auto cluster = graph.ExtractCluster(1, quality, m_setindex);
939966
graph.InsertCluster(/*level=*/0, std::move(cluster), quality);
940967
Updated(graph, /*level=*/0);
@@ -1036,6 +1063,8 @@ bool Cluster::Split(TxGraphImpl& graph, int level) noexcept
10361063
graph.InsertCluster(level, std::move(new_cluster), split_quality);
10371064
todo -= component;
10381065
}
1066+
// We have to split the Cluster up. Remove accounting for the existing one first.
1067+
graph.GetClusterSet(level).m_cluster_usage -= TotalMemoryUsage();
10391068
// Redistribute the transactions.
10401069
for (auto i : m_linearization) {
10411070
/** The cluster which transaction originally in position i is moved to. */
@@ -1057,10 +1086,11 @@ bool Cluster::Split(TxGraphImpl& graph, int level) noexcept
10571086
for (auto par : m_depgraph.GetReducedParents(i)) new_parents.Set(remap[par].second);
10581087
new_cluster->m_depgraph.AddDependencies(new_parents, remap[i].second);
10591088
}
1060-
// Update all the Locators of moved transactions.
1089+
// Update all the Locators of moved transactions, and memory usage.
10611090
for (Cluster* new_cluster : new_clusters) {
10621091
new_cluster->Updated(graph, level);
10631092
new_cluster->Compact();
1093+
graph.GetClusterSet(level).m_cluster_usage += new_cluster->TotalMemoryUsage();
10641094
}
10651095
// Wipe this Cluster, and return that it needs to be deleted.
10661096
m_depgraph = DepGraph<SetType>{};
@@ -1624,7 +1654,9 @@ void TxGraphImpl::Merge(std::span<Cluster*> to_merge, int level) noexcept
16241654
// moves.
16251655
size_t max_size_pos{0};
16261656
DepGraphIndex max_size = to_merge[max_size_pos]->GetTxCount();
1657+
GetClusterSet(level).m_cluster_usage -= to_merge[max_size_pos]->TotalMemoryUsage();
16271658
for (size_t i = 1; i < to_merge.size(); ++i) {
1659+
GetClusterSet(level).m_cluster_usage -= to_merge[i]->TotalMemoryUsage();
16281660
DepGraphIndex size = to_merge[i]->GetTxCount();
16291661
if (size > max_size) {
16301662
max_size_pos = i;
@@ -1639,6 +1671,7 @@ void TxGraphImpl::Merge(std::span<Cluster*> to_merge, int level) noexcept
16391671
DeleteCluster(*to_merge[i], level);
16401672
}
16411673
to_merge[0]->Compact();
1674+
GetClusterSet(level).m_cluster_usage += to_merge[0]->TotalMemoryUsage();
16421675
}
16431676

16441677
void TxGraphImpl::ApplyDependencies(int level) noexcept
@@ -1764,6 +1797,7 @@ TxGraph::Ref TxGraphImpl::AddTransaction(const FeePerWeight& feerate) noexcept
17641797
auto& clusterset = GetClusterSet(level);
17651798
InsertCluster(level, std::move(cluster), oversized ? QualityLevel::OVERSIZED_SINGLETON : QualityLevel::OPTIMAL);
17661799
cluster_ptr->Updated(*this, level);
1800+
clusterset.m_cluster_usage += cluster_ptr->TotalMemoryUsage();
17671801
++clusterset.m_txcount;
17681802
// Deal with individually oversized transactions.
17691803
if (oversized) {
@@ -2116,6 +2150,7 @@ void TxGraphImpl::StartStaging() noexcept
21162150
m_staging_clusterset->m_group_data = m_main_clusterset.m_group_data;
21172151
m_staging_clusterset->m_oversized = m_main_clusterset.m_oversized;
21182152
Assume(m_staging_clusterset->m_oversized.has_value());
2153+
m_staging_clusterset->m_cluster_usage = 0;
21192154
}
21202155

21212156
void TxGraphImpl::AbortStaging() noexcept
@@ -2413,6 +2448,7 @@ void TxGraphImpl::SanityCheck() const
24132448
assert(level < MAX_LEVELS);
24142449
auto& clusterset = GetClusterSet(level);
24152450
std::set<const Cluster*> actual_clusters;
2451+
size_t recomputed_cluster_usage{0};
24162452

24172453
// For all quality levels...
24182454
for (int qual = 0; qual < int(QualityLevel::NONE); ++qual) {
@@ -2448,9 +2484,14 @@ void TxGraphImpl::SanityCheck() const
24482484
// Check that the cluster's quality and setindex matches its position in the quality list.
24492485
assert(cluster.m_quality == quality);
24502486
assert(cluster.m_setindex == setindex);
2487+
// Count memory usage.
2488+
recomputed_cluster_usage += cluster.TotalMemoryUsage();
24512489
}
24522490
}
24532491

2492+
// Verify memory usage.
2493+
assert(clusterset.m_cluster_usage == recomputed_cluster_usage);
2494+
24542495
// Verify that all to-be-removed transactions have valid identifiers.
24552496
for (GraphIndex idx : clusterset.m_to_remove) {
24562497
assert(idx < m_entries.size());

0 commit comments

Comments
 (0)