Skip to content

Commit b929adf

Browse files
Overhaul ExtendWith to support arbitrary prefixes
1 parent 3a76f3d commit b929adf

File tree

1 file changed

+47
-62
lines changed

1 file changed

+47
-62
lines changed

src/treefrog.rs

Lines changed: 47 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -282,19 +282,24 @@ pub(crate) mod filters {
282282
}
283283
}
284284

285-
impl<Key: Ord, Val: Ord> Relation<(Key, Val)> {
286-
/// Extend with `Val` using the elements of the relation.
287-
pub fn extend_with<'leap, Tuple: Ord, Func: Fn(&Tuple) -> Key>(
288-
&'leap self,
289-
key_func: Func,
290-
) -> extend_with::ExtendWith<'leap, Key, Val, Tuple, Func>
291-
where
292-
Key: 'leap,
293-
Val: 'leap,
285+
impl<T: Ord + Copy> Relation<T> {
286+
/// Extend with `<T as Split<P>>::Suffix` using the elements of the relation.
287+
///
288+
/// This leaper proposes all tuples in `self` that have as a prefix the key extracted from the
289+
/// source tuple via `key_func`.
290+
///
291+
/// This leaper is analagous to a join: it finds all sets of tuples in the source and in
292+
/// the underlying relation that have a shared prefix of type `P`, and for each shared prefix
293+
/// generates the cartesian product of the two sets.
294+
pub fn extend_with<P, F, S>(&self, key_func: F) -> extend_with::ExtendWith<'_, P, T, F>
295+
where F: Fn(&S) -> P // These bounds aren't necessary and could be deferred.
296+
// They help with closure inference, however (see rust#41078).
294297
{
295298
extend_with::ExtendWith::from(self, key_func)
296299
}
300+
}
297301

