Skip to content

Commit a6cfc9c

Browse files
tchardingjoemphilips
authored andcommitted
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 dd19e19 commit a6cfc9c

File tree

1 file changed

+53
-35
lines changed

1 file changed

+53
-35
lines changed

src/miniscript/types/extra_props.rs

+53-35
Original file line numberDiff line numberDiff line change
@@ -775,17 +775,13 @@ impl Property for ExtData {
775775
let mut ops_count = 0;
776776
let mut ops_count_sat_vec = Vec::with_capacity(n);
777777
let mut ops_count_nsat_sum = 0;
778-
let mut op_count_sat = Some(0);
779778
let mut timelocks = Vec::with_capacity(n);
780779
let mut stack_elem_count_sat_vec = Vec::with_capacity(n);
781-
let mut stack_elem_count_sat = Some(0);
782780
let mut stack_elem_count_dissat = Some(0);
783781
let mut max_sat_size_vec = Vec::with_capacity(n);
784-
let mut max_sat_size = Some((0, 0));
785782
let mut max_dissat_size = Some((0, 0));
786783
// the max element count is same as max sat element count when satisfying one element + 1
787784
let mut exec_stack_elem_count_sat_vec = Vec::with_capacity(n);
788-
let mut exec_stack_elem_count_sat = Some(0);
789785
let mut exec_stack_elem_count_dissat = Some(0);
790786

791787
for i in 0..n {
@@ -823,42 +819,59 @@ impl Property for ExtData {
823819
}
824820

825821
stack_elem_count_sat_vec.sort_by(sat_minus_option_dissat);
826-
// Sum of the cost by iterating through the sorted vector *backward*.
827-
for (i, &(x, y)) in stack_elem_count_sat_vec.iter().rev().enumerate() {
828-
stack_elem_count_sat = if i <= k {
829-
x.and_then(|x| stack_elem_count_sat.map(|count| count + x))
830-
} else {
831-
y.and_then(|y| stack_elem_count_sat.map(|count| count + y))
832-
};
833-
}
822+
let stack_elem_count_sat =
823+
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_add(acc, x)
830+
} else {
831+
opt_add(acc, y)
832+
}
833+
});
834834

835835
exec_stack_elem_count_sat_vec.sort_by(sat_minus_option_dissat);
836-
for (i, &(x, y)) in exec_stack_elem_count_sat_vec.iter().rev().enumerate() {
837-
exec_stack_elem_count_sat = if i <= k {
838-
opt_max(exec_stack_elem_count_sat, x)
839-
} else {
840-
opt_max(exec_stack_elem_count_sat, y)
841-
};
842-
}
836+
let exec_stack_elem_count_sat = exec_stack_elem_count_sat_vec
837+
.iter()
838+
.rev()
839+
.enumerate()
840+
.fold(Some(0), |acc, (i, &(x, y))| {
841+
if i <= k {
842+
opt_max(acc, x)
843+
} else {
844+
opt_max(acc, y)
845+
}
846+
});
843847

844848
// FIXME: Maybe make the ExtData struct aware of Ctx and add a one_cost() method here ?
845849
max_sat_size_vec.sort_by(sat_minus_dissat_witness);
846-
for (i, &(x, y)) in max_sat_size_vec.iter().enumerate() {
847-
max_sat_size = if i <= k {
848-
x.and_then(|x| max_sat_size.map(|(w, s)| (w + x.0, s + x.1)))
849-
} else {
850-
y.and_then(|y| max_sat_size.map(|(w, s)| (w + y.0, s + y.1)))
851-
};
852-
}
850+
let max_sat_size =
851+
max_sat_size_vec
852+
.iter()
853+
.enumerate()
854+
.fold(Some((0, 0)), |acc, (i, &(x, y))| {
855+
if i <= k {
856+
opt_tuple_add(acc, x)
857+
} else {
858+
opt_tuple_add(acc, y)
859+
}
860+
});
853861

854862
ops_count_sat_vec.sort_by(sat_minus_dissat);
855-
for (i, &(x, y)) in ops_count_sat_vec.iter().enumerate() {
856-
op_count_sat = if i <= k {
857-
opt_add(op_count_sat, x)
858-
} else {
859-
opt_add(op_count_sat, Some(y))
860-
};
861-
}
863+
let op_count_sat =
864+
ops_count_sat_vec
865+
.iter()
866+
.enumerate()
867+
.fold(Some(0), |acc, (i, &(x, y))| {
868+
if i <= k {
869+
opt_add(acc, x)
870+
} else {
871+
opt_add(acc, Some(y))
872+
}
873+
});
874+
862875
Ok(ExtData {
863876
pk_cost: pk_cost + n - 1, //all pk cost + (n-1)*ADD
864877
has_free_verify: true,
@@ -1056,7 +1069,7 @@ fn sat_minus_dissat_witness<'r, 's>(
10561069
.cmp(&b.0.map(|x| b.1.map(|y| x.0 as isize - y.0 as isize)))
10571070
}
10581071

1059-
// Returns Some(max(x,y)) is both x and y are Some. Otherwise, return none
1072+
/// Returns Some(max(x,y)) is both x and y are Some. Otherwise, returns `None`.
10601073
fn opt_max<T: Ord>(a: Option<T>, b: Option<T>) -> Option<T> {
10611074
if let (Some(x), Some(y)) = (a, b) {
10621075
Some(cmp::max(x, y))
@@ -1065,7 +1078,12 @@ fn opt_max<T: Ord>(a: Option<T>, b: Option<T>) -> Option<T> {
10651078
}
10661079
}
10671080

1068-
// Returns Some(x+y) is both x and y are Some. Otherwise, return none
1081+
/// Returns Some(x+y) is both x and y are Some. Otherwise, returns `None`.
10691082
fn opt_add(a: Option<usize>, b: Option<usize>) -> Option<usize> {
10701083
a.and_then(|x| b.map(|y| x + y))
10711084
}
1085+
1086+
/// Returns Some((x0+y0, x1+y1)) is both x and y are Some. Otherwise, returns `None`.
1087+
fn opt_tuple_add(a: Option<(usize, usize)>, b: Option<(usize, usize)>) -> Option<(usize, usize)> {
1088+
a.and_then(|x| b.map(|(w, s)| (w + x.0, s + x.1)))
1089+
}

0 commit comments

Comments
 (0)