Skip to content

Commit 5cbbc21

Browse files
frankmcsherrynikomatsakis
authored andcommitted
nomenclature revamp
1 parent 15bd998 commit 5cbbc21

File tree

1 file changed

+47
-20
lines changed

1 file changed

+47
-20
lines changed

src/leapfrog.rs

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@
22
33
use super::{Variable, Relation};
44

5-
/// Performs leapfrog join using a list of leapers.
6-
pub fn leapfrog_into<'a, Tuple: Ord, Val: Ord+'a, Result: Ord>(
5+
/// Performs treefrog leapjoin using a list of leapers.
6+
pub fn leapjoin_into<'a, Tuple: Ord, Val: Ord+'a, Result: Ord>(
77
source: &Variable<Tuple>,
8-
leapers: &mut [&mut LeapFrog<'a, Tuple, Val>],
8+
leapers: &mut [&mut Leaper<'a, Tuple, Val>],
99
output: &Variable<Result>,
1010
mut logic: impl FnMut(&Tuple, &Val)->Result) {
1111

12-
let mut result = Vec::new();
13-
let mut values = Vec::new();
12+
let mut result = Vec::new(); // temp output storage.
13+
let mut values = Vec::new(); // temp value storage.
1414

1515
for tuple in source.recent.borrow().iter() {
1616

17+
// Determine which leaper would propose the fewest values.
1718
let mut min_index = usize::max_value();
1819
let mut min_count = usize::max_value();
1920
for index in 0 .. leapers.len() {
@@ -24,16 +25,23 @@ pub fn leapfrog_into<'a, Tuple: Ord, Val: Ord+'a, Result: Ord>(
2425
}
2526
}
2627

28+
// We had best have at least one relation restricting values.
2729
assert!(min_count < usize::max_value());
30+
31+
// If there are values to propose ..
2832
if min_count > 0 {
33+
34+
// Propose them, ..
2935
leapers[min_index].propose(tuple, &mut values);
3036

37+
// Intersect them, ..
3138
for index in 0 .. leapers.len() {
3239
if index != min_index {
3340
leapers[index].intersect(tuple, &mut values);
3441
}
3542
}
3643

44+
// Respond to each of them.
3745
for val in values.drain(..) {
3846
result.push(logic(tuple, val));
3947
}
@@ -43,8 +51,8 @@ pub fn leapfrog_into<'a, Tuple: Ord, Val: Ord+'a, Result: Ord>(
4351
output.insert(result.into());
4452
}
4553

46-
/// Methods to support leapfrog navigation.
47-
pub trait LeapFrog<'a,Tuple,Val> {
54+
/// Methods to support treefrog leapjoin.
55+
pub trait Leaper<'a,Tuple,Val> {
4856
/// Estimates the number of proposed values.
4957
fn count(&mut self, prefix: &Tuple) -> usize;
5058
/// Populates `values` with proposed values.
@@ -54,7 +62,7 @@ pub trait LeapFrog<'a,Tuple,Val> {
5462
}
5563

5664
/// Extension method for relations.
57-
pub trait Leaper<Key: Ord, Val: Ord> {
65+
pub trait RelationLeaper<Key: Ord, Val: Ord> {
5866
/// Extend with `Val` using the elements of the relation.
5967
fn extend_with<'a, Tuple: Ord, Func: Fn(&Tuple)->Key>(&'a self, key_func: Func) -> extend_with::ExtendWith<'a, Key, Val, Tuple, Func> where Key: 'a, Val: 'a;
6068
/// Extend with `Val` using the complement of the relation.
@@ -65,7 +73,7 @@ pub trait Leaper<Key: Ord, Val: Ord> {
6573
fn filter_anti<'a, Tuple: Ord, Func: Fn(&Tuple)->(Key,Val)>(&'a self, key_func: Func) -> filter_anti::FilterAnti<'a, Key, Val, Tuple, Func> where Key: 'a, Val: 'a;
6674
}
6775

68-
impl<Key: Ord, Val: Ord> Leaper<Key, Val> for Relation<(Key, Val)> {
76+
impl<Key: Ord, Val: Ord> RelationLeaper<Key, Val> for Relation<(Key, Val)> {
6977
fn extend_with<'a, Tuple: Ord, Func: Fn(&Tuple)->Key>(&'a self, key_func: Func) -> extend_with::ExtendWith<'a, Key, Val, Tuple, Func> where Key: 'a, Val: 'a {
7078
extend_with::ExtendWith::from(self, key_func)
7179
}
@@ -82,7 +90,7 @@ impl<Key: Ord, Val: Ord> Leaper<Key, Val> for Relation<(Key, Val)> {
8290

8391
mod extend_with {
8492

85-
use super::{Relation, LeapFrog, gallop};
93+
use super::{Relation, Leaper, gallop, binary_search};
8694

8795
/// Wraps a Relation<Tuple> as a leaper.
8896
pub struct ExtendWith<'a, Key: Ord+'a, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->Key> {
@@ -106,13 +114,13 @@ mod extend_with {
106114
}
107115
}
108116

109-
impl<'a, Key: Ord, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->Key> LeapFrog<'a, Tuple,Val> for ExtendWith<'a, Key, Val, Tuple, Func> {
117+
impl<'a, Key: Ord, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->Key> Leaper<'a, Tuple,Val> for ExtendWith<'a, Key, Val, Tuple, Func> {
110118

111119
fn count(&mut self, prefix: &Tuple) -> usize {
112120
let key = (self.key_func)(prefix);
113-
let slice1 = gallop(&self.relation[..], |x| &x.0 < &key);
121+
self.start = binary_search(&self.relation[..], |x| &x.0 < &key);
122+
let slice1 = &self.relation[self.start ..];
114123
let slice2 = gallop(slice1, |x| &x.0 <= &key);
115-
self.start = self.relation.len() - slice1.len();
116124
self.end = self.relation.len() - slice2.len();
117125
slice1.len() - slice2.len()
118126
}
@@ -132,7 +140,7 @@ mod extend_with {
132140

133141
mod extend_anti {
134142

135-
use super::{Relation, LeapFrog, gallop};
143+
use super::{Relation, Leaper, gallop, binary_search};
136144

137145
/// Wraps a Relation<Tuple> as a leaper.
138146
pub struct ExtendAnti<'a, Key: Ord+'a, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->Key> {
@@ -152,7 +160,7 @@ mod extend_anti {
152160
}
153161
}
154162

155-
impl<'a, Key: Ord, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->Key> LeapFrog<'a, Tuple,Val> for ExtendAnti<'a, Key, Val, Tuple, Func> {
163+
impl<'a, Key: Ord, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->Key> Leaper<'a, Tuple,Val> for ExtendAnti<'a, Key, Val, Tuple, Func> {
156164
fn count(&mut self, _prefix: &Tuple) -> usize {
157165
usize::max_value()
158166
}
@@ -161,7 +169,8 @@ mod extend_anti {
161169
}
162170
fn intersect(&mut self, prefix: &Tuple, values: &mut Vec<&'a Val>) {
163171
let key = (self.key_func)(prefix);
164-
let slice1 = gallop(&self.relation[..], |x| &x.0 < &key);
172+
let start = binary_search(&self.relation[..], |x| &x.0 < &key);
173+
let slice1 = &self.relation[start..];
165174
let slice2 = gallop(slice1, |x| &x.0 <= &key);
166175
let mut slice = &slice1[.. (slice1.len() - slice2.len())];
167176
if !slice.is_empty() {
@@ -176,7 +185,7 @@ mod extend_anti {
176185

177186
mod filter_with {
178187

179-
use super::{Relation, LeapFrog};
188+
use super::{Relation, Leaper};
180189

181190
/// Wraps a Relation<Tuple> as a leaper.
182191
pub struct FilterWith<'a, Key: Ord+'a, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->(Key,Val)> {
@@ -196,7 +205,7 @@ mod filter_with {
196205
}
197206
}
198207

199-
impl<'a, Key: Ord, Val: Ord+'a, Val2, Tuple: Ord, Func: Fn(&Tuple)->(Key,Val)> LeapFrog<'a,Tuple,Val2> for FilterWith<'a, Key, Val, Tuple, Func> {
208+
impl<'a, Key: Ord, Val: Ord+'a, Val2, Tuple: Ord, Func: Fn(&Tuple)->(Key,Val)> Leaper<'a,Tuple,Val2> for FilterWith<'a, Key, Val, Tuple, Func> {
200209
fn count(&mut self, prefix: &Tuple) -> usize {
201210
let key_val = (self.key_func)(prefix);
202211
if self.relation.binary_search(&key_val).is_ok() {
@@ -217,7 +226,7 @@ mod filter_with {
217226

218227
mod filter_anti {
219228

220-
use super::{Relation, LeapFrog};
229+
use super::{Relation, Leaper};
221230

222231
/// Wraps a Relation<Tuple> as a leaper.
223232
pub struct FilterAnti<'a, Key: Ord+'a, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->(Key,Val)> {
@@ -237,7 +246,7 @@ mod filter_anti {
237246
}
238247
}
239248

240-
impl<'a, Key: Ord, Val: Ord+'a, Val2, Tuple: Ord, Func: Fn(&Tuple)->(Key,Val)> LeapFrog<'a,Tuple,Val2> for FilterAnti<'a, Key, Val, Tuple, Func> {
249+
impl<'a, Key: Ord, Val: Ord+'a, Val2, Tuple: Ord, Func: Fn(&Tuple)->(Key,Val)> Leaper<'a,Tuple,Val2> for FilterAnti<'a, Key, Val, Tuple, Func> {
241250
fn count(&mut self, prefix: &Tuple) -> usize {
242251
let key_val = (self.key_func)(prefix);
243252
if self.relation.binary_search(&key_val).is_ok() {
@@ -256,6 +265,24 @@ mod filter_anti {
256265
}
257266
}
258267

268+
fn binary_search<T>(slice: &[T], mut cmp: impl FnMut(&T)->bool) -> usize {
269+
270+
// we maintain the invariant that `lo` many elements of `slice` satisfy `cmp`.
271+
// `hi` is maintained at the first element we know does not satisfy `cmp`.
272+
273+
let mut hi = slice.len();
274+
let mut lo = 0;
275+
while lo < hi {
276+
let mid = lo + (hi - lo)/2;
277+
if cmp(&slice[mid]) {
278+
lo = mid + 1;
279+
}
280+
else {
281+
hi = mid;
282+
}
283+
}
284+
lo
285+
}
259286

260287
fn gallop<T>(mut slice: &[T], mut cmp: impl FnMut(&T)->bool) -> &[T] {
261288
// if empty slice, or already >= element, return

0 commit comments

Comments
 (0)