@@ -192,7 +192,9 @@ invariant = go 1
192192 -- too large and is promoted, in that case initially there's no merge,
193193 -- but it is still represented as a 'MergingRun', using 'SingleRun'.
194194 MergePolicyLevelling -> assertST $ null rs
195- MergePolicyTiering -> assertST $ all (\ r -> tieringRunSizeToLevel r == ln) rs
195+ -- Runs in tiering levels usually fit that size, but they can be one
196+ -- larger, if a run has been held back (creating a 5-way merge).
197+ MergePolicyTiering -> assertST $ all (\ r -> tieringRunSizeToLevel r `elem` [ln, ln+ 1 ]) rs
196198
197199 -- Incoming runs being merged also need to be of the right size, but the
198200 -- conditions are more complicated.
@@ -214,13 +216,14 @@ invariant = go 1
214216 assertST $ levellingRunSizeToLevel r <= ln+ 1
215217
216218 -- An ongoing merge for levelling should have 4 incoming runs of
217- -- the right size for the level below, and 1 run from this level,
219+ -- the right size for the level below (or slightly larger due to
220+ -- holding back underfull runs), and 1 run from this level,
218221 -- but the run from this level can be of almost any size for the
219222 -- same reasons as above. Although if this is the first merge for
220223 -- a new level, it'll have only 4 runs.
221224 (_, OngoingMerge _ rs _) -> do
222225 assertST $ length rs == 4 || length rs == 5
223- assertST $ all (\ r -> tieringRunSizeToLevel r == ln- 1 ) (take 4 rs)
226+ assertST $ all (\ r -> tieringRunSizeToLevel r `elem` [ ln- 1 , ln] ) (take 4 rs)
224227 assertST $ all (\ r -> levellingRunSizeToLevel r <= ln+ 1 ) (drop 4 rs)
225228
226229 MergePolicyTiering ->
@@ -240,9 +243,10 @@ invariant = go 1
240243
241244 -- A completed mid level run is usually of the size for the
242245 -- level it is entering, but can also be one smaller (in which case
243- -- it'll be held back and merged again).
246+ -- it'll be held back and merged again) or one larger (because it
247+ -- includes a run that has been held back before).
244248 (_, CompletedMerge r, MergeMidLevel ) ->
245- assertST $ tieringRunSizeToLevel r `elem` [ln, ln+ 1 ]
249+ assertST $ tieringRunSizeToLevel r `elem` [ln- 1 , ln , ln+ 1 ]
246250
247251 -- An ongoing merge for tiering should have 4 incoming runs of
248252 -- the right size for the level below, and at most 1 run held back
0 commit comments