Skip to content

Commit 5e4c6a6

Browse files
committed
unify style of invariant
This way we always know the exact assertion that failed.
1 parent 8f6c02e commit 5e4c6a6

File tree

1 file changed

+37
-36
lines changed

1 file changed

+37
-36
lines changed

prototypes/ScheduledMerges.hs

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import Data.STRef
4949
import Control.Exception (assert)
5050
import Control.Monad.ST
5151
import Control.Tracer (Tracer, contramap, traceWith)
52-
import GHC.Stack (HasCallStack)
52+
import GHC.Stack (HasCallStack, callStack)
5353

5454
import Database.LSMTree.Normal (LookupResult (..), Update (..))
5555

@@ -159,101 +159,103 @@ mergeLastForLevel _ = MergeMidLevel
159159
-- | Note that the invariants rely on the fact that levelling is only used on
160160
-- the last level.
161161
--
162-
invariant :: forall s. Levels s -> ST s Bool
162+
invariant :: forall s. Levels s -> ST s ()
163163
invariant = go 1
164164
where
165-
go :: Int -> [Level s] -> ST s Bool
166-
go !_ [] = return True
165+
go :: Int -> [Level s] -> ST s ()
166+
go !_ [] = return ()
167167

168168
go !ln (Level mr rs : ls) = do
169169

170170
mrs <- case mr of
171171
SingleRun r -> return (CompletedMerge r)
172172
MergingRun _ _ ref -> readSTRef ref
173173

174-
assert (case mr of
175-
SingleRun{} -> True
176-
MergingRun mp ml _ -> mergePolicyForLevel ln ls == mp
177-
&& mergeLastForLevel ls == ml)
178-
assert (length rs <= 3) $
179-
assert (expectedRunLengths ln rs ls) $
180-
assert (expectedMergingRunLengths ln mr mrs ls) $
181-
return ()
174+
assertST $ case mr of
175+
SingleRun{} -> True
176+
MergingRun mp ml _ -> mergePolicyForLevel ln ls == mp
177+
&& mergeLastForLevel ls == ml
178+
assertST $ length rs <= 3
179+
expectedRunLengths ln rs ls
180+
expectedMergingRunLengths ln mr mrs ls
182181

183182
go (ln+1) ls
184183

185184
-- All runs within a level "proper" (as opposed to the incoming runs
186185
-- being merged) should be of the correct size for the level.
187-
expectedRunLengths :: Int -> [Run] -> [Level s] -> Bool
186+
expectedRunLengths :: Int -> [Run] -> [Level s] -> ST s ()
188187
expectedRunLengths ln rs ls =
189188
case mergePolicyForLevel ln ls of
190189
-- Levels using levelling have only one run, and that single run is
191190
-- (almost) always involved in an ongoing merge. Thus there are no
192191
-- other "normal" runs. The exception is when a levelling run becomes
193192
-- too large and is promoted, in that case initially there's no merge,
194193
-- but it is still represented as a 'MergingRun', using 'SingleRun'.
195-
MergePolicyLevelling -> null rs
196-
MergePolicyTiering -> all (\r -> tieringRunSizeToLevel r == ln) rs
194+
MergePolicyLevelling -> assertST $ null rs
195+
MergePolicyTiering -> assertST $ all (\r -> tieringRunSizeToLevel r == ln) rs
197196

