1
1
//! Join functionality.
2
2
3
- use super :: { Relation , Variable } ;
3
+ use super :: { Relation , Split , Variable } ;
4
4
use std:: cell:: Ref ;
5
5
use std:: ops:: Deref ;
6
6
@@ -9,28 +9,38 @@ use std::ops::Deref;
9
9
/// because relations have no "recent" tuples, so the fn would be a
10
10
/// guaranteed no-op if both arguments were relations. See also
11
11
/// `join_into_relation`.
12
- pub ( crate ) fn join_into < ' me , Key : Ord , Val1 : Ord , Val2 : Ord , Result : Ord > (
13
- input1 : & Variable < ( Key , Val1 ) > ,
14
- input2 : impl JoinInput < ' me , ( Key , Val2 ) > ,
15
- output : & Variable < Result > ,
16
- mut logic : impl FnMut ( & Key , & Val1 , & Val2 ) -> Result ,
17
- ) {
12
+ pub ( crate ) fn join_into < ' me , P , A , B , O > (
13
+ input1 : & Variable < A > ,
14
+ input2 : impl JoinInput < ' me , B > ,
15
+ output : & Variable < O > ,
16
+ mut logic : impl FnMut ( P , A :: Suffix , B :: Suffix ) -> O ,
17
+ ) where
18
+ P : Ord ,
19
+ A : Copy + Split < P > ,
20
+ B : Copy + Split < P > ,
21
+ O : Ord ,
22
+ {
18
23
let mut results = Vec :: new ( ) ;
19
- let push_result = |k : & Key , v1 : & Val1 , v2 : & Val2 | results. push ( logic ( k, v1, v2) ) ;
24
+ let push_result = |k, v1, v2| results. push ( logic ( k, v1, v2) ) ;
20
25
21
26
join_delta ( input1, input2, push_result) ;
22
27
23
28
output. insert ( Relation :: from_vec ( results) ) ;
24
29
}
25
30
26
- pub ( crate ) fn join_and_filter_into < ' me , Key : Ord , Val1 : Ord , Val2 : Ord , Result : Ord > (
27
- input1 : & Variable < ( Key , Val1 ) > ,
28
- input2 : impl JoinInput < ' me , ( Key , Val2 ) > ,
29
- output : & Variable < Result > ,
30
- mut logic : impl FnMut ( & Key , & Val1 , & Val2 ) -> Option < Result > ,
31
- ) {
31
+ pub ( crate ) fn join_and_filter_into < ' me , P , A , B , O > (
32
+ input1 : & Variable < A > ,
33
+ input2 : impl JoinInput < ' me , B > ,
34
+ output : & Variable < O > ,
35
+ mut logic : impl FnMut ( P , A :: Suffix , B :: Suffix ) -> Option < O > ,
36
+ ) where
37
+ P : Ord ,
38
+ A : Copy + Split < P > ,
39
+ B : Copy + Split < P > ,
40
+ O : Ord ,
41
+ {
32
42
let mut results = Vec :: new ( ) ;
33
- let push_result = |k : & Key , v1 : & Val1 , v2 : & Val2 | {
43
+ let push_result = |k, v1, v2| {
34
44
if let Some ( result) = logic ( k, v1, v2) {
35
45
results. push ( result) ;
36
46
}
@@ -43,11 +53,15 @@ pub(crate) fn join_and_filter_into<'me, Key: Ord, Val1: Ord, Val2: Ord, Result:
43
53
44
54
/// Joins the `recent` tuples of each input with the `stable` tuples of the other, then the
45
55
/// `recent` tuples of *both* inputs.
46
- fn join_delta < ' me , Key : Ord , Val1 : Ord , Val2 : Ord > (
47
- input1 : & Variable < ( Key , Val1 ) > ,
48
- input2 : impl JoinInput < ' me , ( Key , Val2 ) > ,
49
- mut result : impl FnMut ( & Key , & Val1 , & Val2 ) ,
50
- ) {
56
+ fn join_delta < ' me , P , A , B > (
57
+ input1 : & Variable < A > ,
58
+ input2 : impl JoinInput < ' me , B > ,
59
+ mut result : impl FnMut ( P , A :: Suffix , B :: Suffix ) ,
60
+ ) where
61
+ P : Ord ,
62
+ A : Copy + Split < P > ,
63
+ B : Copy + Split < P > ,
64
+ {
51
65
let recent1 = input1. recent ( ) ;
52
66
let recent2 = input2. recent ( ) ;
53
67
@@ -63,11 +77,17 @@ fn join_delta<'me, Key: Ord, Val1: Ord, Val2: Ord>(
63
77
}
64
78
65
79
/// Join, but for two relations.
66
- pub ( crate ) fn join_into_relation < ' me , Key : Ord , Val1 : Ord , Val2 : Ord , Result : Ord > (
67
- input1 : & Relation < ( Key , Val1 ) > ,
68
- input2 : & Relation < ( Key , Val2 ) > ,
69
- mut logic : impl FnMut ( & Key , & Val1 , & Val2 ) -> Result ,
70
- ) -> Relation < Result > {
80
+ pub ( crate ) fn join_into_relation < P , A , B , O > (
81
+ input1 : & Relation < A > ,
82
+ input2 : & Relation < B > ,
83
+ mut logic : impl FnMut ( P , A :: Suffix , B :: Suffix ) -> O ,
84
+ ) -> Relation < O >
85
+ where
86
+ P : Ord ,
87
+ A : Copy + Split < P > ,
88
+ B : Copy + Split < P > ,
89
+ O : Ord ,
90
+ {
71
91
let mut results = Vec :: new ( ) ;
72
92
73
93
join_helper ( & input1. elements , & input2. elements , |k, v1, v2| {
@@ -98,28 +118,32 @@ pub(crate) fn antijoin<Key: Ord, Val: Ord, Result: Ord>(
98
118
Relation :: from_vec ( results)
99
119
}
100
120
101
- fn join_helper < K : Ord , V1 , V2 > (
102
- mut slice1 : & [ ( K , V1 ) ] ,
103
- mut slice2 : & [ ( K , V2 ) ] ,
104
- mut result : impl FnMut ( & K , & V1 , & V2 ) ,
105
- ) {
121
+ fn join_helper < P , A , B > (
122
+ mut slice1 : & [ A ] ,
123
+ mut slice2 : & [ B ] ,
124
+ mut result : impl FnMut ( P , A :: Suffix , B :: Suffix ) ,
125
+ ) where
126
+ A : Copy + Split < P > ,
127
+ B : Copy + Split < P > ,
128
+ P : Ord ,
129
+ {
106
130
while !slice1. is_empty ( ) && !slice2. is_empty ( ) {
107
131
use std:: cmp:: Ordering ;
108
132
109
133
// If the keys match produce tuples, else advance the smaller key until they might.
110
- match slice1[ 0 ] . 0 . cmp ( & slice2[ 0 ] . 0 ) {
134
+ match slice1[ 0 ] . prefix ( ) . cmp ( & slice2[ 0 ] . prefix ( ) ) {
111
135
Ordering :: Less => {
112
- slice1 = gallop ( slice1, |x| x. 0 < slice2[ 0 ] . 0 ) ;
136
+ slice1 = gallop ( slice1, |x| x. prefix ( ) < slice2[ 0 ] . prefix ( ) ) ;
113
137
}
114
138
Ordering :: Equal => {
115
139
// Determine the number of matching keys in each slice.
116
- let count1 = slice1. iter ( ) . take_while ( |x| x. 0 == slice1[ 0 ] . 0 ) . count ( ) ;
117
- let count2 = slice2. iter ( ) . take_while ( |x| x. 0 == slice2[ 0 ] . 0 ) . count ( ) ;
140
+ let count1 = slice1. iter ( ) . take_while ( |x| x. prefix ( ) == slice1[ 0 ] . prefix ( ) ) . count ( ) ;
141
+ let count2 = slice2. iter ( ) . take_while ( |x| x. prefix ( ) == slice2[ 0 ] . prefix ( ) ) . count ( ) ;
118
142
119
143
// Produce results from the cross-product of matches.
120
144
for index1 in 0 ..count1 {
121
145
for s2 in slice2[ ..count2] . iter ( ) {
122
- result ( & slice1[ 0 ] . 0 , & slice1[ index1] . 1 , & s2. 1 ) ;
146
+ result ( slice1[ 0 ] . prefix ( ) , slice1[ index1] . suffix ( ) , s2. suffix ( ) ) ;
123
147
}
124
148
}
125
149
@@ -128,7 +152,7 @@ fn join_helper<K: Ord, V1, V2>(
128
152
slice2 = & slice2[ count2..] ;
129
153
}
130
154
Ordering :: Greater => {
131
- slice2 = gallop ( slice2, |x| x. 0 < slice1[ 0 ] . 0 ) ;
155
+ slice2 = gallop ( slice2, |x| x. prefix ( ) < slice1[ 0 ] . prefix ( ) ) ;
132
156
}
133
157
}
134
158
}
0 commit comments