@@ -164,11 +164,23 @@ class TxGraphImpl final : public TxGraph
164
164
/* * Information about one group of Clusters to be merged. */
165
165
struct GroupEntry
166
166
{
167
- /* * Which clusters are to be merged. */
168
- std::vector<Cluster*> m_clusters;
169
- /* * Which dependencies are to be applied to those merged clusters, as (parent, child)
170
- * pairs. */
171
- std::vector<std::pair<GraphIndex, GraphIndex>> m_deps;
167
+ /* * Where the clusters to be merged start in m_group_clusters. */
168
+ uint32_t m_cluster_offset;
169
+ /* * How many clusters to merge. */
170
+ uint32_t m_cluster_count;
171
+ /* * Where the dependencies for this cluster group in m_deps_to_add start. */
172
+ uint32_t m_deps_offset;
173
+ /* * How many dependencies to add. */
174
+ uint32_t m_deps_count;
175
+ };
176
+
177
+ /* * Information about all groups of Clusters to be merged. */
178
+ struct GroupData
179
+ {
180
+ /* * The groups of Clusters to be merged. */
181
+ std::vector<GroupEntry> m_groups;
182
+ /* * Which clusters are to be merged. GroupEntry::m_cluster_offset indexes into this. */
183
+ std::vector<Cluster*> m_group_clusters;
172
184
};
173
185
174
186
/* * The vectors of clusters, one vector per quality level. ClusterSetIndex indexes into each. */
@@ -179,7 +191,7 @@ class TxGraphImpl final : public TxGraph
179
191
* into this. */
180
192
std::vector<std::pair<GraphIndex, GraphIndex>> m_deps_to_add;
181
193
/* * Information about the merges to be performed, if known. */
182
- std::optional<std::vector<GroupEntry>> m_group_data = std::vector<GroupEntry> {};
194
+ std::optional<GroupData> m_group_data = GroupData {};
183
195
/* * Total number of transactions in this graph (sum of all transaction counts in all Clusters).
184
196
* */
185
197
GraphIndex m_txcount{0 };
@@ -796,24 +808,34 @@ void TxGraphImpl::GroupClusters() noexcept
796
808
std::sort (an_deps.begin (), an_deps.end (), [](auto & a, auto & b) noexcept { return a.second < b.second ; });
797
809
std::sort (an_clusters.begin (), an_clusters.end (), [](auto & a, auto & b) noexcept { return a.second < b.second ; });
798
810
799
- // Translate the resulting cluster groups to the m_group_data structure.
800
- m_group_data = std::vector<GroupEntry>{};
811
+ // Translate the resulting cluster groups to the m_group_data structure, and the dependencies
812
+ // back to m_deps_to_add.
813
+ m_group_data = GroupData{};
814
+ m_group_data->m_group_clusters .reserve (an_clusters.size ());
815
+ m_deps_to_add.clear ();
816
+ m_deps_to_add.reserve (an_deps.size ());
801
817
auto an_deps_it = an_deps.begin ();
802
818
auto an_clusters_it = an_clusters.begin ();
803
819
while (an_clusters_it != an_clusters.end ()) {
804
820
// Process all clusters/dependencies belonging to the partition with representative rep.
805
821
auto rep = an_clusters_it->second ;
806
822
// Create and initialize a new GroupData entry for the partition.
807
- auto & new_entry = m_group_data->emplace_back ();
808
- // Add all its clusters to it (copying those from an_clusters to m_clusters).
823
+ auto & new_entry = m_group_data->m_groups .emplace_back ();
824
+ new_entry.m_cluster_offset = m_group_data->m_group_clusters .size ();
825
+ new_entry.m_cluster_count = 0 ;
826
+ new_entry.m_deps_offset = m_deps_to_add.size ();
827
+ new_entry.m_deps_count = 0 ;
828
+ // Add all its clusters to it (copying those from an_clusters to m_group_clusters).
809
829
while (an_clusters_it != an_clusters.end () && an_clusters_it->second == rep) {
810
- new_entry. m_clusters .push_back (an_clusters_it->first );
830
+ m_group_data-> m_group_clusters .push_back (an_clusters_it->first );
811
831
++an_clusters_it;
832
+ ++new_entry.m_cluster_count ;
812
833
}
813
- // Add all its dependencies to it (copying those back from an_deps to m_deps ).
834
+ // Add all its dependencies to it (copying those back from an_deps to m_deps_to_add ).
814
835
while (an_deps_it != an_deps.end () && an_deps_it->second == rep) {
815
- new_entry. m_deps .push_back (an_deps_it->first );
836
+ m_deps_to_add .push_back (an_deps_it->first );
816
837
++an_deps_it;
838
+ ++new_entry.m_deps_count ;
817
839
}
818
840
}
819
841
Assume (an_deps_it == an_deps.end ());
@@ -857,22 +879,27 @@ void TxGraphImpl::ApplyDependencies() noexcept
857
879
if (m_deps_to_add.empty ()) return ;
858
880
859
881
// For each group of to-be-merged Clusters.
860
- for (auto & group_data : * m_group_data) {
882
+ for (const auto & group_data : m_group_data-> m_groups ) {
861
883
// Invoke Merge() to merge them into a single Cluster.
862
- Merge (group_data.m_clusters );
884
+ auto cluster_span = std::span{m_group_data->m_group_clusters }
885
+ .subspan (group_data.m_cluster_offset , group_data.m_cluster_count );
886
+ Merge (cluster_span);
863
887
// Actually apply all to-be-added dependencies (all parents and children from this grouping
864
888
// belong to the same Cluster at this point because of the merging above).
865
- const auto & loc = m_entries[group_data.m_deps [0 ].second ].m_locator ;
889
+ auto deps_span = std::span{m_deps_to_add}
890
+ .subspan (group_data.m_deps_offset , group_data.m_deps_count );
891
+ Assume (!deps_span.empty ());
892
+ const auto & loc = m_entries[deps_span[0 ].second ].m_locator ;
866
893
Assume (loc.IsPresent ());
867
- loc.cluster ->ApplyDependencies (*this , group_data. m_deps );
894
+ loc.cluster ->ApplyDependencies (*this , deps_span );
868
895
}
869
896
870
897
// Wipe the list of to-be-added dependencies now that they are applied.
871
898
m_deps_to_add.clear ();
872
899
Compact ();
873
900
// Also no further Cluster mergings are needed (note that we clear, but don't set to
874
901
// std::nullopt, as that would imply the groupings are unknown).
875
- m_group_data = std::vector<GroupEntry> {};
902
+ m_group_data = GroupData {};
876
903
}
877
904
878
905
void Cluster::Relinearize (TxGraphImpl& graph, uint64_t max_iters) noexcept
0 commit comments