@@ -282,19 +282,24 @@ pub(crate) mod filters {
282282 }
283283}
284284
285- impl < Key : Ord , Val : Ord > Relation < ( Key , Val ) > {
285+ impl < T : Ord + Copy > Relation < T > {
286286 /// 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 ,
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 looks for tuples in the source and in the underlying
292+ /// relation that have a shared prefix of type `P`, and for each shared prefix generates the
293+ /// cartesian product of those two groups.
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)> {
335340pub ( 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