@@ -180,12 +180,12 @@ test_merge_again_with_incoming =
180180-- | Supplying enough credits for the remaining debt completes the union merge
181181-- (as externally observable through 'LSM.remainingUnionDebt'). However, a
182182-- special union level remains.
183- prop_union_complete :: LSMConfig -> [[( LSM. Key , LSM. Entry )]] -> Property
184- prop_union_complete conf kess = length ( filter ( not . null ) kess) > 1 QC. ==>
183+ prop_union_complete :: LSMConfig -> NestedUnionData -> Property
184+ prop_union_complete conf nestedUnionData =
185185 QC. ioProperty $ runWithTracer $ \ tr ->
186186 stToIO $ do
187- ts <- traverse ( uncurry $ mkTable tr conf) ( zip [ LSM. TableId 0 .. ] kess )
188- t <- LSM. unions tr ( LSM. TableId ( length kess)) ts
187+ tidCounter <- newSTRef ( LSM. TableId 0 )
188+ t <- mkNestedUnion tr conf tidCounter nestedUnionData
189189
190190 rep <- dumpRepresentation t
191191 debt@ (UnionDebt x) <- LSM. remainingUnionDebt t
@@ -210,12 +210,62 @@ prop_union_complete conf kess = length (filter (not . null) kess) > 1 QC.==>
210210 MLeaf {} -> True
211211 MNode {} -> False
212212
213- mkTable :: Tracer (ST s ) Event -> LSMConfig -> LSM. TableId -> [(LSM. Key , LSM. Entry )] -> ST s (LSM s )
214- mkTable tr conf tid ks = do
213+
214+ -- | For simplicity, this is not a recursive structure. We just nest once, or
215+ -- not at all if there is just a single 'UnionData'.
216+ newtype NestedUnionData = NestedUnionData [UnionData ]
217+ deriving stock Show
218+ deriving Arbitrary
219+ via (QC. NonEmptyList UnionData )
220+
221+ -- | Note that we want at least two inputs, so there is some merging required.
222+ newtype UnionData = UnionData [TableData ]
223+ deriving stock Show
224+
225+ unionInputInvariant :: UnionData -> Bool
226+ unionInputInvariant (UnionData tableInputs) = length tableInputs >= 2
227+
228+ newtype TableData = TableData [(LSM. Key , LSM. Entry )]
229+ deriving stock Show
230+ deriving Arbitrary
231+ via QC. NonEmptyList (LSM. Key , LSM. Entry )
232+
233+ instance Arbitrary UnionData where
234+ arbitrary = do
235+ len <- QC. oneof [pure 2 , QC. chooseInt (3 , 6 )]
236+ UnionData <$> QC. vectorOf len arbitrary
237+
238+ shrink (UnionData tableInputs) =
239+ filter unionInputInvariant (UnionData <$> shrink tableInputs)
240+
241+ mkNestedUnion :: Tracer (ST s ) Event -> LSMConfig -> STRef s LSM. TableId
242+ -> NestedUnionData -> ST s (LSM s )
243+ mkNestedUnion tr conf tidCounter (NestedUnionData unionInputs) = do
244+ tid <- freshTableId tidCounter
245+ ts <- traverse (mkUnion tr conf tidCounter) unionInputs
246+ LSM. unions tr tid ts
247+
248+ mkUnion :: Tracer (ST s ) Event -> LSMConfig -> STRef s LSM. TableId
249+ -> UnionData -> ST s (LSM s )
250+ mkUnion tr conf tidCounter (UnionData tableInputs) = do
251+ tid <- freshTableId tidCounter
252+ ts <- traverse (mkTable tr conf tidCounter) tableInputs
253+ LSM. unions tr tid ts
254+
255+ mkTable :: Tracer (ST s ) Event -> LSMConfig -> STRef s LSM. TableId
256+ -> TableData -> ST s (LSM s )
257+ mkTable tr conf tidCounter (TableData ks) = do
258+ tid <- freshTableId tidCounter
215259 t <- LSM. newWith tr tid conf
216260 LSM. updates tr t ks
217261 pure t
218262
263+ freshTableId :: STRef s LSM. TableId -> ST s LSM. TableId
264+ freshTableId ref = do
265+ tid <- readSTRef ref
266+ modifySTRef' ref succ
267+ pure tid
268+
219269-------------------------------------------------------------------------------
220270-- tests for MergingTree
221271--
0 commit comments