@@ -88,7 +88,13 @@ module ScheduledMerges (
88
88
-- * Run sizes
89
89
levelNumberToMaxRunSize ,
90
90
runSizeToLevelNumber ,
91
- maxWriteBufferSize
91
+ maxWriteBufferSize ,
92
+ runSizeFitsInLevel ,
93
+ runSizeTooSmallForLevel ,
94
+ runSizeTooLargeForLevel ,
95
+
96
+ -- * Level capacity
97
+ levelIsFull ,
92
98
) where
93
99
94
100
import Prelude hiding (lookup )
@@ -620,6 +626,97 @@ fromIntegerChecked x
620
626
x' = fromInteger x
621
627
x'' = toInteger x'
622
628
629
+ -- | See 'runSizeFitsInLevel'.
630
+ _runFitsInLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Run -> Bool
631
+ _runFitsInLevel mpl conf ln r = runSizeFitsInLevel mpl conf ln (runSize r)
632
+
633
+ -- | Check wheter a run of the given size fits in the given level.
634
+ --
635
+ -- See 'levelNumberToMaxRunSize' for the bounds on (tiering or levelling) run
636
+ -- sizes at each level.
637
+ --
638
+ -- >>> runSizeFitsInLevel MergePolicyTiering (LSMConfig 2) 3 <$> [8,9,16,32,33]
639
+ -- [False,True,True,True,False]
640
+ --
641
+ -- >>> runSizeFitsInLevel MergePolicyLevelling (LSMConfig 2) 2 <$> [8,9,16,32,33]
642
+ -- [False,True,True,True,False]
643
+ runSizeFitsInLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Int -> Bool
644
+ runSizeFitsInLevel mpl conf ln n
645
+ | ln < 0 = error " level number must be non-negative"
646
+ | ln == 0 = n == 0
647
+ | otherwise =
648
+ levelNumberToMaxRunSize mpl conf (pred ln) < n
649
+ && n <= levelNumberToMaxRunSize mpl conf ln
650
+
651
+ -- | See 'runSizeTooSmallForLevel'.
652
+ runTooSmallForLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Run -> Bool
653
+ runTooSmallForLevel mpl conf ln r = runSizeTooSmallForLevel mpl conf ln (runSize r)
654
+
655
+ -- | Check wheter a run of the given size is too small for the given level.
656
+ --
657
+ -- See 'levelNumberToMaxRunSize' for the bounds on (tiering or levelling) run
658
+ -- sizes at each level.
659
+ --
660
+ -- >>> runSizeTooSmallForLevel MergePolicyTiering (LSMConfig 2) 3 <$> [8,9]
661
+ -- [True,False]
662
+ --
663
+ -- >>> runSizeTooSmallForLevel MergePolicyLevelling (LSMConfig 2) 2 <$> [8,9]
664
+ -- [True,False]
665
+ runSizeTooSmallForLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Int -> Bool
666
+ runSizeTooSmallForLevel mpl conf ln n
667
+ | ln < 0 = error " level number must be non-negative"
668
+ | ln == 0 = False
669
+ | otherwise = case mpl of
670
+ MergePolicyTiering ->
671
+ n <= levelNumberToMaxRunSize MergePolicyTiering conf (pred ln)
672
+ MergePolicyLevelling ->
673
+ n <= levelNumberToMaxRunSize MergePolicyLevelling conf (pred ln)
674
+
675
+ -- | See 'runSizeTooLargeForLevel'.
676
+ runTooLargeForLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Run -> Bool
677
+ runTooLargeForLevel mpl conf ln r = runSizeTooLargeForLevel mpl conf ln (runSize r)
678
+
679
+ -- | Check wheter a run of the given size is too large for the given level.
680
+ --
681
+ -- See 'levelNumberToMaxRunSize' for the bounds on (tiering or levelling) run
682
+ -- sizes at each level.
683
+ --
684
+ -- >>> runSizeTooLargeForLevel MergePolicyTiering (LSMConfig 2) 2 <$> [8,9]
685
+ -- [False,True]
686
+ --
687
+ -- >>> runSizeTooLargeForLevel MergePolicyLevelling (LSMConfig 2) 1 <$> [8,9]
688
+ -- [False,True]
689
+ runSizeTooLargeForLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Int -> Bool
690
+ runSizeTooLargeForLevel mpl conf ln n
691
+ | ln < 0 = error " level number must be non-negative"
692
+ | ln == 0 = not (n == 0 )
693
+ | otherwise = case mpl of
694
+ MergePolicyTiering ->
695
+ n > levelNumberToMaxRunSize MergePolicyTiering conf ln
696
+ MergePolicyLevelling ->
697
+ n > levelNumberToMaxRunSize MergePolicyLevelling conf ln
698
+
699
+ -------------------------------------------------------------------------------
700
+ -- Level capacity
701
+ --
702
+
703
+ levelIsFull :: MergePolicy -> LSMConfig -> LevelNo -> [Run ] -> [Run ] -> Bool
704
+ levelIsFull mpl conf ln incoming resident = case mpl of
705
+ MergePolicyTiering -> levelIsFullTiering conf ln incoming resident
706
+ MergePolicyLevelling ->
707
+ assert (length resident == 1 ) $
708
+ levelIsFullLevelling conf ln incoming (head resident)
709
+
710
+ -- | Only based on run count, not their sizes.
711
+ levelIsFullTiering :: LSMConfig -> LevelNo -> [Run ] -> [Run ] -> Bool
712
+ levelIsFullTiering _conf _ln _incoming resident = length resident >= 4
713
+
714
+ -- | The level is only considered full once the resident run is /too large/
715
+ -- for the level.
716
+ levelIsFullLevelling :: LSMConfig -> LevelNo -> [Run ] -> Run -> Bool
717
+ levelIsFullLevelling conf ln _incoming resident =
718
+ runTooLargeForLevel MergePolicyLevelling conf ln resident
719
+
623
720
-------------------------------------------------------------------------------
624
721
-- Merging credits
625
722
--
@@ -1308,15 +1405,15 @@ increment tr sc conf run0 ls0 ul = do
1308
1405
1309
1406
-- If r is still too small for this level then keep it and merge again
1310
1407
-- with the incoming runs.
1311
- MergePolicyTiering | runToLevelNumber MergePolicyTiering conf r < ln -> do
1408
+ MergePolicyTiering | runTooSmallForLevel MergePolicyTiering conf ln r -> do
1312
1409
ir' <- newLevelMerge tr' conf ln MergePolicyTiering (mergeTypeFor ls) (incoming ++ [r])
1313
1410
return (Level ir' rs : ls)
1314
1411
1315
1412
-- This tiering level is now full. We take the completed merged run
1316
1413
-- (the previous incoming runs), plus all the other runs on this level
1317
1414
-- as a bundle and move them down to the level below. We start a merge
1318
1415
-- for the new incoming runs. This level is otherwise empty.
1319
- MergePolicyTiering | tieringLevelIsFull ln incoming resident -> do
1416
+ MergePolicyTiering | levelIsFullTiering conf ln incoming resident -> do
1320
1417
ir' <- newLevelMerge tr' conf ln MergePolicyTiering MergeMidLevel incoming
1321
1418
ls' <- go (ln+ 1 ) resident ls
1322
1419
return (Level ir' [] : ls')
@@ -1332,7 +1429,7 @@ increment tr sc conf run0 ls0 ul = do
1332
1429
-- run is too large for this level, we promote the run to the next
1333
1430
-- level and start merging the incoming runs into this (otherwise
1334
1431
-- empty) level .
1335
- MergePolicyLevelling | levellingLevelIsFull conf ln incoming r -> do
1432
+ MergePolicyLevelling | levelIsFullLevelling conf ln incoming r -> do
1336
1433
assert (null rs && null ls) $ return ()
1337
1434
ir' <- newLevelMerge tr' conf ln MergePolicyTiering MergeMidLevel incoming
1338
1435
ls' <- go (ln+ 1 ) [r] []
@@ -1387,15 +1484,6 @@ newLevelMerge tr conf level mergePolicy mergeType rs = do
1387
1484
+ levelNumberToMaxRunSize MergePolicyLevelling conf level
1388
1485
MergePolicyTiering -> length rs * levelNumberToMaxRunSize MergePolicyTiering conf (level- 1 )
1389
1486
1390
- -- | Only based on run count, not their sizes.
1391
- tieringLevelIsFull :: Int -> [Run ] -> [Run ] -> Bool
1392
- tieringLevelIsFull _ln _incoming resident = length resident >= 4
1393
-
1394
- -- | The level is only considered full once the resident run is /too large/ for
1395
- -- the level.
1396
- levellingLevelIsFull :: LSMConfig -> Int -> [Run ] -> Run -> Bool
1397
- levellingLevelIsFull conf ln _incoming resident = runToLevelNumber MergePolicyLevelling conf resident > ln
1398
-
1399
1487
-------------------------------------------------------------------------------
1400
1488
-- MergingTree abstraction
1401
1489
--
0 commit comments