@@ -408,6 +408,26 @@ struct Node {
408
408
));
409
409
}
410
410
411
+ /* * Compare two miniscript subtrees, using a non-recursive algorithm. */
412
+ friend int Compare (const Node<Key>& node1, const Node<Key>& node2)
413
+ {
414
+ std::vector<std::pair<const Node<Key>&, const Node<Key>&>> queue;
415
+ queue.emplace_back (node1, node2);
416
+ while (!queue.empty ()) {
417
+ const auto & [a, b] = queue.back ();
418
+ queue.pop_back ();
419
+ if (std::tie (a.fragment , a.k , a.keys , a.data ) < std::tie (b.fragment , b.k , b.keys , b.data )) return -1 ;
420
+ if (std::tie (b.fragment , b.k , b.keys , b.data ) < std::tie (a.fragment , a.k , a.keys , a.data )) return 1 ;
421
+ if (a.subs .size () < b.subs .size ()) return -1 ;
422
+ if (b.subs .size () < a.subs .size ()) return 1 ;
423
+ size_t n = a.subs .size ();
424
+ for (size_t i = 0 ; i < n; ++i) {
425
+ queue.emplace_back (*a.subs [n - 1 - i], *b.subs [n - 1 - i]);
426
+ }
427
+ }
428
+ return 0 ;
429
+ }
430
+
411
431
// ! Compute the type for this miniscript.
412
432
Type CalcType () const {
413
433
using namespace internal ;
@@ -765,20 +785,7 @@ struct Node {
765
785
bool IsSaneTopLevel () const { return IsValidTopLevel () && IsSane () && NeedsSignature (); }
766
786
767
787
// ! Equality testing.
768
- bool operator ==(const Node<Key>& arg) const
769
- {
770
- if (fragment != arg.fragment ) return false ;
771
- if (k != arg.k ) return false ;
772
- if (data != arg.data ) return false ;
773
- if (keys != arg.keys ) return false ;
774
- if (subs.size () != arg.subs .size ()) return false ;
775
- for (size_t i = 0 ; i < subs.size (); ++i) {
776
- if (!(*subs[i] == *arg.subs [i])) return false ;
777
- }
778
- assert (scriptlen == arg.scriptlen );
779
- assert (typ == arg.typ );
780
- return true ;
781
- }
788
+ bool operator ==(const Node<Key>& arg) const { return Compare (*this , arg) == 0 ; }
782
789
783
790
// Constructors with various argument combinations.
784
791
Node (Fragment nt, std::vector<NodeRef<Key>> sub, std::vector<unsigned char > arg, uint32_t val = 0 ) : fragment(nt), k(val), data(std::move(arg)), subs(std::move(sub)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
0 commit comments