Skip to content

Commit e20fda7

Browse files
committed
clusterlin: reduce computation of unnecessary pot sets (optimization)
Keep track of which transactions in the graph have an individual feerate that is better than the best included set so far. Others do not need to be added to the pot set, as they cannot possibly help beating best.
1 parent 6060a94 commit e20fda7

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

src/cluster_linearize.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,10 @@ class SearchCandidateFinder
668668
SetType und;
669669
/** (Only when inc is not empty) The best feerate of any superset of inc that is also a
670670
* subset of (inc | und), without requiring it to be topologically valid. It forms a
671-
* conservative upper bound on how good a set this work item can give rise to. */
671+
* conservative upper bound on how good a set this work item can give rise to.
672+
* Transactions whose feerate is below best's are ignored when determining this value,
673+
* which means it may technically be an underestimate, but if so, this work item
674+
* cannot result in something that beats best anyway. */
672675
FeeFrac pot_feerate;
673676

674677
/** Construct a new work item. */
@@ -711,8 +714,16 @@ class SearchCandidateFinder
711714
/** Local copy of the iteration limit. */
712715
uint64_t iterations_left = max_iterations;
713716

717+
/** The set of transactions in m_todo which have feerate > best's. */
718+
SetType imp = m_todo;
719+
while (imp.Any()) {
720+
ClusterIndex check = imp.Last();
721+
if (m_sorted_depgraph.FeeRate(check) >> best.feerate) break;
722+
imp.Reset(check);
723+
}
724+
714725
/** Internal function to add an item to the queue of elements to explore if there are any
715-
* transactions left to split on, and to update best.
726+
* transactions left to split on, and to update best/imp.
716727
*
717728
* - inc: the "inc" value for the new work item (must be topological).
718729
* - und: the "und" value for the new work item ((inc | und) must be topological).
@@ -722,8 +733,11 @@ class SearchCandidateFinder
722733
* pot_feerate. It starts off equal to inc. */
723734
auto pot = inc;
724735
if (!inc.feerate.IsEmpty()) {
725-
// Add entries to pot.
726-
for (auto pos : und) {
736+
// Add entries to pot. We iterate over all undecided transactions whose feerate is
737+
// higher than best. While undecided transactions of lower feerate may improve pot,
738+
// the resulting pot feerate cannot possibly exceed best's (and this item will be
739+
// skipped in split_fn anyway).
740+
for (auto pos : imp & und) {
727741
// Determine if adding transaction pos to pot (ignoring topology) would improve
728742
// it. If not, we're done updating pot. This relies on the fact that
729743
// m_sorted_depgraph, and thus the transactions iterated over, are in decreasing
@@ -735,6 +749,12 @@ class SearchCandidateFinder
735749
// If inc's feerate is better than best's, remember it as our new best.
736750
if (inc.feerate > best.feerate) {
737751
best = inc;
752+
// See if we can remove any entries from imp now.
753+
while (imp.Any()) {
754+
ClusterIndex check = imp.Last();
755+
if (m_sorted_depgraph.FeeRate(check) >> best.feerate) break;
756+
imp.Reset(check);
757+
}
738758
}
739759

740760
// If no potential transactions exist beyond the already included ones, no
@@ -774,6 +794,9 @@ class SearchCandidateFinder
774794

775795
const ClusterIndex first = elem.und.First();
776796
if (!elem.inc.feerate.IsEmpty()) {
797+
// If no undecided transactions remain with feerate higher than best, this entry
798+
// cannot be improved beyond best.
799+
if (!elem.und.Overlaps(imp)) return;
777800
// We can ignore any queue item whose potential feerate isn't better than the best
778801
// seen so far.
779802
if (elem.pot_feerate <= best.feerate) return;

0 commit comments

Comments
 (0)