Skip to content

Commit 2d37e7f

Browse files
authored
Merge pull request #141 from sanket1729/compiler_btree
Switch Policy to use BTreeMap from HashMap
2 parents eae1634 + 03b94d9 commit 2d37e7f

File tree

1 file changed

+27
-23
lines changed

1 file changed

+27
-23
lines changed

src/policy/compiler.rs

+27-23
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
//! Optimizing compiler from concrete policies to Miniscript
1818
//!
1919
20-
use std::collections::HashMap;
20+
use std::collections::BTreeMap;
2121
use std::convert::From;
2222
use std::marker::PhantomData;
23-
use std::{cmp, error, f64, fmt};
23+
use std::{cmp, error, f64, fmt, mem};
2424

2525
use miniscript::types::extra_props::MAX_OPS_PER_SCRIPT;
2626
use miniscript::types::{self, ErrorKind, ExtData, Property, Type};
@@ -33,7 +33,7 @@ use {policy, Terminal};
3333
use {Miniscript, MiniscriptKey};
3434

3535
type PolicyCache<Pk, Ctx> =
36-
HashMap<(Concrete<Pk>, OrdF64, Option<OrdF64>), HashMap<CompilationKey, AstElemExt<Pk, Ctx>>>;
36+
BTreeMap<(Concrete<Pk>, OrdF64, Option<OrdF64>), BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>>;
3737

