@@ -51,13 +51,13 @@ fn join_delta<'me, Key: Ord, Val1: Ord, Val2: Ord>(
5151 let recent1 = input1. recent ( ) ;
5252 let recent2 = input2. recent ( ) ;
5353
54- for batch2 in input2. stable ( ) . iter ( ) {
54+ input2. for_each_stable_set ( |batch2| {
5555 join_helper ( & recent1, & batch2, & mut result) ;
56- }
56+ } ) ;
5757
58- for batch1 in input1. stable ( ) . iter ( ) {
58+ input1. for_each_stable_set ( |batch1| {
5959 join_helper ( & batch1, & recent2, & mut result) ;
60- }
60+ } ) ;
6161
6262 join_helper ( & recent1, & recent2, & mut result) ;
6363}
@@ -164,40 +164,61 @@ pub trait JoinInput<'me, Tuple: Ord>: Copy {
164164 /// empty slice.)
165165 type RecentTuples : Deref < Target = [ Tuple ] > ;
166166
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-
172167 /// Get the set of recent tuples.
173168 fn recent ( self ) -> Self :: RecentTuples ;
174169
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 ] ) ) ;
177172}
178173
179174impl < ' me , Tuple : Ord > JoinInput < ' me , Tuple > for & ' me Variable < Tuple > {
180175 type RecentTuples = Ref < ' me , [ Tuple ] > ;
181- type StableTuples = Ref < ' me , [ Relation < Tuple > ] > ;
182176
183177 fn recent ( self ) -> Self :: RecentTuples {
184178 Ref :: map ( self . recent . borrow ( ) , |r| & r. elements [ ..] )
185179 }
186180
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+ }
189185 }
190186}
191187
192188impl < ' me , Tuple : Ord > JoinInput < ' me , Tuple > for & ' me Relation < Tuple > {
193189 type RecentTuples = & ' me [ Tuple ] ;
194- type StableTuples = & ' me [ Relation < Tuple > ] ;
195190
196191 fn recent ( self ) -> Self :: RecentTuples {
197192 & [ ]
198193 }
199194
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)
202223 }
203224}
0 commit comments