Skip to content

Commit f9307c8

Browse files
committed
semantic: Remove recursion in sorted
Done as part of the effort to remove all the recursion crate wide. Use the `TreeLike` trait to iterate over policy nodes and remove the recursive call in `semantic::Policy::sorted`.
1 parent 09a47cb commit f9307c8

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

src/policy/semantic.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -649,17 +649,29 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
649649
/// in general this appears to require Gröbner basis techniques that are not
650650
/// implemented.
651651
pub fn sorted(self) -> Policy<Pk> {
652-
match self {
653-
Policy::Threshold(k, subs) => {
654-
let mut new_subs: Vec<_> = subs
655-
.into_iter()
656-
.map(|p| Arc::new(p.as_ref().clone().sorted()))
657-
.collect();
658-
new_subs.sort();
659-
Policy::Threshold(k, new_subs)
652+
use Policy::*;
653+
654+
let mut sorted = vec![];
655+
for data in Arc::new(self).post_order_iter() {
656+
let child_n = |n| Arc::clone(&sorted[data.child_indices[n]]);
657+
658+
let new_policy = match data.node.as_ref() {
659+
Threshold(k, ref subs) => {
660+
let mut subs = (0..subs.len()).map(child_n).collect::<Vec<_>>();
661+
subs.sort();
662+
Some(Threshold(*k, subs))
663+
}
664+
_ => None,
665+
};
666+
match new_policy {
667+
Some(new_policy) => sorted.push(Arc::new(new_policy)),
668+
None => sorted.push(Arc::clone(&data.node)),
660669
}
661-
x => x,
662670
}
671+
// Unwrap is ok because we know we processed at least one node.
672+
let root_node = sorted.pop().unwrap();
673+
// Unwrap is ok because we know `root_node` is the only strong reference.
674+
Arc::try_unwrap(root_node).unwrap()
663675
}
664676
}
665677

0 commit comments

Comments
 (0)