3838
///Ordered f64 for comparison
3939
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
@@ -107,7 +107,7 @@ impl hash::Hash for OrdF64 {
107107

108108
/// Compilation key: This represents the state of the best possible compilation
109109
/// of a given policy(implicitly keyed).
110-
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
110+
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord)]
111111
struct CompilationKey {
112112
/// The type of the compilation result
113113
ty: Type,
@@ -646,7 +646,7 @@ fn all_casts<Pk: MiniscriptKey, Ctx: ScriptContext>() -> [Cast<Pk, Ctx>; 10] {
646646
/// In general, we maintain the invariant that if anything is inserted into the
647647
/// map, it's cast closure must also be considered for best compilations.
648648
fn insert_elem<Pk: MiniscriptKey, Ctx: ScriptContext>(
649-
map: &mut HashMap<CompilationKey, AstElemExt<Pk, Ctx>>,
649+
map: &mut BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>,
650650
elem: AstElemExt<Pk, Ctx>,
651651
sat_prob: f64,
652652
dissat_prob: Option<f64>,
@@ -680,10 +680,13 @@ fn insert_elem<Pk: MiniscriptKey, Ctx: ScriptContext>(
680680
if !is_worse {
681681
// If the element is not worse any element in the map, remove elements
682682
// whose subtype is the current element and have worse cost.
683-
map.retain(|&existing_key, existing_elem| {
684-
let existing_elem_cost = existing_elem.cost_1d(sat_prob, dissat_prob);
685-
!(elem_key.is_subtype(existing_key) && existing_elem_cost >= elem_cost)
686-
});
683+
*map = mem::replace(map, BTreeMap::new())
684+
.into_iter()
685+
.filter(|&(ref existing_key, ref existing_elem)| {
686+
let existing_elem_cost = existing_elem.cost_1d(sat_prob, dissat_prob);
687+
!(elem_key.is_subtype(*existing_key) && existing_elem_cost >= elem_cost)
688+
})
689+
.collect();
687690
map.insert(elem_key, elem);
688691
}
689692
!is_worse
@@ -698,7 +701,7 @@ fn insert_elem<Pk: MiniscriptKey, Ctx: ScriptContext>(
698701
/// all map is smallest possible closure of all compilations of a policy with
699702
/// given sat and dissat probabilities.
700703
fn insert_elem_closure<Pk: MiniscriptKey, Ctx: ScriptContext>(
701-
map: &mut HashMap<CompilationKey, AstElemExt<Pk, Ctx>>,
704+
map: &mut BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>,
702705
astelem_ext: AstElemExt<Pk, Ctx>,
703706
sat_prob: f64,
704707
dissat_prob: Option<f64>,
@@ -734,7 +737,7 @@ fn insert_elem_closure<Pk: MiniscriptKey, Ctx: ScriptContext>(
734737
fn insert_best_wrapped<Pk: MiniscriptKey, Ctx: ScriptContext>(
735738
policy_cache: &mut PolicyCache<Pk, Ctx>,
736739
policy: &Concrete<Pk>,
737-
map: &mut HashMap<CompilationKey, AstElemExt<Pk, Ctx>>,
740+
map: &mut BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>,
738741
data: AstElemExt<Pk, Ctx>,
739742
sat_prob: f64,
740743
dissat_prob: Option<f64>,
@@ -762,7 +765,7 @@ fn best_compilations<Pk, Ctx>(
762765
policy: &Concrete<Pk>,
763766
sat_prob: f64,
764767
dissat_prob: Option<f64>,
765-
) -> Result<HashMap<CompilationKey, AstElemExt<Pk, Ctx>>, CompilerError>
768+
) -> Result<BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>, CompilerError>
766769
where
767770
Pk: MiniscriptKey,
768771
Ctx: ScriptContext,
@@ -774,7 +777,7 @@ where
774777
return Ok(ret.clone());
775778
}
776779

777-
let mut ret = HashMap::new();
780+
let mut ret = BTreeMap::new();
778781

779782
//handy macro for good looking code
780783
macro_rules! insert_wrap {
@@ -843,7 +846,7 @@ where
843846
compile_binary!(&mut right, &mut left, [1.0, 1.0], Terminal::AndB);
844847
compile_binary!(&mut left, &mut right, [1.0, 1.0], Terminal::AndV);
845848
compile_binary!(&mut right, &mut left, [1.0, 1.0], Terminal::AndV);
846-
let mut zero_comp = HashMap::new();
849+
let mut zero_comp = BTreeMap::new();
847850
zero_comp.insert(
848851
CompilationKey::from_type(
849852
Type::from_false(),
@@ -1042,9 +1045,9 @@ where
10421045
fn compile_binary<Pk, Ctx, F>(
10431046
policy_cache: &mut PolicyCache<Pk, Ctx>,
10441047
policy: &Concrete<Pk>,
1045-
ret: &mut HashMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1046-
left_comp: &mut HashMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1047-
right_comp: &mut HashMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1048+
ret: &mut BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1049+
left_comp: &mut BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1050+
right_comp: &mut BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>,
10481051
weights: [f64; 2],
10491052
sat_prob: f64,
10501053
dissat_prob: Option<f64>,
@@ -1076,10 +1079,10 @@ where
10761079
fn compile_tern<Pk: MiniscriptKey, Ctx: ScriptContext>(
10771080
policy_cache: &mut PolicyCache<Pk, Ctx>,
10781081
policy: &Concrete<Pk>,
1079-
ret: &mut HashMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1080-
a_comp: &mut HashMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1081-
b_comp: &mut HashMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1082-
c_comp: &mut HashMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1082+
ret: &mut BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1083+
a_comp: &mut BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1084+
b_comp: &mut BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>,
1085+
c_comp: &mut BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>,
10831086
weights: [f64; 2],
10841087
sat_prob: f64,
10851088
dissat_prob: Option<f64>,
@@ -1170,6 +1173,7 @@ mod tests {
11701173
use super::*;
11711174
use bitcoin::blockdata::{opcodes, script};
11721175
use bitcoin::{self, hashes, secp256k1, SigHashType};
1176+
use std::collections::HashMap;
11731177
use std::str::FromStr;
11741178
use std::string::String;
11751179

@@ -1272,7 +1276,7 @@ mod tests {
12721276
fn compile_q() {
12731277
let policy = SPolicy::from_str("or(1@and(pk(),pk()),127@pk())").expect("parsing");
12741278
let compilation: DummySegwitAstElemExt =
1275-
best_t(&mut HashMap::new(), &policy, 1.0, None).unwrap();
1279+
best_t(&mut BTreeMap::new(), &policy, 1.0, None).unwrap();
12761280

12771281
assert_eq!(compilation.cost_1d(1.0, None), 88.0 + 74.109375);
12781282
assert_eq!(
@@ -1284,7 +1288,7 @@ mod tests {
12841288
"and(and(and(or(127@thresh(2,pk(),pk(),thresh(2,or(127@pk(),1@pk()),after(100),or(and(pk(),after(200)),and(pk(),sha256(66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925))),pk())),1@pk()),sha256(66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925)),or(127@pk(),1@after(300))),or(127@after(400),pk()))"
12851289
).expect("parsing");
12861290
let compilation: DummySegwitAstElemExt =
1287-
best_t(&mut HashMap::new(), &policy, 1.0, None).unwrap();
1291+
best_t(&mut BTreeMap::new(), &policy, 1.0, None).unwrap();
12881292

12891293
assert_eq!(compilation.cost_1d(1.0, None), 437.0 + 299.4003295898438);
12901294
assert_eq!(

0 commit comments

Comments
 (0)