mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-11 21:20:39 +02:00
clusterlin: adopt STL ranges algorithms (refactor)
This commit is contained in:
committed by
Pieter Wuille
parent
747da25360
commit
1aa78cdab6
@@ -9,6 +9,7 @@
|
||||
#include <cstdint>
|
||||
#include <numeric>
|
||||
#include <optional>
|
||||
#include <ranges>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -316,7 +317,7 @@ public:
|
||||
{
|
||||
DepGraphIndex old_len = list.size();
|
||||
for (auto i : select) list.push_back(i);
|
||||
std::sort(list.begin() + old_len, list.end(), [&](DepGraphIndex a, DepGraphIndex b) noexcept {
|
||||
std::ranges::sort(std::span{list}.subspan(old_len), [&](DepGraphIndex a, DepGraphIndex b) noexcept {
|
||||
const auto a_anc_count = entries[a].ancestors.Count();
|
||||
const auto b_anc_count = entries[b].ancestors.Count();
|
||||
if (a_anc_count != b_anc_count) return a_anc_count < b_anc_count;
|
||||
@@ -1618,7 +1619,7 @@ public:
|
||||
for (auto chunk_idx : m_chunk_idxs) {
|
||||
ret.push_back(m_set_info[chunk_idx].feerate);
|
||||
}
|
||||
std::sort(ret.begin(), ret.end(), std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
std::ranges::sort(ret, std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1647,8 +1648,8 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(expected_dependencies.begin(), expected_dependencies.end());
|
||||
std::sort(all_dependencies.begin(), all_dependencies.end());
|
||||
std::ranges::sort(expected_dependencies);
|
||||
std::ranges::sort(all_dependencies);
|
||||
assert(expected_dependencies == all_dependencies);
|
||||
|
||||
//
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ranges>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
@@ -433,7 +434,7 @@ FUZZ_TARGET(txgraph)
|
||||
assert(num_tx == sim.GetTransactionCount());
|
||||
// Sort by feerate only, since violating topological constraints within same-feerate
|
||||
// chunks won't affect diagram comparisons.
|
||||
std::sort(chunk_feerates.begin(), chunk_feerates.end(), std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
std::ranges::sort(chunk_feerates, std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
return chunk_feerates;
|
||||
};
|
||||
|
||||
@@ -1006,7 +1007,7 @@ FUZZ_TARGET(txgraph)
|
||||
for (auto i : cluster) sizes.push_back(top_sim.graph.FeeRate(i).size);
|
||||
auto sum_sizes = std::accumulate(sizes.begin(), sizes.end(), uint64_t{0});
|
||||
// Sort from large to small.
|
||||
std::sort(sizes.begin(), sizes.end(), std::greater{});
|
||||
std::ranges::sort(sizes, std::greater{});
|
||||
// In the worst case, only the smallest transactions are removed.
|
||||
while (sizes.size() > max_cluster_count || sum_sizes > max_cluster_size) {
|
||||
sum_sizes -= sizes.back();
|
||||
@@ -1075,8 +1076,8 @@ FUZZ_TARGET(txgraph)
|
||||
auto cmp = [&](SimTxGraph::Pos a, SimTxGraph::Pos b) noexcept {
|
||||
return real->CompareMainOrder(*sims[0].GetRef(a), *sims[0].GetRef(b)) < 0;
|
||||
};
|
||||
std::sort(vec1.begin(), vec1.end(), cmp);
|
||||
std::sort(vec2.begin(), vec2.end(), cmp);
|
||||
std::ranges::sort(vec1, cmp);
|
||||
std::ranges::sort(vec2, cmp);
|
||||
|
||||
// Verify the resulting orderings are identical. This could only fail if the ordering was
|
||||
// not total.
|
||||
@@ -1199,7 +1200,7 @@ FUZZ_TARGET(txgraph)
|
||||
auto cmp_redo = [&](SimTxGraph::Pos a, SimTxGraph::Pos b) noexcept {
|
||||
return real_redo->CompareMainOrder(*txobjects_redo[a], *txobjects_redo[b]) < 0;
|
||||
};
|
||||
std::sort(vec_redo.begin(), vec_redo.end(), cmp_redo);
|
||||
std::ranges::sort(vec_redo, cmp_redo);
|
||||
// Compare with the ordering we got from real.
|
||||
assert(vec1 == vec_redo);
|
||||
}
|
||||
@@ -1274,8 +1275,8 @@ FUZZ_TARGET(txgraph)
|
||||
// std::set_difference can be used on them below. The exact ordering does not matter
|
||||
// here, but it has to be consistent with the one used in main_real_diagram and
|
||||
// stage_real_diagram).
|
||||
std::sort(main_cmp_diagram.begin(), main_cmp_diagram.end(), std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
std::sort(stage_cmp_diagram.begin(), stage_cmp_diagram.end(), std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
std::ranges::sort(main_cmp_diagram, std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
std::ranges::sort(stage_cmp_diagram, std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
// Find the chunks that appear in main_diagram but are missing from main_cmp_diagram.
|
||||
// This is allowed, because GetMainStagingDiagrams omits clusters in main unaffected
|
||||
// by staging.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <compare>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <ranges>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <unordered_set>
|
||||
@@ -1212,8 +1213,8 @@ std::vector<Cluster*> TxGraphImpl::GetConflicts() const noexcept
|
||||
}
|
||||
}
|
||||
// Deduplicate the result (the same Cluster may appear multiple times).
|
||||
std::sort(ret.begin(), ret.end(), [](Cluster* a, Cluster* b) noexcept { return CompareClusters(a, b) < 0; });
|
||||
ret.erase(std::unique(ret.begin(), ret.end()), ret.end());
|
||||
std::ranges::sort(ret, [](Cluster* a, Cluster* b) noexcept { return CompareClusters(a, b) < 0; });
|
||||
ret.erase(std::ranges::unique(ret).begin(), ret.end());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1558,7 +1559,7 @@ void SingletonClusterImpl::Merge(TxGraphImpl&, int, Cluster&) noexcept
|
||||
void GenericClusterImpl::ApplyDependencies(TxGraphImpl& graph, int level, std::span<std::pair<GraphIndex, GraphIndex>> to_apply) noexcept
|
||||
{
|
||||
// Sort the list of dependencies to apply by child, so those can be applied in batch.
|
||||
std::sort(to_apply.begin(), to_apply.end(), [](auto& a, auto& b) { return a.second < b.second; });
|
||||
std::ranges::sort(to_apply, [](auto& a, auto& b) { return a.second < b.second; });
|
||||
// Iterate over groups of to-be-added dependencies with the same child.
|
||||
auto it = to_apply.begin();
|
||||
while (it != to_apply.end()) {
|
||||
@@ -1720,7 +1721,7 @@ void TxGraphImpl::ApplyRemovals(int up_to_level) noexcept
|
||||
}
|
||||
}
|
||||
// Group the set of to-be-removed entries by Cluster::m_sequence.
|
||||
std::sort(to_remove.begin(), to_remove.end(), [&](GraphIndex a, GraphIndex b) noexcept {
|
||||
std::ranges::sort(to_remove, [&](GraphIndex a, GraphIndex b) noexcept {
|
||||
Cluster* cluster_a = m_entries[a].m_locator[level].cluster;
|
||||
Cluster* cluster_b = m_entries[b].m_locator[level].cluster;
|
||||
return CompareClusters(cluster_a, cluster_b) < 0;
|
||||
@@ -1791,7 +1792,7 @@ void TxGraphImpl::Compact() noexcept
|
||||
// ones get processed first. This means earlier-processed GraphIndexes will not cause moving of
|
||||
// later-processed ones during the "swap with end of m_entries" step below (which might
|
||||
// invalidate them).
|
||||
std::sort(m_unlinked.begin(), m_unlinked.end(), std::greater{});
|
||||
std::ranges::sort(m_unlinked, std::greater{});
|
||||
|
||||
std::vector<Cluster*> affected_main;
|
||||
auto last = GraphIndex(-1);
|
||||
@@ -1817,7 +1818,7 @@ void TxGraphImpl::Compact() noexcept
|
||||
|
||||
// Update the affected clusters, to fixup Entry::m_main_max_chunk_fallback values which may
|
||||
// have become outdated due to the compaction above.
|
||||
std::sort(affected_main.begin(), affected_main.end());
|
||||
std::ranges::sort(affected_main);
|
||||
affected_main.erase(std::unique(affected_main.begin(), affected_main.end()), affected_main.end());
|
||||
for (Cluster* cluster : affected_main) {
|
||||
cluster->Updated(*this, /*level=*/0, /*rename=*/true);
|
||||
@@ -1901,10 +1902,10 @@ void TxGraphImpl::GroupClusters(int level) noexcept
|
||||
}
|
||||
// Sort and deduplicate an_clusters, so we end up with a sorted list of all involved Clusters
|
||||
// to which dependencies apply, or which are oversized.
|
||||
std::sort(an_clusters.begin(), an_clusters.end(), [](auto& a, auto& b) noexcept { return a.second < b.second; });
|
||||
an_clusters.erase(std::unique(an_clusters.begin(), an_clusters.end()), an_clusters.end());
|
||||
std::ranges::sort(an_clusters, [](auto& a, auto& b) noexcept { return a.second < b.second; });
|
||||
an_clusters.erase(std::ranges::unique(an_clusters).begin(), an_clusters.end());
|
||||
// Sort an_deps by applying the same order to the involved child cluster.
|
||||
std::sort(an_deps.begin(), an_deps.end(), [&](auto& a, auto& b) noexcept { return a.second < b.second; });
|
||||
std::ranges::sort(an_deps, [&](auto& a, auto& b) noexcept { return a.second < b.second; });
|
||||
|
||||
// Run the union-find algorithm to find partitions of the input Clusters which need to be
|
||||
// grouped together. See https://en.wikipedia.org/wiki/Disjoint-set_data_structure.
|
||||
@@ -2017,8 +2018,8 @@ void TxGraphImpl::GroupClusters(int level) noexcept
|
||||
|
||||
// Sort both an_clusters and an_deps by sequence number of the representative of the
|
||||
// partition they are in, grouping all those applying to the same partition together.
|
||||
std::sort(an_deps.begin(), an_deps.end(), [](auto& a, auto& b) noexcept { return a.second < b.second; });
|
||||
std::sort(an_clusters.begin(), an_clusters.end(), [](auto& a, auto& b) noexcept { return a.second < b.second; });
|
||||
std::ranges::sort(an_deps, [](auto& a, auto& b) noexcept { return a.second < b.second; });
|
||||
std::ranges::sort(an_clusters, [](auto& a, auto& b) noexcept { return a.second < b.second; });
|
||||
|
||||
// Translate the resulting cluster groups to the m_group_data structure, and the dependencies
|
||||
// back to m_deps_to_add.
|
||||
@@ -2489,7 +2490,7 @@ std::vector<TxGraph::Ref*> TxGraphImpl::GetAncestorsUnion(std::span<const Ref* c
|
||||
matches.emplace_back(cluster, m_entries[GetRefIndex(*arg)].m_locator[cluster_level].index);
|
||||
}
|
||||
// Group by Cluster.
|
||||
std::sort(matches.begin(), matches.end(), [](auto& a, auto& b) noexcept { return CompareClusters(a.first, b.first) < 0; });
|
||||
std::ranges::sort(matches, [](auto& a, auto& b) noexcept { return CompareClusters(a.first, b.first) < 0; });
|
||||
// Dispatch to the Clusters.
|
||||
std::span match_span(matches);
|
||||
std::vector<TxGraph::Ref*> ret;
|
||||
@@ -2522,7 +2523,7 @@ std::vector<TxGraph::Ref*> TxGraphImpl::GetDescendantsUnion(std::span<const Ref*
|
||||
matches.emplace_back(cluster, m_entries[GetRefIndex(*arg)].m_locator[cluster_level].index);
|
||||
}
|
||||
// Group by Cluster.
|
||||
std::sort(matches.begin(), matches.end(), [](auto& a, auto& b) noexcept { return CompareClusters(a.first, b.first) < 0; });
|
||||
std::ranges::sort(matches, [](auto& a, auto& b) noexcept { return CompareClusters(a.first, b.first) < 0; });
|
||||
// Dispatch to the Clusters.
|
||||
std::span match_span(matches);
|
||||
std::vector<TxGraph::Ref*> ret;
|
||||
@@ -2796,7 +2797,7 @@ TxGraph::GraphIndex TxGraphImpl::CountDistinctClusters(std::span<const Ref* cons
|
||||
if (cluster != nullptr) clusters.push_back(cluster);
|
||||
}
|
||||
// Count the number of distinct elements in clusters.
|
||||
std::sort(clusters.begin(), clusters.end(), [](Cluster* a, Cluster* b) noexcept { return CompareClusters(a, b) < 0; });
|
||||
std::ranges::sort(clusters, [](Cluster* a, Cluster* b) noexcept { return CompareClusters(a, b) < 0; });
|
||||
Cluster* last{nullptr};
|
||||
GraphIndex ret{0};
|
||||
for (Cluster* cluster : clusters) {
|
||||
@@ -2827,8 +2828,8 @@ std::pair<std::vector<FeeFrac>, std::vector<FeeFrac>> TxGraphImpl::GetMainStagin
|
||||
}
|
||||
}
|
||||
// Sort both by decreasing feerate to obtain diagrams, and return them.
|
||||
std::sort(main_feerates.begin(), main_feerates.end(), std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
std::sort(staging_feerates.begin(), staging_feerates.end(), std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
std::ranges::sort(main_feerates, std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
std::ranges::sort(staging_feerates, std::greater<ByRatioNegSize<FeeFrac>>{});
|
||||
return std::make_pair(std::move(main_feerates), std::move(staging_feerates));
|
||||
}
|
||||
|
||||
@@ -3401,7 +3402,7 @@ std::vector<TxGraph::Ref*> TxGraphImpl::Trim() noexcept
|
||||
// Sort the trim data by GraphIndex. In what follows, we will treat this sorted vector as
|
||||
// a map from GraphIndex to TrimTxData via locate_fn, and its ordering will not change
|
||||
// anymore.
|
||||
std::sort(trim_data.begin(), trim_data.end(), [](auto& a, auto& b) noexcept { return a.m_index < b.m_index; });
|
||||
std::ranges::sort(trim_data, [](auto& a, auto& b) noexcept { return a.m_index < b.m_index; });
|
||||
|
||||
// Add the explicitly added dependencies to deps_by_child.
|
||||
deps_by_child.insert(deps_by_child.end(),
|
||||
@@ -3410,7 +3411,7 @@ std::vector<TxGraph::Ref*> TxGraphImpl::Trim() noexcept
|
||||
|
||||
// Sort deps_by_child by child transaction GraphIndex. The order will not be changed
|
||||
// anymore after this.
|
||||
std::sort(deps_by_child.begin(), deps_by_child.end(), [](auto& a, auto& b) noexcept { return a.second < b.second; });
|
||||
std::ranges::sort(deps_by_child, [](auto& a, auto& b) noexcept { return a.second < b.second; });
|
||||
// Fill m_parents_count and m_parents_offset in trim_data, as well as m_deps_left, and
|
||||
// initially populate trim_heap. Because of the sort above, all dependencies involving the
|
||||
// same child are grouped together, so a single linear scan suffices.
|
||||
@@ -3434,7 +3435,7 @@ std::vector<TxGraph::Ref*> TxGraphImpl::Trim() noexcept
|
||||
// Construct deps_by_parent, sorted by parent transaction GraphIndex. The order will not be
|
||||
// changed anymore after this.
|
||||
deps_by_parent = deps_by_child;
|
||||
std::sort(deps_by_parent.begin(), deps_by_parent.end(), [](auto& a, auto& b) noexcept { return a.first < b.first; });
|
||||
std::ranges::sort(deps_by_parent, [](auto& a, auto& b) noexcept { return a.first < b.first; });
|
||||
// Fill m_children_offset and m_children_count in trim_data. Because of the sort above, all
|
||||
// dependencies involving the same parent are grouped together, so a single linear scan
|
||||
// suffices.
|
||||
@@ -3482,8 +3483,8 @@ std::vector<TxGraph::Ref*> TxGraphImpl::Trim() noexcept
|
||||
Assume(chl == entry.m_index);
|
||||
current_deps.push_back(find_fn(&*locate_fn(par)));
|
||||
}
|
||||
std::sort(current_deps.begin(), current_deps.end());
|
||||
current_deps.erase(std::unique(current_deps.begin(), current_deps.end()), current_deps.end());
|
||||
std::ranges::sort(current_deps);
|
||||
current_deps.erase(std::ranges::unique(current_deps).begin(), current_deps.end());
|
||||
|
||||
// Compute resource counts.
|
||||
uint32_t new_count = 1;
|
||||
|
||||
Reference in New Issue
Block a user