Skip to content

Commit ae6975e

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 dceced4 commit ae6975e

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

0 commit comments

Comments
 (0)