Skip to content

Commit 803424f

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 807c60f commit 803424f

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

0 commit comments

Comments
 (0)