Skip to content

Commit 28662d2

Browse files
committed
Use fold combinator instead of manual implementation
Currently we are using a mutable variable to manually implement the logic that the `fold` combinator provides.
1 parent cb4c037 commit 28662d2

File tree

1 file changed

+53
-35
lines changed

1 file changed

+53
-35
lines changed

src/miniscript/types/extra_props.rs

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -762,17 +762,13 @@ impl Property for ExtData {
762762
let mut ops_count = 0;
763763
let mut ops_count_sat_vec = Vec::with_capacity(n);
764764
let mut ops_count_nsat_sum = 0;
765-
let mut op_count_sat = Some(0);
766765
let mut timelocks = Vec::with_capacity(n);
767766
let mut stack_elem_count_sat_vec = Vec::with_capacity(n);
768-
let mut stack_elem_count_sat = Some(0);
769767
let mut stack_elem_count_dissat = Some(0);
770768
let mut max_sat_size_vec = Vec::with_capacity(n);
771-
let mut max_sat_size = Some((0, 0));
772769
let mut max_dissat_size = Some((0, 0));
773770
// the max element count is same as max sat element count when satisfying one element + 1
774771
let mut exec_stack_elem_count_sat_vec = Vec::with_capacity(n);
775-
let mut exec_stack_elem_count_sat = Some(0);
776772
let mut exec_stack_elem_count_dissat = Some(0);
777773

778774
for i in 0..n {
@@ -810,42 +806,59 @@ impl Property for ExtData {
810806
}
811807

812808
stack_elem_count_sat_vec.sort_by(sat_minus_option_dissat);
813-
// Sum of the cost by iterating through the sorted vector *backward*.
814-
for (i, &(x, y)) in stack_elem_count_sat_vec.iter().rev().enumerate() {
815-
stack_elem_count_sat = if i <= k {
816-
x.and_then(|x| stack_elem_count_sat.map(|count| count + x))
817-
} else {
818-
y.and_then(|y| stack_elem_count_sat.map(|count| count + y))
819-
};
820-
}
809+
let stack_elem_count_sat =
810+
stack_elem_count_sat_vec
811+
.iter()
812+
.rev()
813+
.enumerate()
814+
.fold(Some(0), |acc, (i, &(x, y))| {
815+
if i <= k {
816+
opt_add(acc, x)
817+
} else {
818+
opt_add(acc, y)
819+
}
820+
});
821821

822822
exec_stack_elem_count_sat_vec.sort_by(sat_minus_option_dissat);
823-
for (i, &(x, y)) in exec_stack_elem_count_sat_vec.iter().rev().enumerate() {
824-
exec_stack_elem_count_sat = if i <= k {
825-
opt_max(exec_stack_elem_count_sat, x)
826-
} else {
827-
opt_max(exec_stack_elem_count_sat, y)
828-
};
829-
}
823+
let exec_stack_elem_count_sat = exec_stack_elem_count_sat_vec
824+
.iter()
825+
.rev()
826+
.enumerate()
827+
.fold(Some(0), |acc, (i, &(x, y))| {
828+
if i <= k {
829+
opt_max(acc, x)
830+
} else {
831+
opt_max(acc, y)
832+
}
833+
});
830834

831835
// FIXME: Maybe make the ExtData struct aware of Ctx and add a one_cost() method here ?
832836
max_sat_size_vec.sort_by(sat_minus_dissat_witness);
833-
for (i, &(x, y)) in max_sat_size_vec.iter().enumerate() {
834-
max_sat_size = if i <= k {
835-
x.and_then(|x| max_sat_size.map(|(w, s)| (w + x.0, s + x.1)))
836-
} else {
837-
y.and_then(|y| max_sat_size.map(|(w, s)| (w + y.0, s + y.1)))
838-
};
839-
}
837+
let max_sat_size =
838+
max_sat_size_vec
839+
.iter()
840+
.enumerate()
841+
.fold(Some((0, 0)), |acc, (i, &(x, y))| {
842+
if i <= k {
843+
opt_tuple_add(acc, x)
844+
} else {
845+
opt_tuple_add(acc, y)
846+
}
847+
});
840848

841849
ops_count_sat_vec.sort_by(sat_minus_dissat);
842-
for (i, &(x, y)) in ops_count_sat_vec.iter().enumerate() {
843-
op_count_sat = if i <= k {
844-
opt_add(op_count_sat, x)
845-
} else {
846-
opt_add(op_count_sat, Some(y))
847-
};
848-
}
850+
let op_count_sat =
851+
ops_count_sat_vec
852+
.iter()
853+
.enumerate()
854+
.fold(Some(0), |acc, (i, &(x, y))| {
855+
if i <= k {
856+
opt_add(acc, x)
857+
} else {
858+
opt_add(acc, Some(y))
859+
}
860+
});
861+
849862
Ok(ExtData {
850863
pk_cost: pk_cost + n - 1, //all pk cost + (n-1)*ADD
851864
has_free_verify: true,
@@ -1043,7 +1056,7 @@ fn sat_minus_dissat_witness<'r, 's>(
10431056
.cmp(&b.0.map(|x| b.1.map(|y| x.0 as isize - y.0 as isize)))
10441057
}
10451058

1046-
// Returns Some(max(x,y)) is both x and y are Some. Otherwise, return none
1059+
/// Returns Some(max(x,y)) is both x and y are Some. Otherwise, returns `None`.
10471060
fn opt_max<T: Ord>(a: Option<T>, b: Option<T>) -> Option<T> {
10481061
if let (Some(x), Some(y)) = (a, b) {
10491062
Some(cmp::max(x, y))
@@ -1052,7 +1065,12 @@ fn opt_max<T: Ord>(a: Option<T>, b: Option<T>) -> Option<T> {
10521065
}
10531066
}
10541067

1055-
// Returns Some(x+y) is both x and y are Some. Otherwise, return none
1068+
/// Returns Some(x+y) is both x and y are Some. Otherwise, returns `None`.
10561069
fn opt_add(a: Option<usize>, b: Option<usize>) -> Option<usize> {
10571070
a.and_then(|x| b.map(|y| x + y))
10581071
}
1072+
1073+
/// Returns Some((x0+y0, x1+y1)) is both x and y are Some. Otherwise, returns `None`.
1074+
fn opt_tuple_add(a: Option<(usize, usize)>, b: Option<(usize, usize)>) -> Option<(usize, usize)> {
1075+
a.and_then(|x| b.map(|(w, s)| (w + x.0, s + x.1)))
1076+
}

0 commit comments

Comments
 (0)