Skip to content

Commit 8df81fc

Browse files
frankmcsherrynikomatsakis
authored andcommitted
second hop
1 parent b77f690 commit 8df81fc

File tree

1 file changed

+77
-113
lines changed

1 file changed

+77
-113
lines changed

src/leapfrog.rs

Lines changed: 77 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -10,50 +10,47 @@ pub fn leapfrog_into<'a, Tuple: Ord, Val: Ord+'a, Result: Ord>(
1010
mut logic: impl FnMut(&Tuple, &Val)->Result) {
1111

1212
let mut result = Vec::new();
13+
let mut values = Vec::new();
1314

1415
for tuple in source.recent.borrow().iter() {
1516

16-
for leaper in leapers.iter_mut() {
17-
leaper.seek_prefix(tuple);
17+
let mut min_index = usize::max_value();
18+
let mut min_count = usize::max_value();
19+
for index in 0 .. leapers.len() {
20+
let count = leapers[index].count(tuple);
21+
if min_count > count {
22+
min_count = count;
23+
min_index = index;
24+
}
1825
}
1926

20-
while !leapers.iter().any(|l| l.is_empty()) {
21-
// for leaper in leapers.iter() { println!("{:?}, {:?}", leaper.peek_val().is_some(), leaper.is_empty()); }
22-
let val = leapers.iter_mut().flat_map(|l| l.peek_val()).max().expect("No maximum found");
23-
let mut present = true;
24-
for leaper in leapers.iter_mut() {
25-
if !leaper.seek_val(&val) { present = false; }
27+
assert!(min_count < usize::max_value());
28+
if min_count > 0 {
29+
leapers[min_index].propose(tuple, &mut values);
30+
31+
for index in 0 .. leapers.len() {
32+
if index != min_index {
33+
leapers[index].intersect(tuple, &mut values);
34+
}
2635
}
27-
if present {
28-
result.push(logic(&tuple, &val));
36+
37+
for val in values.drain(..) {
38+
result.push(logic(tuple, val));
2939
}
3040
}
31-
3241
}
3342

3443
output.insert(result.into());
3544
}
3645

3746
/// Methods to support leapfrog navigation.
3847
pub trait LeapFrog<'a,Tuple,Val> {
39-
/// Sets the cursor for a specific key.
40-
fn seek_prefix(&mut self, prefix: &Tuple);
41-
/// Seeks a specific key and value pair.
42-
///
43-
/// This method positions the cursor just after `val`,
44-
/// under the assumption that we will not seek for the
45-
/// same value immediately afterwards.
46-
fn seek_val(&mut self, val: &Val) -> bool;
47-
/// Proposes a next value.
48-
///
49-
/// It is not mandatory that this method return a value,
50-
/// but we will only observe extensions in the union of
51-
/// peeked values. This allows antijoin implementations
52-
/// to implement this interface, as long as at least one
53-
/// normal join participates.
54-
fn peek_val(&self) -> Option<&'a Val>;
55-
/// Indicates no further values available.
56-
fn is_empty(&self) -> bool;
48+
/// Estimates the number of proposed values.
49+
fn count(&mut self, prefix: &Tuple) -> usize;
50+
/// Populates `values` with proposed values.
51+
fn propose(&mut self, prefix: &Tuple, values: &mut Vec<&'a Val>);
52+
/// Restricts `values` to proposed values.
53+
fn intersect(&mut self, prefix: &Tuple, values: &mut Vec<&'a Val>);
5754
}
5855

5956
/// Extension method for relations.
@@ -110,42 +107,25 @@ mod extend_with {
110107
}
111108

112109
impl<'a, Key: Ord, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->Key> LeapFrog<'a, Tuple,Val> for ExtendWith<'a, Key, Val, Tuple, Func> {
113-
fn seek_prefix(&mut self, tuple: &Tuple) {
114-
let key = (self.key_func)(tuple);
110+
111+
fn count(&mut self, prefix: &Tuple) -> usize {
112+
let key = (self.key_func)(prefix);
115113
let slice1 = gallop(&self.relation[..], |x| &x.0 < &key);
116114
let slice2 = gallop(slice1, |x| &x.0 <= &key);
117115
self.start = self.relation.len() - slice1.len();
118116
self.end = self.relation.len() - slice2.len();
119-
assert!(self.start <= self.end);
120-
}
121-
fn seek_val(&mut self, val: &Val) -> bool {
122-
assert!(self.start <= self.end);
123-
// Attempt to position the cursor at (key, val).
124-
if !self.is_empty() {
125-
let slice = gallop(&self.relation[self.start .. self.end], |x| &x.1 < val);
126-
self.start = self.end - slice.len();
127-
}
128-
// If the cursor is positioned at something that yields `val`, then success.
129-
if self.peek_val() == Some(val) {
130-
self.start += 1;
131-
true
132-
}
133-
else {
134-
false
135-
}
117+
slice1.len() - slice2.len()
136118
}
137-
fn peek_val(&self) -> Option<&'a Val> {
138-
assert!(self.start <= self.end);
139-
if self.start < self.end {
140-
Some(&self.relation[self.start].1)
141-
}
142-
else {
143-
None
144-
}
119+
fn propose(&mut self, _prefix: &Tuple, values: &mut Vec<&'a Val>) {
120+
let slice = &self.relation[self.start .. self.end];
121+
values.extend(slice.iter().map(|&(_, ref val)| val));
145122
}
146-
fn is_empty(&self) -> bool {
147-
assert!(self.start <= self.end);
148-
self.start == self.end
123+
fn intersect(&mut self, _prefix: &Tuple, values: &mut Vec<&'a Val>) {
124+
let mut slice = &self.relation[self.start .. self.end];
125+
values.retain(|v| {
126+
slice = gallop(slice, |kv| &kv.1 < v);
127+
slice.get(0).map(|kv| &kv.1) == Some(v)
128+
});
149129
}
150130
}
151131
}
@@ -157,8 +137,6 @@ mod extend_anti {
157137
/// Wraps a Relation<Tuple> as a leaper.
158138
pub struct ExtendAnti<'a, Key: Ord+'a, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->Key> {
159139
relation: &'a Relation<(Key, Val)>,
160-
start: usize,
161-
end: usize,
162140
key_func: Func,
163141
phantom: ::std::marker::PhantomData<Tuple>,
164142
}
@@ -168,44 +146,30 @@ mod extend_anti {
168146
pub fn from(relation: &'a Relation<(Key, Val)>, key_func: Func) -> Self {
169147
ExtendAnti {
170148
relation,
171-
start: 0,
172-
end: 0,
173149
key_func,
174150
phantom: ::std::marker::PhantomData,
175151
}
176152
}
177153
}
178154

179155
impl<'a, Key: Ord, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->Key> LeapFrog<'a, Tuple,Val> for ExtendAnti<'a, Key, Val, Tuple, Func> {
180-
fn seek_prefix(&mut self, tuple: &Tuple) {
181-
let key = (self.key_func)(tuple);
156+
fn count(&mut self, _prefix: &Tuple) -> usize {
157+
usize::max_value()
158+
}
159+
fn propose(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val>) {
160+
panic!("ExtendAnti::propose(): variable apparently unbound.");
161+
}
162+
fn intersect(&mut self, prefix: &Tuple, values: &mut Vec<&'a Val>) {
163+
let key = (self.key_func)(prefix);
182164
let slice1 = gallop(&self.relation[..], |x| &x.0 < &key);
183165
let slice2 = gallop(slice1, |x| &x.0 <= &key);
184-
self.start = self.relation.len() - slice1.len();
185-
self.end = self.relation.len() - slice2.len();
186-
assert!(self.start <= self.end);
187-
}
188-
fn seek_val(&mut self, val: &Val) -> bool {
189-
assert!(self.start <= self.end);
190-
// Attempt to position the cursor at (key, val).
191-
if !self.is_empty() {
192-
let slice = gallop(&self.relation[self.start .. self.end], |x| &x.1 < val);
193-
self.start = self.end - slice.len();
194-
}
195-
// If the cursor is positioned at something that yields `val`, then success.
196-
if self.start < self.end && &self.relation[self.start].1 == val {
197-
self.start += 1;
198-
false
166+
let mut slice = &slice1[.. (slice1.len() - slice2.len())];
167+
if !slice.is_empty() {
168+
values.retain(|v| {
169+
slice = gallop(slice, |kv| &kv.1 < v);
170+
slice.get(0).map(|kv| &kv.1) != Some(v)
171+
});
199172
}
200-
else {
201-
true
202-
}
203-
}
204-
fn peek_val(&self) -> Option<&'a Val> {
205-
None
206-
}
207-
fn is_empty(&self) -> bool {
208-
false
209173
}
210174
}
211175
}
@@ -218,7 +182,6 @@ mod filter_with {
218182
pub struct FilterWith<'a, Key: Ord+'a, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->(Key,Val)> {
219183
relation: &'a Relation<(Key, Val)>,
220184
key_func: Func,
221-
found: bool,
222185
phantom: ::std::marker::PhantomData<Tuple>,
223186
}
224187

@@ -228,25 +191,26 @@ mod filter_with {
228191
FilterWith {
229192
relation,
230193
key_func,
231-
found: false,
232194
phantom: ::std::marker::PhantomData,
233195
}
234196
}
235197
}
236198

237199
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> {
238-
fn seek_prefix(&mut self, tuple: &Tuple) {
239-
let key_val = (self.key_func)(tuple);
240-
self.found = self.relation.binary_search(&key_val).is_ok();
241-
}
242-
fn seek_val(&mut self, _val: &Val2) -> bool {
243-
self.found
200+
fn count(&mut self, prefix: &Tuple) -> usize {
201+
let key_val = (self.key_func)(prefix);
202+
if self.relation.binary_search(&key_val).is_ok() {
203+
usize::max_value()
204+
}
205+
else {
206+
0
207+
}
244208
}
245-
fn peek_val(&self) -> Option<&'a Val2> {
246-
None
209+
fn propose(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val2>) {
210+
panic!("FilterWith::propose(): variable apparently unbound.");
247211
}
248-
fn is_empty(&self) -> bool {
249-
!self.found
212+
fn intersect(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val2>) {
213+
// Only here because we didn't return zero above, right?
250214
}
251215
}
252216
}
@@ -259,7 +223,6 @@ mod filter_anti {
259223
pub struct FilterAnti<'a, Key: Ord+'a, Val: Ord+'a, Tuple: Ord, Func: Fn(&Tuple)->(Key,Val)> {
260224
relation: &'a Relation<(Key, Val)>,
261225
key_func: Func,
262-
found: bool,
263226
phantom: ::std::marker::PhantomData<Tuple>,
264227
}
265228

@@ -269,25 +232,26 @@ mod filter_anti {
269232
FilterAnti {
270233
relation,
271234
key_func,
272-
found: false,
273235
phantom: ::std::marker::PhantomData,
274236
}
275237
}
276238
}
277239

278240
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> {
279-
fn seek_prefix(&mut self, tuple: &Tuple) {
280-
let key_val = (self.key_func)(tuple);
281-
self.found = self.relation.binary_search(&key_val).is_ok();
282-
}
283-
fn seek_val(&mut self, _val: &Val2) -> bool {
284-
!self.found
241+
fn count(&mut self, prefix: &Tuple) -> usize {
242+
let key_val = (self.key_func)(prefix);
243+
if self.relation.binary_search(&key_val).is_ok() {
244+
0
245+
}
246+
else {
247+
usize::max_value()
248+
}
285249
}
286-
fn peek_val(&self) -> Option<&'a Val2> {
287-
None
250+
fn propose(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val2>) {
251+
panic!("FilterWith::propose(): variable apparently unbound.");
288252
}
289-
fn is_empty(&self) -> bool {
290-
self.found
253+
fn intersect(&mut self, _prefix: &Tuple, _values: &mut Vec<&'a Val2>) {
254+
// Only here because we didn't return zero above, right?
291255
}
292256
}
293257
}

0 commit comments

Comments
 (0)