@@ -25,13 +25,13 @@ pub(crate) fn join_into<'me, Key: Ord, Val1: Ord, Val2: Ord, Result: Ord>(
2525
2626 let mut closure = |k : & Key , v1 : & Val1 , v2 : & Val2 | results. push ( logic ( k, v1, v2) ) ;
2727
28- for batch2 in input2. stable ( ) . iter ( ) {
28+ input2. for_each_stable_set ( |batch2| {
2929 join_helper ( & recent1, & batch2, & mut closure) ;
30- }
30+ } ) ;
3131
32- for batch1 in input1. stable ( ) . iter ( ) {
32+ input1. for_each_stable_set ( |batch1| {
3333 join_helper ( & batch1, & recent2, & mut closure) ;
34- }
34+ } ) ;
3535
3636 join_helper ( & recent1, & recent2, & mut closure) ;
3737 }
@@ -141,40 +141,56 @@ pub trait JoinInput<'me, Tuple: Ord>: Copy {
141141 /// empty slice.)
142142 type RecentTuples : Deref < Target = [ Tuple ] > ;
143143
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-
149144 /// Get the set of recent tuples.
150145 fn recent ( self ) -> Self :: RecentTuples ;
151146
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 ] ) ) ;
154149}
155150
156151impl < ' me , Tuple : Ord > JoinInput < ' me , Tuple > for & ' me Variable < Tuple > {
157152 type RecentTuples = Ref < ' me , [ Tuple ] > ;
158- type StableTuples = Ref < ' me , [ Relation < Tuple > ] > ;
159153
160154 fn recent ( self ) -> Self :: RecentTuples {
161155 Ref :: map ( self . recent . borrow ( ) , |r| & r. elements [ ..] )
162156 }
163157
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+ }
166162 }
167163}
168164
169165impl < ' me , Tuple : Ord > JoinInput < ' me , Tuple > for & ' me Relation < Tuple > {
170166 type RecentTuples = & ' me [ Tuple ] ;
171- type StableTuples = & ' me [ Relation < Tuple > ] ;
172167
173168 fn recent ( self ) -> Self :: RecentTuples {
174169 & [ ]
175170 }
176171
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)
179195 }
180196}
0 commit comments