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

Method Split

src/txgraph.cpp:1439–1511  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1437}
1438
1439bool GenericClusterImpl::Split(TxGraphImpl& graph, int level) noexcept
1440{
1441 // This function can only be called when the Cluster needs splitting.
1442 Assume(NeedsSplitting());
1443 // Determine the new quality the split-off Clusters will have.
1444 QualityLevel new_quality = IsTopological() ? QualityLevel::NEEDS_RELINEARIZE : QualityLevel::NEEDS_FIX;
1445 /** Which positions are still left in this Cluster. */
1446 auto todo = m_depgraph.Positions();
1447 /** Mapping from transaction positions in this Cluster to the Cluster where it ends up, and
1448 * its position therein. */
1449 std::vector<std::pair<Cluster*, DepGraphIndex>> remap(m_depgraph.PositionRange());
1450 std::vector<Cluster*> new_clusters;
1451 bool first{true};
1452 // Iterate over the connected components of this Cluster's m_depgraph.
1453 while (todo.Any()) {
1454 auto component = m_depgraph.FindConnectedComponent(todo);
1455 auto component_size = component.Count();
1456 auto split_quality = component_size <= 1 ? QualityLevel::OPTIMAL : new_quality;
1457 if (first && component == todo && SetType::Fill(component_size) == component && component_size >= MIN_INTENDED_TX_COUNT) {
1458 // The existing Cluster is an entire component, without holes. Leave it be, but update
1459 // its quality. If there are holes, we continue, so that the Cluster is reconstructed
1460 // without holes, reducing memory usage. If the component's size is below the intended
1461 // transaction count for this Cluster implementation, continue so that it can get
1462 // converted.
1463 Assume(todo == m_depgraph.Positions());
1464 graph.SetClusterQuality(level, m_quality, m_setindex, split_quality);
1465 // If this made the quality ACCEPTABLE or OPTIMAL, we need to compute and cache its
1466 // chunking.
1467 Updated(graph, /*level=*/level, /*rename=*/false);
1468 return false;
1469 }
1470 first = false;
1471 // Construct a new Cluster to hold the found component.
1472 auto new_cluster = graph.CreateEmptyCluster(component_size);
1473 new_clusters.push_back(new_cluster.get());
1474 // Remember that all the component's transactions go to this new Cluster. The positions
1475 // will be determined below, so use -1 for now.
1476 for (auto i : component) {
1477 remap[i] = {new_cluster.get(), DepGraphIndex(-1)};
1478 }
1479 graph.InsertCluster(level, std::move(new_cluster), split_quality);
1480 todo -= component;
1481 }
1482 // We have to split the Cluster up. Remove accounting for the existing one first.
1483 graph.GetClusterSet(level).m_cluster_usage -= TotalMemoryUsage();
1484 // Redistribute the transactions.
1485 for (auto i : m_linearization) {
1486 /** The cluster which transaction originally in position i is moved to. */
1487 Cluster* new_cluster = remap[i].first;
1488 // Copy the transaction to the new cluster's depgraph, and remember the position.
1489 remap[i].second = new_cluster->AppendTransaction(m_mapping[i], FeePerWeight::FromFeeFrac(m_depgraph.FeeRate(i)));
1490 }
1491 // Redistribute the dependencies.
1492 for (auto i : m_linearization) {
1493 /** The cluster transaction in position i is moved to. */
1494 Cluster* new_cluster = remap[i].first;
1495 // Copy its parents, translating positions.
1496 SetType new_parents;

Callers

nothing calls this directly

Calls 15

PositionRangeMethod · 0.80
SetClusterQualityMethod · 0.80
CreateEmptyClusterMethod · 0.80
InsertClusterMethod · 0.80
AppendTransactionMethod · 0.80
FeeRateMethod · 0.80
GetReducedParentsMethod · 0.80
UpdatedMethod · 0.80
TotalMemoryUsageMethod · 0.80
AnyMethod · 0.45
CountMethod · 0.45

Tested by

no test coverage detected