@@ -5,7 +5,7 @@ use super::Relation;
5
5
/// Performs treefrog leapjoin using a list of leapers.
6
6
pub ( crate ) fn leapjoin < ' a , Tuple : Ord , Val : Ord + ' a , Result : Ord > (
7
7
source : & [ Tuple ] ,
8
- leapers : & mut [ & mut dyn Leaper < ' a , Tuple , Val > ] ,
8
+ mut leapers : & mut [ & mut dyn Leaper < ' a , Tuple , Val > ] ,
9
9
mut logic : impl FnMut ( & Tuple , & Val ) -> Result ,
10
10
) -> Relation < Result > {
11
11
let mut result = Vec :: new ( ) ; // temp output storage.
@@ -15,30 +15,26 @@ pub(crate) fn leapjoin<'a, Tuple: Ord, Val: Ord + 'a, Result: Ord>(
15
15
// Determine which leaper would propose the fewest values.
16
16
let mut min_index = usize:: max_value ( ) ;
17
17
let mut min_count = usize:: max_value ( ) ;
18
- for index in 0 ..leapers. len ( ) {
19
- let count = leapers[ index] . count ( tuple) ;
18
+ leapers. for_each_count ( tuple, |index, count| {
20
19
if min_count > count {
21
20
min_count = count;
22
21
min_index = index;
23
22
}
24
- }
23
+ } ) ;
25
24
26
25
// We had best have at least one relation restricting values.
27
26
assert ! ( min_count < usize :: max_value( ) ) ;
28
27
29
- // If there are values to propose ..
28
+ // If there are values to propose:
30
29
if min_count > 0 {
31
- // Propose them, ..
32
- leapers[ min_index] . propose ( tuple, & mut values) ;
33
-
34
- // Intersect them, ..
35
- for index in 0 ..leapers. len ( ) {
36
- if index != min_index {
37
- leapers[ index] . intersect ( tuple, & mut values) ;
38
- }
39
- }
30
+ // Push the values that `min_index` "proposes" into `values`.
31
+ leapers. propose ( tuple, min_index, & mut values) ;
32
+
33
+ // Give other leapers a chance to remove values from
34
+ // anti-joins or filters.
35
+ leapers. intersect ( tuple, min_index, & mut values) ;
40
36
41
- // Respond to each of them .
37
+ // Push remaining items into result .
42
38
for val in values. drain ( ..) {
43
39
result. push ( logic ( tuple, val) ) ;
44
40
}
@@ -48,6 +44,35 @@ pub(crate) fn leapjoin<'a, Tuple: Ord, Val: Ord + 'a, Result: Ord>(
48
44
Relation :: from_vec ( result)
49
45
}
50
46
47
+ pub trait Leapers < ' a , Tuple , Val > {
48
+ fn for_each_count ( & mut self , tuple : & Tuple , op : impl FnMut ( usize , usize ) ) ;
49
+
50
+ fn propose ( & mut self , tuple : & Tuple , min_index : usize , values : & mut Vec < & ' a Val > ) ;
51
+
52
+ fn intersect ( & mut self , tuple : & Tuple , min_index : usize , values : & mut Vec < & ' a Val > ) ;
53
+ }
54
+
55
+ impl < ' a , Tuple , Val > Leapers < ' a , Tuple , Val > for & mut [ & mut dyn Leaper < ' a , Tuple , Val > ] {
56
+ fn for_each_count ( & mut self , tuple : & Tuple , mut op : impl FnMut ( usize , usize ) ) {
57
+ for ( index, leaper) in self . iter_mut ( ) . enumerate ( ) {
58
+ let count = leaper. count ( tuple) ;
59
+ op ( index, count) ;
60
+ }
61
+ }
62
+
63
+ fn propose ( & mut self , tuple : & Tuple , min_index : usize , values : & mut Vec < & ' a Val > ) {
64
+ self [ min_index] . propose ( tuple, values) ;
65
+ }
66
+
67
+ fn intersect ( & mut self , tuple : & Tuple , min_index : usize , values : & mut Vec < & ' a Val > ) {
68
+ for ( index, leaper) in self . iter_mut ( ) . enumerate ( ) {
69
+ if index != min_index {
70
+ leaper. intersect ( tuple, values) ;
71
+ }
72
+ }
73
+ }
74
+ }
75
+
51
76
/// Methods to support treefrog leapjoin.
52
77
pub trait Leaper < ' a , Tuple , Val > {
53
78
/// Estimates the number of proposed values.
0 commit comments