Skip to content

Commit 2689e39

Browse files
authored
Merge pull request #20 from rust-lang-nursery/filter_leaper
Predicate leaper [WIP]
2 parents 8a55b28 + cda06b6 commit 2689e39

File tree

2 files changed

+90
-2
lines changed

2 files changed

+90
-2
lines changed

src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@ mod join;
1919
mod map;
2020
mod treefrog;
2121
pub use treefrog::{
22-
extend_anti::ExtendAnti, extend_with::ExtendWith, filter_anti::FilterAnti,
23-
filter_with::FilterWith, Leaper, RelationLeaper,
22+
extend_anti::ExtendAnti,
23+
extend_with::ExtendWith,
24+
filter_anti::FilterAnti,
25+
filter_with::FilterWith,
26+
filters::{PrefixFilter, ValueFilter},
27+
Leaper, RelationLeaper,
2428
};
2529

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

src/treefrog.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,90 @@ 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+
} else {
94+
0
95+
}
96+
}
97+
/// Populates `values` with proposed values.
98+
fn propose(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val>) {
99+
panic!("PrefixFilter::propose(): variable apparently unbound");
100+
}
101+
/// Restricts `values` to proposed values.
102+
fn intersect(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val>) {
103+
// We can only be here if we returned max_value() above.
104+
}
105+
}
106+
107+
/// A treefrog leaper based on a predicate of prefix and value.
108+
pub struct ValueFilter<Tuple, Val, Func: Fn(&Tuple, &Val) -> bool> {
109+
phantom: ::std::marker::PhantomData<(Tuple, Val)>,
110+
predicate: Func,
111+
}
112+
113+
impl<'a, Tuple, Val, Func> ValueFilter<Tuple, Val, Func>
114+
where
115+
Func: Fn(&Tuple, &Val) -> bool,
116+
{
117+
/// Creates a new filter based on the prefix
118+
pub fn from(predicate: Func) -> Self {
119+
ValueFilter {
120+
phantom: ::std::marker::PhantomData,
121+
predicate,
122+
}
123+
}
124+
}
125+
126+
impl<'a, Tuple, Val, Func> Leaper<'a, Tuple, Val> for ValueFilter<Tuple, Val, Func>
127+
where
128+
Func: Fn(&Tuple, &Val) -> bool,
129+
{
130+
/// Estimates the number of proposed values.
131+
fn count(&mut self, _prefix: &Tuple) -> usize {
132+
usize::max_value()
133+
}
134+
/// Populates `values` with proposed values.
135+
fn propose(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val>) {
136+
panic!("PrefixFilter::propose(): variable apparently unbound");
137+
}
138+
/// Restricts `values` to proposed values.
139+
fn intersect(&mut self, prefix: &Tuple, values: &mut Vec<&'a Val>) {
140+
values.retain(|val| (self.predicate)(prefix, val));
141+
}
142+
}
143+
144+
}
145+
62146
/// Extension method for relations.
63147
pub trait RelationLeaper<Key: Ord, Val: Ord> {
64148
/// Extend with `Val` using the elements of the relation.

0 commit comments

Comments
 (0)