diff options
Diffstat (limited to 'src/cluster_linearize.h')
-rw-r--r-- | src/cluster_linearize.h | 44 |
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())). |