198197
-- Incoming runs being merged also need to be of the right size, but the
199198
-- conditions are more complicated.
200199
expectedMergingRunLengths :: Int -> MergingRun s -> MergingRunState
201-
-> [Level s] -> Bool
200+
-> [Level s] -> ST s ()
202201
expectedMergingRunLengths ln mr mrs ls =
203202
case mergePolicyForLevel ln ls of
204203
MergePolicyLevelling ->
205204
case (mr, mrs) of
206205
-- A single incoming run (which thus didn't need merging) must be
207206
-- of the expected size range already
208207
(SingleRun r, CompletedMerge{}) ->
209-
assert (levellingRunSizeToLevel r == ln) True
208+
assertST $ levellingRunSizeToLevel r == ln
210209

211210
-- A completed merge for levelling can be of almost any size at all!
212211
-- It can be smaller, due to deletions in the last level. But it
213212
-- can't be bigger than would fit into the next level.
214213
(_, CompletedMerge r) ->
215-
assert (levellingRunSizeToLevel r <= ln+1) True
214+
assertST $ levellingRunSizeToLevel r <= ln+1
216215

217216
-- An ongoing merge for levelling should have 4 incoming runs of
218217
-- the right size for the level below, and 1 run from this level,
219218
-- but the run from this level can be of almost any size for the
220219
-- same reasons as above. Although if this is the first merge for
221220
-- a new level, it'll have only 4 runs.
222-
(_, OngoingMerge _ rs _) ->
223-
assert (length rs == 4 || length rs == 5) True
224-
&& assert (all (\r -> tieringRunSizeToLevel r == ln-1) (take 4 rs)) True
225-
&& assert (all (\r -> levellingRunSizeToLevel r <= ln+1) (drop 4 rs)) True
221+
(_, OngoingMerge _ rs _) -> do
222+
assertST $ length rs == 4 || length rs == 5
223+
assertST $ all (\r -> tieringRunSizeToLevel r == ln-1) (take 4 rs)
224+
assertST $ all (\r -> levellingRunSizeToLevel r <= ln+1) (drop 4 rs)
226225

227226
MergePolicyTiering ->
228227
case (mr, mrs, mergeLastForLevel ls) of
229228
-- A single incoming run (which thus didn't need merging) must be
230229
-- of the expected size already
231230
(SingleRun r, CompletedMerge{}, _) ->
232-
tieringRunSizeToLevel r == ln
231+
assertST $ tieringRunSizeToLevel r == ln
233232

234233
-- A completed last level run can be of almost any smaller size due
235234
-- to deletions, but it can't be bigger than the next level down.
236235
-- Note that tiering on the last level only occurs when there is
237236
-- a single level only.
238-
(_, CompletedMerge r, MergeLastLevel) ->
239-
ln == 1
240-
&& tieringRunSizeToLevel r <= ln+1
237+
(_, CompletedMerge r, MergeLastLevel) -> do
238+
assertST $ ln == 1
239+
assertST $ tieringRunSizeToLevel r <= ln+1
241240

242241
-- A completed mid level run is usually of the size for the
243242
-- level it is entering, but can also be one smaller (in which case
244243
-- it'll be held back and merged again).
245244
(_, CompletedMerge r, MergeMidLevel) ->
246-
rln == ln || rln == ln+1
247-
where
248-
rln = tieringRunSizeToLevel r
245+
assertST $ tieringRunSizeToLevel r `elem` [ln, ln+1]
249246

250247
-- An ongoing merge for tiering should have 4 incoming runs of
251248
-- the right size for the level below, and at most 1 run held back
252249
-- due to being too small (which would thus also be of the size of
253250
-- the level below).
254-
(_, OngoingMerge _ rs _, _) ->
255-
(length rs == 4 || length rs == 5)
256-
&& all (\r -> tieringRunSizeToLevel r == ln-1) rs
251+
(_, OngoingMerge _ rs _, _) -> do
252+
assertST $ length rs == 4 || length rs == 5
253+
assertST $ all (\r -> tieringRunSizeToLevel r == ln-1) rs
254+
255+
-- 'callStack' just ensures that the 'HasCallStack' constraint is not redundant
256+
-- when compiling with debug assertions disabled.
257+
assertST :: HasCallStack => Bool -> ST s ()
258+
assertST p = assert p $ return (const () callStack)
257259

258260

259261
-------------------------------------------------------------------------------
@@ -423,8 +425,7 @@ supply (LSMHandle scr lsmr) credits = do
423425
LSMContent _ ls <- readSTRef lsmr
424426
modifySTRef' scr (+1)
425427
supplyCredits credits ls
426-
ok <- invariant ls
427-
assert ok $ return ()
428+
invariant ls
428429

429430
lookups :: LSM s -> [Key] -> ST s [(Key, LookupResult Value Blob)]
430431
lookups lsm = mapM (\k -> (k,) <$> lookup lsm k)
@@ -494,8 +495,8 @@ increment :: forall s. Tracer (ST s) Event
494495
-> Counter -> Run -> Levels s -> ST s (Levels s)
495496
increment tr sc = \r ls -> do
496497
ls' <- go 1 [r] ls
497-
ok <- invariant ls'
498-
assert ok (return ls')
498+
invariant ls'
499+
return ls'
499500
where
500501
go :: Int -> [Run] -> Levels s -> ST s (Levels s)
501502
go !ln incoming [] = do

0 commit comments

Comments
 (0)