Skip to content

Commit 5f8df47

Browse files
committed
predicate leaper
1 parent 8a55b28 commit 5f8df47

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ mod treefrog;
2121
pub use treefrog::{
2222
extend_anti::ExtendAnti, extend_with::ExtendWith, filter_anti::FilterAnti,
2323
filter_with::FilterWith, Leaper, RelationLeaper,
24+
filters::{PrefixFilter, ValueFilter},
2425
};
2526

2627
/// A static, ordered list of key-value pairs.

src/treefrog.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,92 @@ pub trait Leaper<'a, Tuple, Val> {
5959
fn intersect(&mut self, prefix: &Tuple, values: &mut Vec<&'a Val>);
6060
}
6161

62+
pub mod filters {
63+
64+
use super::Leaper;
65+
66+
/// A treefrog leaper based on a per-prefix predicate.
67+
pub struct PrefixFilter<Tuple, Func: Fn(&Tuple)->bool> {
68+
phantom: ::std::marker::PhantomData<Tuple>,
69+
predicate: Func,
70+
}
71+
72+
impl<'a, Tuple, Func> PrefixFilter<Tuple, Func>
73+
where
74+
Func: Fn(&Tuple) -> bool
75+
{
76+
/// Creates a new filter based on the prefix
77+
pub fn from(predicate: Func) -> Self {
78+
PrefixFilter {
79+
phantom: ::std::marker::PhantomData,
80+
predicate,
81+
}
82+
}
83+
}
84+
85+
impl<'a, Tuple, Val, Func> Leaper<'a, Tuple, Val> for PrefixFilter<Tuple, Func>
86+
where
87+
Func: Fn(&Tuple) -> bool
88+
{
89+
/// Estimates the number of proposed values.
90+
fn count(&mut self, prefix: &Tuple) -> usize {
91+
if (self.predicate)(prefix) {
92+
usize::max_value()
93+
}
94+
else {
95+
0
96+
}
97+
}
98+
/// Populates `values` with proposed values.
99+
fn propose(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val>) {
100+
panic!("PrefixFilter::propose(): variable apparently unbound");
101+
}
102+
/// Restricts `values` to proposed values.
103+
fn intersect(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val>) {
104+
// We can only be here if we returned max_value() above.
105+
}
106+
}
107+
108+
/// A treefrog leaper based on a predicate of prefix and value.
109+
pub struct ValueFilter<Tuple, Val, Func: Fn(&Tuple, &Val)->bool> {
110+
phantom: ::std::marker::PhantomData<(Tuple, Val)>,
111+
predicate: Func,
112+
}
113+
114+
impl<'a, Tuple, Val, Func> ValueFilter<Tuple, Val, Func>
115+
where
116+
Func: Fn(&Tuple, &Val) -> bool
117+
{
118+
/// Creates a new filter based on the prefix
119+
pub fn from(predicate: Func) -> Self {
120+
ValueFilter {
121+
phantom: ::std::marker::PhantomData,
122+
predicate,
123+
}
124+
}
125+
}
126+
127+
impl<'a, Tuple, Val, Func> Leaper<'a, Tuple, Val> for ValueFilter<Tuple, Val, Func>
128+
where
129+
Func: Fn(&Tuple, &Val) -> bool
130+
{
131+
/// Estimates the number of proposed values.
132+
fn count(&mut self, _prefix: &Tuple) -> usize {
133+
usize::max_value()
134+
}
135+
/// Populates `values` with proposed values.
136+
fn propose(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val>) {
137+
panic!("PrefixFilter::propose(): variable apparently unbound");
138+
}
139+
/// Restricts `values` to proposed values.
140+
fn intersect(&mut self, prefix: &Tuple, values: &mut Vec<&'a Val>) {
141+
values.retain(|val| (self.predicate)(prefix, val));
142+
}
143+
}
144+
145+
}
146+
147+
62148
/// Extension method for relations.
63149
pub trait RelationLeaper<Key: Ord, Val: Ord> {
64150
/// Extend with `Val` using the elements of the relation.

0 commit comments

Comments
 (0)