@@ -196,10 +196,8 @@ invariant = go 1
196
196
-- too large and is promoted, in that case initially there's no merge,
197
197
-- but it is still represented as a 'MergingRun', using 'SingleRun'.
198
198
MergePolicyLevelling -> assertST $ null rs
199
- -- Runs in tiering levels usually fit that size, but they can be one
200
- -- smaller due to compaction (if they have not been held back and
201
- -- merged again).
202
- MergePolicyTiering -> assertST $ all (\ r -> tieringRunSizeToLevel r `elem` [ln- 1 , ln]) rs
199
+ -- Runs in tiering levels fit that size.
200
+ MergePolicyTiering -> assertST $ all (\ r -> tieringRunSizeToLevel r == ln) rs
203
201
204
202
-- Incoming runs being merged also need to be of the right size, but the
205
203
-- conditions are more complicated.
@@ -234,7 +232,7 @@ invariant = go 1
234
232
let resident = drop 4 rs
235
233
assertST $ length incoming == 4
236
234
assertST $ length resident <= 1
237
- assertST $ all (\ r -> tieringRunSizeToLevel r `elem` [ ln- 2 , ln - 1 ] ) incoming
235
+ assertST $ all (\ r -> tieringRunSizeToLevel r == ln- 1 ) incoming
238
236
assertST $ all (\ r -> levellingRunSizeToLevel r <= ln+ 1 ) resident
239
237
240
238
MergePolicyTiering ->
@@ -261,12 +259,12 @@ invariant = go 1
261
259
assertST $ tieringRunSizeToLevel r `elem` [ln- 1 , ln]
262
260
263
261
-- An ongoing merge for tiering should have 4 incoming runs of
264
- -- the right size for the level below (or slightly smaller) , and at
265
- -- most 1 run held back due to being too small (which would thus
266
- -- also be of the size of the level below).
262
+ -- the right size for the level below, and at most 1 run held back
263
+ -- due to being too small (which would thus also be of the size of
264
+ -- the level below).
267
265
(_, OngoingMerge _ rs _, _) -> do
268
266
assertST $ length rs == 4 || length rs == 5
269
- assertST $ all (\ r -> tieringRunSizeToLevel r `elem` [ ln- 2 , ln - 1 ] ) rs
267
+ assertST $ all (\ r -> tieringRunSizeToLevel r == ln- 1 ) rs
270
268
271
269
-- 'callStack' just ensures that the 'HasCallStack' constraint is not redundant
272
270
-- when compiling with debug assertions disabled.
@@ -486,8 +484,11 @@ creditsForMerge SingleRun{} = 0
486
484
creditsForMerge (MergingRun MergePolicyLevelling _ _) = (1 + 4 ) / 1
487
485
488
486
-- A tiering merge has 4 runs at most (once could be held back to merged again)
489
- -- and must be completed before the level is full (once 4 more runs come in).
490
- creditsForMerge (MergingRun MergePolicyTiering _ _) = 4 / 4
487
+ -- and must be completed before the level is full (once 3 more runs come in,
488
+ -- as it could have started out with an additional refused run).
489
+ -- TODO: We could only increase the merging speed for the merges where this
490
+ -- applies, which should be rare.
491
+ creditsForMerge (MergingRun MergePolicyTiering _ _) = 4 / 3
491
492
492
493
type Event = EventAt EventDetail
493
494
data EventAt e = EventAt {
@@ -531,9 +532,8 @@ increment tr sc = \r ls -> do
531
532
assertST $ tieringRunSizeToLevel r `elem` [ln, ln+ 1 ] -- +1 from levelling
532
533
_ -> do
533
534
assertST $ length incoming == 4
534
- -- because of underfull runs
535
- assertST $ all (\ r -> tieringRunSizeToLevel r `elem` [ln- 2 , ln- 1 ]) incoming
536
- assertST $ tieringLevel (sum (map Map. size incoming)) `elem` [ln- 1 , ln]
535
+ assertST $ all (\ r -> tieringRunSizeToLevel r == ln- 1 ) incoming
536
+ assertST $ tieringLevel (sum (map Map. size incoming)) == ln
537
537
(ls', refused) <- go' ln incoming ls
538
538
for_ refused $ assertST . (== head incoming)
539
539
return (ls', refused)
@@ -554,12 +554,19 @@ increment tr sc = \r ls -> do
554
554
-- If r is still too small for this level then keep it and merge again
555
555
-- with the incoming runs, but only if the resulting run is guaranteed
556
556
-- not to be too large for this level.
557
- MergePolicyTiering
558
- | tieringRunSizeToLevel r < ln
559
- , sum (map Map. size (r : incoming)) <= tieringRunSize ln -> do
560
- let mergelast = mergeLastForLevel ls
561
- mr' <- newMerge tr' ln MergePolicyTiering mergelast (incoming ++ [r])
562
- return (Level mr' rs : ls, Nothing )
557
+ -- If it might become too large, only create a 4-way merge and refuse
558
+ -- the most recent of the incoming runs.
559
+ MergePolicyTiering | tieringRunSizeToLevel r < ln ->
560
+ if sum (map Map. size (r : incoming)) <= tieringRunSize ln
561
+ then do
562
+ let mergelast = mergeLastForLevel ls
563
+ mr' <- newMerge tr' ln MergePolicyTiering mergelast (incoming ++ [r])
564
+ return (Level mr' rs : ls, Nothing )
565
+ else do
566
+ -- TODO: comment
567
+ let mergelast = mergeLastForLevel ls
568
+ mr' <- newMerge tr' ln MergePolicyTiering mergelast (tail incoming ++ [r])
569
+ return (Level mr' rs : ls, Just (head incoming))
563
570
564
571
-- This tiering level is now full. We take the completed merged run
565
572
-- (the previous incoming runs), plus all the other runs on this level
0 commit comments