Skip to content

Commit 57f5499

Browse files
committed
txgraph: Avoid looking up the same child cluster repeatedly (optimization)
Since m_deps_to_add has been sorted by child Cluster* already, all dependencies with the same child will be processed consecutively. Take advantage of this by remember the last partition merged with, and reusing that if applicable.
1 parent 1171953 commit 57f5499

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

src/txgraph.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -784,18 +784,20 @@ void TxGraphImpl::GroupClusters() noexcept
784784
return data;
785785
};
786786

787-
/** Given two PartitionDatas, union the partitions they are in. */
787+
/** Given two PartitionDatas, union the partitions they are in, and return their
788+
* representative. */
788789
static constexpr auto union_fn = [](PartitionData* arg1, PartitionData* arg2) noexcept {
789790
// Find the roots of the trees, and bail out if they are already equal (which would
790791
// mean they are in the same partition already).
791792
auto rep1 = find_root_fn(arg1);
792793
auto rep2 = find_root_fn(arg2);
793-
if (rep1 == rep2) return;
794+
if (rep1 == rep2) return rep1;
794795
// Pick the lower-rank root to become a child of the higher-rank one.
795796
// See https://en.wikipedia.org/wiki/Disjoint-set_data_structure#Union_by_rank.
796797
if (rep1->rank < rep2->rank) std::swap(rep1, rep2);
797798
rep2->parent = rep1;
798799
rep1->rank += (rep1->rank == rep2->rank);
800+
return rep1;
799801
};
800802

801803
// Start by initializing every Cluster as its own singleton partition.
@@ -808,6 +810,8 @@ void TxGraphImpl::GroupClusters() noexcept
808810

809811
// Run through all parent/child pairs in m_deps_to_add, and union the
810812
// the partitions their Clusters are in.
813+
Cluster* last_chl_cluster{nullptr};
814+
PartitionData* last_partition{nullptr};
811815
for (const auto& [par, chl] : m_deps_to_add) {
812816
auto par_cluster = m_entries[par].m_locator.cluster;
813817
auto chl_cluster = m_entries[chl].m_locator.cluster;
@@ -816,7 +820,15 @@ void TxGraphImpl::GroupClusters() noexcept
816820
// Nothing to do if either parent or child transaction is removed already.
817821
if (par_cluster == nullptr || chl_cluster == nullptr) continue;
818822
Assume(par != chl);
819-
union_fn(locate_fn(par_cluster), locate_fn(chl_cluster));
823+
if (chl_cluster == last_chl_cluster) {
824+
// If the child Clusters is the same as the previous iteration, union with the
825+
// tree they were in, avoiding the need for another lookup. Note that m_deps_to_add
826+
// is sorted by child Cluster, so batches with the same child are expected.
827+
last_partition = union_fn(locate_fn(par_cluster), last_partition);
828+
} else {
829+
last_chl_cluster = chl_cluster;
830+
last_partition = union_fn(locate_fn(par_cluster), locate_fn(chl_cluster));
831+
}
820832
}
821833

822834
// Populate the an_clusters and an_deps data structures with the list of input Clusters,

0 commit comments

Comments
 (0)