@@ -784,18 +784,20 @@ void TxGraphImpl::GroupClusters() noexcept
784
784
return data;
785
785
};
786
786
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. */
788
789
static constexpr auto union_fn = [](PartitionData* arg1, PartitionData* arg2) noexcept {
789
790
// Find the roots of the trees, and bail out if they are already equal (which would
790
791
// mean they are in the same partition already).
791
792
auto rep1 = find_root_fn (arg1);
792
793
auto rep2 = find_root_fn (arg2);
793
- if (rep1 == rep2) return ;
794
+ if (rep1 == rep2) return rep1 ;
794
795
// Pick the lower-rank root to become a child of the higher-rank one.
795
796
// See https://en.wikipedia.org/wiki/Disjoint-set_data_structure#Union_by_rank.
796
797
if (rep1->rank < rep2->rank ) std::swap (rep1, rep2);
797
798
rep2->parent = rep1;
798
799
rep1->rank += (rep1->rank == rep2->rank );
800
+ return rep1;
799
801
};
800
802
801
803
// Start by initializing every Cluster as its own singleton partition.
@@ -808,6 +810,8 @@ void TxGraphImpl::GroupClusters() noexcept
808
810
809
811
// Run through all parent/child pairs in m_deps_to_add, and union the
810
812
// the partitions their Clusters are in.
813
+ Cluster* last_chl_cluster{nullptr };
814
+ PartitionData* last_partition{nullptr };
811
815
for (const auto & [par, chl] : m_deps_to_add) {
812
816
auto par_cluster = m_entries[par].m_locator .cluster ;
813
817
auto chl_cluster = m_entries[chl].m_locator .cluster ;
@@ -816,7 +820,15 @@ void TxGraphImpl::GroupClusters() noexcept
816
820
// Nothing to do if either parent or child transaction is removed already.
817
821
if (par_cluster == nullptr || chl_cluster == nullptr ) continue ;
818
822
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
+ }
820
832
}
821
833
822
834
// Populate the an_clusters and an_deps data structures with the list of input Clusters,
0 commit comments