aboutsummaryrefslogtreecommitdiff
path: root/src/cluster_linearize.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/cluster_linearize.h')
-rw-r--r--src/cluster_linearize.h44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/cluster_linearize.h b/src/cluster_linearize.h
index 61b76968cf..b581f01da5 100644
--- a/src/cluster_linearize.h
+++ b/src/cluster_linearize.h
@@ -171,6 +171,50 @@ public:
return ret;
}
+ /** Find some connected component within the subset "todo" of this graph.
+ *
+ * Specifically, this finds the connected component which contains the first transaction of
+ * todo (if any).
+ *
+ * Two transactions are considered connected if they are both in `todo`, and one is an ancestor
+ * of the other in the entire graph (so not just within `todo`), or transitively there is a
+ * path of transactions connecting them. This does mean that if `todo` contains a transaction
+ * and a grandparent, but misses the parent, they will still be part of the same component.
+ *
+ * Complexity: O(ret.Count()).
+ */
+ SetType FindConnectedComponent(const SetType& todo) const noexcept
+ {
+ if (todo.None()) return todo;
+ auto to_add = SetType::Singleton(todo.First());
+ SetType ret;
+ do {
+ SetType old = ret;
+ for (auto add : to_add) {
+ ret |= Descendants(add);
+ ret |= Ancestors(add);
+ }
+ ret &= todo;
+ to_add = ret - old;
+ } while (to_add.Any());
+ return ret;
+ }
+
+ /** Determine if a subset is connected.
+ *
+ * Complexity: O(subset.Count()).
+ */
+ bool IsConnected(const SetType& subset) const noexcept
+ {
+ return FindConnectedComponent(subset) == subset;
+ }
+
+ /** Determine if this entire graph is connected.
+ *
+ * Complexity: O(TxCount()).
+ */
+ bool IsConnected() const noexcept { return IsConnected(SetType::Fill(TxCount())); }
+
/** Append the entries of select to list in a topologically valid order.
*
* Complexity: O(select.Count() * log(select.Count())).