MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / GroupClusters

Method GroupClusters

src/txgraph.cpp:1856–2066  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1854}
1855
1856void TxGraphImpl::GroupClusters(int level) noexcept
1857{
1858 auto& clusterset = GetClusterSet(level);
1859 // If the groupings have been computed already, nothing is left to be done.
1860 if (clusterset.m_group_data.has_value()) return;
1861
1862 // Before computing which Clusters need to be merged together, first apply all removals and
1863 // split the Clusters into connected components. If we would group first, we might end up
1864 // with inefficient and/or oversized Clusters which just end up being split again anyway.
1865 SplitAll(level);
1866
1867 /** Annotated clusters: an entry for each Cluster, together with the sequence number for the
1868 * representative for the partition it is in (initially its own, later that of the
1869 * to-be-merged group). */
1870 std::vector<std::pair<Cluster*, uint64_t>> an_clusters;
1871 /** Annotated dependencies: an entry for each m_deps_to_add entry (excluding ones that apply
1872 * to removed transactions), together with the sequence number of the representative root of
1873 * Clusters it applies to (initially that of the child Cluster, later that of the
1874 * to-be-merged group). */
1875 std::vector<std::pair<std::pair<GraphIndex, GraphIndex>, uint64_t>> an_deps;
1876
1877 // Construct an an_clusters entry for every oversized cluster, including ones from levels below,
1878 // as they may be inherited in this one.
1879 for (int level_iter = 0; level_iter <= level; ++level_iter) {
1880 for (auto& cluster : GetClusterSet(level_iter).m_clusters[int(QualityLevel::OVERSIZED_SINGLETON)]) {
1881 auto graph_idx = cluster->GetClusterEntry(0);
1882 auto cur_cluster = FindCluster(graph_idx, level);
1883 if (cur_cluster == nullptr) continue;
1884 an_clusters.emplace_back(cur_cluster, cur_cluster->m_sequence);
1885 }
1886 }
1887
1888 // Construct a an_clusters entry for every parent and child in the to-be-applied dependencies,
1889 // and an an_deps entry for each dependency to be applied.
1890 an_deps.reserve(clusterset.m_deps_to_add.size());
1891 for (const auto& [par, chl] : clusterset.m_deps_to_add) {
1892 auto par_cluster = FindCluster(par, level);
1893 auto chl_cluster = FindCluster(chl, level);
1894 // Skip dependencies for which the parent or child transaction is removed.
1895 if (par_cluster == nullptr || chl_cluster == nullptr) continue;
1896 an_clusters.emplace_back(par_cluster, par_cluster->m_sequence);
1897 // Do not include a duplicate when parent and child are identical, as it'll be removed
1898 // below anyway.
1899 if (chl_cluster != par_cluster) an_clusters.emplace_back(chl_cluster, chl_cluster->m_sequence);
1900 // Add entry to an_deps, using the child sequence number.
1901 an_deps.emplace_back(std::pair{par, chl}, chl_cluster->m_sequence);
1902 }
1903 // Sort and deduplicate an_clusters, so we end up with a sorted list of all involved Clusters
1904 // to which dependencies apply, or which are oversized.
1905 std::ranges::sort(an_clusters, [](auto& a, auto& b) noexcept { return a.second < b.second; });
1906 an_clusters.erase(std::ranges::unique(an_clusters).begin(), an_clusters.end());
1907 // Sort an_deps by applying the same order to the involved child cluster.
1908 std::ranges::sort(an_deps, [&](auto& a, auto& b) noexcept { return a.second < b.second; });
1909
1910 // Run the union-find algorithm to find partitions of the input Clusters which need to be
1911 // grouped together. See https://en.wikipedia.org/wiki/Disjoint-set_data_structure.
1912 {
1913 /** Each PartitionData entry contains information about a single input Cluster. */

Callers

nothing calls this directly

Calls 13

has_valueMethod · 0.45
GetClusterEntryMethod · 0.45
emplace_backMethod · 0.45
reserveMethod · 0.45
sizeMethod · 0.45
eraseMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
resizeMethod · 0.45
clearMethod · 0.45
push_backMethod · 0.45
GetTxCountMethod · 0.45

Tested by

no test coverage detected