@@ -51,13 +51,13 @@ fn join_delta<'me, Key: Ord, Val1: Ord, Val2: Ord>(
51
51
let recent1 = input1. recent ( ) ;
52
52
let recent2 = input2. recent ( ) ;
53
53
54
- for batch2 in input2. stable ( ) . iter ( ) {
54
+ input2. for_each_stable_set ( |batch2| {
55
55
join_helper ( & recent1, & batch2, & mut result) ;
56
- }
56
+ } ) ;
57
57
58
- for batch1 in input1. stable ( ) . iter ( ) {
58
+ input1. for_each_stable_set ( |batch1| {
59
59
join_helper ( & batch1, & recent2, & mut result) ;
60
- }
60
+ } ) ;
61
61
62
62
join_helper ( & recent1, & recent2, & mut result) ;
63
63
}
@@ -164,40 +164,61 @@ pub trait JoinInput<'me, Tuple: Ord>: Copy {
164
164
/// empty slice.)
165
165
type RecentTuples : Deref < Target = [ Tuple ] > ;
166
166
167
- /// If we are on iteration N of the loop, these are the tuples
168
- /// added on iteration N - 2 or before. (For a `Relation`, this is
169
- /// just `self`.)
170
- type StableTuples : Deref < Target = [ Relation < Tuple > ] > ;
171
-
172
167
/// Get the set of recent tuples.
173
168
fn recent ( self ) -> Self :: RecentTuples ;
174
169
175
- /// Get the set of stable tuples.
176
- fn stable ( self ) -> Self :: StableTuples ;
170
+ /// Call a function for each set of stable tuples.
171
+ fn for_each_stable_set ( self , f : impl FnMut ( & [ Tuple ] ) ) ;
177
172
}
178
173
179
174
impl < ' me , Tuple : Ord > JoinInput < ' me , Tuple > for & ' me Variable < Tuple > {
180
175
type RecentTuples = Ref < ' me , [ Tuple ] > ;
181
- type StableTuples = Ref < ' me , [ Relation < Tuple > ] > ;
182
176
183
177
fn recent ( self ) -> Self :: RecentTuples {
184
178
Ref :: map ( self . recent . borrow ( ) , |r| & r. elements [ ..] )
185
179
}
186
180
187
- fn stable ( self ) -> Self :: StableTuples {
188
- Ref :: map ( self . stable . borrow ( ) , |v| & v[ ..] )
181
+ fn for_each_stable_set ( self , mut f : impl FnMut ( & [ Tuple ] ) ) {
182
+ for stable in self . stable . borrow ( ) . iter ( ) {
183
+ f ( stable)
184
+ }
189
185
}
190
186
}
191
187
192
188
impl < ' me , Tuple : Ord > JoinInput < ' me , Tuple > for & ' me Relation < Tuple > {
193
189
type RecentTuples = & ' me [ Tuple ] ;
194
- type StableTuples = & ' me [ Relation < Tuple > ] ;
195
190
196
191
fn recent ( self ) -> Self :: RecentTuples {
197
192
& [ ]
198
193
}
199
194
200
- fn stable ( self ) -> Self :: StableTuples {
201
- std:: slice:: from_ref ( self )
195
+ fn for_each_stable_set ( self , mut f : impl FnMut ( & [ Tuple ] ) ) {
196
+ f ( & self . elements )
197
+ }
198
+ }
199
+
200
+ impl < ' me , Tuple : Ord > JoinInput < ' me , ( Tuple , ( ) ) > for & ' me Relation < Tuple > {
201
+ type RecentTuples = & ' me [ ( Tuple , ( ) ) ] ;
202
+
203
+ fn recent ( self ) -> Self :: RecentTuples {
204
+ & [ ]
205
+ }
206
+
207
+ fn for_each_stable_set ( self , mut f : impl FnMut ( & [ ( Tuple , ( ) ) ] ) ) {
208
+ use std:: mem;
209
+ assert_eq ! ( mem:: size_of:: <( Tuple , ( ) ) >( ) , mem:: size_of:: <Tuple >( ) ) ;
210
+ assert_eq ! ( mem:: align_of:: <( Tuple , ( ) ) >( ) , mem:: align_of:: <Tuple >( ) ) ;
211
+
212
+ // SAFETY: https://rust-lang.github.io/unsafe-code-guidelines/layout/structs-and-tuples.html#structs-with-1-zst-fields
213
+ // guarantees that `T` is layout compatible with `(T, ())`, since `()` is a 1-ZST. We use
214
+ // `slice::from_raw_parts` because the layout compatibility guarantee does not extend to
215
+ // containers like `&[T]`.
216
+ let elements: & ' me [ Tuple ] = self . elements . as_slice ( ) ;
217
+ let len = elements. len ( ) ;
218
+
219
+ let elements: & ' me [ ( Tuple , ( ) ) ] =
220
+ unsafe { std:: slice:: from_raw_parts ( elements. as_ptr ( ) as * const _ , len) } ;
221
+
222
+ f ( elements)
202
223
}
203
224
}
0 commit comments