@@ -25,13 +25,13 @@ pub(crate) fn join_into<'me, Key: Ord, Val1: Ord, Val2: Ord, Result: Ord>(
25
25
26
26
let mut closure = |k : & Key , v1 : & Val1 , v2 : & Val2 | results. push ( logic ( k, v1, v2) ) ;
27
27
28
- for batch2 in input2. stable ( ) . iter ( ) {
28
+ input2. for_each_stable_set ( |batch2| {
29
29
join_helper ( & recent1, & batch2, & mut closure) ;
30
- }
30
+ } ) ;
31
31
32
- for batch1 in input1. stable ( ) . iter ( ) {
32
+ input1. for_each_stable_set ( |batch1| {
33
33
join_helper ( & batch1, & recent2, & mut closure) ;
34
- }
34
+ } ) ;
35
35
36
36
join_helper ( & recent1, & recent2, & mut closure) ;
37
37
}
@@ -141,40 +141,56 @@ pub trait JoinInput<'me, Tuple: Ord>: Copy {
141
141
/// empty slice.)
142
142
type RecentTuples : Deref < Target = [ Tuple ] > ;
143
143
144
- /// If we are on iteration N of the loop, these are the tuples
145
- /// added on iteration N - 2 or before. (For a `Relation`, this is
146
- /// just `self`.)
147
- type StableTuples : Deref < Target = [ Relation < Tuple > ] > ;
148
-
149
144
/// Get the set of recent tuples.
150
145
fn recent ( self ) -> Self :: RecentTuples ;
151
146
152
- /// Get the set of stable tuples.
153
- fn stable ( self ) -> Self :: StableTuples ;
147
+ /// Call a function for each set of stable tuples.
148
+ fn for_each_stable_set ( self , f : impl FnMut ( & [ Tuple ] ) ) ;
154
149
}
155
150
156
151
impl < ' me , Tuple : Ord > JoinInput < ' me , Tuple > for & ' me Variable < Tuple > {
157
152
type RecentTuples = Ref < ' me , [ Tuple ] > ;
158
- type StableTuples = Ref < ' me , [ Relation < Tuple > ] > ;
159
153
160
154
fn recent ( self ) -> Self :: RecentTuples {
161
155
Ref :: map ( self . recent . borrow ( ) , |r| & r. elements [ ..] )
162
156
}
163
157
164
- fn stable ( self ) -> Self :: StableTuples {
165
- Ref :: map ( self . stable . borrow ( ) , |v| & v[ ..] )
158
+ fn for_each_stable_set ( self , mut f : impl FnMut ( & [ Tuple ] ) ) {
159
+ for stable in self . stable . borrow ( ) . iter ( ) {
160
+ f ( stable)
161
+ }
166
162
}
167
163
}
168
164
169
165
impl < ' me , Tuple : Ord > JoinInput < ' me , Tuple > for & ' me Relation < Tuple > {
170
166
type RecentTuples = & ' me [ Tuple ] ;
171
- type StableTuples = & ' me [ Relation < Tuple > ] ;
172
167
173
168
fn recent ( self ) -> Self :: RecentTuples {
174
169
& [ ]
175
170
}
176
171
177
- fn stable ( self ) -> Self :: StableTuples {
178
- std:: slice:: from_ref ( self )
172
+ fn for_each_stable_set ( self , mut f : impl FnMut ( & [ Tuple ] ) ) {
173
+ f ( & self . elements )
174
+ }
175
+ }
176
+
177
+ impl < ' me , Tuple : Ord > JoinInput < ' me , ( Tuple , ( ) ) > for & ' me Relation < Tuple > {
178
+ type RecentTuples = & ' me [ ( Tuple , ( ) ) ] ;
179
+
180
+ fn recent ( self ) -> Self :: RecentTuples {
181
+ & [ ]
182
+ }
183
+
184
+ fn for_each_stable_set ( self , mut f : impl FnMut ( & [ ( Tuple , ( ) ) ] ) ) {
185
+ use std:: mem;
186
+ assert_eq ! ( mem:: size_of:: <( Tuple , ( ) ) >( ) , mem:: size_of:: <Tuple >( ) ) ;
187
+ assert_eq ! ( mem:: align_of:: <( Tuple , ( ) ) >( ) , mem:: align_of:: <Tuple >( ) ) ;
188
+
189
+ // SAFETY: https://rust-lang.github.io/unsafe-code-guidelines/layout/structs-and-tuples.html#structs-with-1-zst-fields
190
+ // guarantees that `T` is layout compatible with `(T, ())`, since `()` is a 1-ZST.
191
+ let elements: & ' me [ Tuple ] = self . elements . as_slice ( ) ;
192
+ let elements: & ' me [ ( Tuple , ( ) ) ] = unsafe { std:: mem:: transmute ( elements) } ;
193
+
194
+ f ( elements)
179
195
}
180
196
}
0 commit comments