302+
impl<Key: Ord, Val: Ord> Relation<(Key, Val)> {
298303
/// Extend with `Val` using the complement of the relation.
299304
pub fn extend_anti<'leap, Tuple: Ord, Func: Fn(&Tuple) -> Key>(
300305
&'leap self,
@@ -335,95 +340,75 @@ impl<Key: Ord, Val: Ord> Relation<(Key, Val)> {
335340
pub(crate) mod extend_with {
336341
use super::{binary_search, Leaper, Leapers, Relation};
337342
use crate::join::gallop;
343+
use crate::Split;
338344

339-
/// Wraps a Relation<Tuple> as a leaper.
340-
pub struct ExtendWith<'leap, Key, Val, Tuple, Func>
341-
where
342-
Key: Ord + 'leap,
343-
Val: Ord + 'leap,
344-
Tuple: Ord,
345-
Func: Fn(&Tuple) -> Key,
346-
{
347-
relation: &'leap Relation<(Key, Val)>,
345+
/// Wraps a `Relation<T>` as a leaper that proposes all values who have as a prefix the key
346+
/// extracted from the source tuple.
347+
pub struct ExtendWith<'a, P, T, F> {
348+
relation: &'a Relation<T>,
348349
start: usize,
349350
end: usize,
350-
key_func: Func,
351-
old_key: Option<Key>,
352-
phantom: ::std::marker::PhantomData<Tuple>,
351+
old_key: Option<P>,
352+
key_func: F,
353353
}
354354

355-
impl<'leap, Key, Val, Tuple, Func> ExtendWith<'leap, Key, Val, Tuple, Func>
356-
where
357-
Key: Ord + 'leap,
358-
Val: Ord + 'leap,
359-
Tuple: Ord,
360-
Func: Fn(&Tuple) -> Key,
361-
{
362-
/// Constructs a ExtendWith from a relation and key and value function.
363-
pub fn from(relation: &'leap Relation<(Key, Val)>, key_func: Func) -> Self {
364-
ExtendWith {
365-
relation,
366-
start: 0,
367-
end: 0,
368-
key_func,
369-
old_key: None,
370-
phantom: ::std::marker::PhantomData,
371-
}
355+
impl<'a, P, T, F> ExtendWith<'a, P, T, F> {
356+
/// Constructs an `ExtendWith` from a `Relation` and a key function.
357+
pub fn from(relation: &'a Relation<T>, key_func: F) -> Self {
358+
ExtendWith { relation, start: 0, end: 0, old_key: None, key_func }
372359
}
373360
}
374361

375-
impl<'leap, Key, Val, Tuple, Func> Leaper<Tuple, Val>
376-
for ExtendWith<'leap, Key, Val, Tuple, Func>
362+
impl<P, T, S, F> Leaper<S, T::Suffix> for ExtendWith<'_, P, T, F>
377363
where
378-
Key: Ord + 'leap,
379-
Val: Clone + Ord + 'leap,
380-
Tuple: Ord,
381-
Func: Fn(&Tuple) -> Key,
364+
T: Copy + Split<P>,
365+
P: Ord,
366+
T::Suffix: Ord,
367+
F: Fn(&S) -> P,
382368
{
383-
fn count(&mut self, prefix: &Tuple) -> usize {
384-
let key = (self.key_func)(prefix);
369+
fn count(&mut self, src: &S) -> usize {
370+
let key = (self.key_func)(src);
385371
if self.old_key.as_ref() != Some(&key) {
386-
self.start = binary_search(&self.relation.elements, |x| &x.0 < &key);
372+
self.start = binary_search(&self.relation.elements, |x| &x.prefix() < &key);
387373
let slice1 = &self.relation[self.start..];
388-
let slice2 = gallop(slice1, |x| &x.0 <= &key);
374+
let slice2 = gallop(slice1, |x| &x.prefix() <= &key);
389375
self.end = self.relation.len() - slice2.len();
390376

391377
self.old_key = Some(key);
392378
}
393379

394380
self.end - self.start
395381
}
396-
fn propose(&mut self, _prefix: &Tuple, values: &mut Vec<Val>) {
382+
383+
fn propose(&mut self, _src: &S, values: &mut Vec<T::Suffix>) {
397384
let slice = &self.relation[self.start..self.end];
398-
values.extend(slice.iter().map(|&(_, ref val)| val.clone()));
385+
values.extend(slice.iter().map(|val| val.suffix()));
399386
}
400-
fn intersect(&mut self, _prefix: &Tuple, values: &mut Vec<Val>) {
387+
388+
fn intersect(&mut self, _src: &S, values: &mut Vec<T::Suffix>) {
401389
let mut slice = &self.relation[self.start..self.end];
402390
values.retain(|v| {
403-
slice = gallop(slice, |kv| &kv.1 < v);
404-
slice.get(0).map(|kv| &kv.1) == Some(v)
391+
slice = gallop(slice, |kv| &kv.suffix() < v);
392+
slice.get(0).map(|kv| kv.suffix()).as_ref() == Some(v)
405393
});
406394
}
407395
}
408396

409-
impl<'leap, Key, Val, Tuple, Func> Leapers<Tuple, Val>
410-
for ExtendWith<'leap, Key, Val, Tuple, Func>
397+
impl<P, T, S, F> Leapers<S, T::Suffix> for ExtendWith<'_, P, T, F>
411398
where
412-
Key: Ord + 'leap,
413-
Val: Clone + Ord + 'leap,
414-
Tuple: Ord,
415-
Func: Fn(&Tuple) -> Key,
399+
T: Split<P>,
400+
Self: Leaper<S, T::Suffix>,
416401
{
417-
fn for_each_count(&mut self, tuple: &Tuple, mut op: impl FnMut(usize, usize)) {
402+
fn for_each_count(&mut self, tuple: &S, mut op: impl FnMut(usize, usize)) {
418403
op(0, self.count(tuple))
419404
}
420405

421-
fn propose(&mut self, tuple: &Tuple, min_index: usize, values: &mut Vec<Val>) {
406+
fn propose(&mut self, tuple: &S, min_index: usize, values: &mut Vec<T::Suffix>) {
422407
assert_eq!(min_index, 0);
423408
Leaper::propose(self, tuple, values);
424409
}
425410

426-
fn intersect(&mut self, _: &Tuple, min_index: usize, _: &mut Vec<Val>) {
411+
fn intersect(&mut self, _: &S, min_index: usize, _: &mut Vec<T::Suffix>) {
427412
assert_eq!(min_index, 0);
428413
}
429414
}

0 commit comments

Comments
 (0)