Skip to content

Commit 9507538

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 5e2b235 commit 9507538

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
@@ -658,17 +658,29 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
658658
/// in general this appears to require Gröbner basis techniques that are not
659659
/// implemented.
660660
pub fn sorted(self) -> Policy<Pk> {
661-
match self {
662-
Policy::Threshold(k, subs) => {
663-
let mut new_subs: Vec<_> = subs
664-
.into_iter()
665-
.map(|p| Arc::new(p.as_ref().clone().sorted()))
666-
.collect();
667-
new_subs.sort();
668-
Policy::Threshold(k, new_subs)
661+
use Policy::*;
662+
663+
let mut sorted = vec![];
664+
for data in Arc::new(self).post_order_iter() {
665+
let child_n = |n| Arc::clone(&sorted[data.child_indices[n]]);
666+
667+
let new_policy = match data.node.as_ref() {
668+
Threshold(k, ref subs) => {
669+
let mut subs = (0..subs.len()).map(child_n).collect::<Vec<_>>();
670+
subs.sort();
671+
Some(Threshold(*k, subs))
672+
}
673+
_ => None,
674+
};
675+
match new_policy {
676+
Some(new_policy) => sorted.push(Arc::new(new_policy)),
677+
None => sorted.push(Arc::clone(&data.node)),
669678
}
670-
x => x,
671679
}
680+
// Unwrap is ok because we know we processed at least one node.
681+
let root_node = sorted.pop().unwrap();
682+
// Unwrap is ok because we know `root_node` is the only strong reference.
683+
Arc::try_unwrap(root_node).unwrap()
672684
}
673685
}
674686

0 commit comments

Comments
 (0)