Skip to content

Commit abc1e07

Browse files
committed
TOSQUASH
1 parent 5daeeee commit abc1e07

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

src/Database/LSMTree/Internal/MergeSchedule.hs

+22-7
Original file line numberDiff line numberDiff line change
@@ -915,18 +915,33 @@ supplyMergeCredits (ScaledCredits c) (MergingRun _ _ var) = do
915915

916916
-- If we previously performed too many merge steps, then we perform
917917
-- fewer now.
918-
let stepsToDo = totalCredits - totalSteps + c
919-
-- Merge.steps guarantees that stepsDone >= stepsToDo
918+
let stepsToDo = max 0 (totalCredits + c - totalSteps)
919+
-- Merge.steps guarantees that stepsDone >= stepsToDo /unless/ the merge
920+
-- was just now finished in fewer than stepsToDo steps, in which case
921+
-- stepsDone <= stepsToDo.
920922
(stepsDone, stepResult) <- Merge.steps m stepsToDo
923+
assert (case stepResult of
924+
MergeInProgress -> stepsDone >= stepsToDo
925+
MergeComplete -> stepsDone <= stepsToDo
926+
) $ pure ()
921927

922928
-- This should be the only point at which we write to these variables.
923-
-- Since we we never perform fewer merge steps than we requested, the
924-
-- invariant is that @readPrimVar totalStepsVar >= readPrimVar
925-
-- totalCreditsVar@. That is also why we update totalStepsVar before
926-
-- totalCreditsVar, in case an asynchronous exception is thrown in
927-
-- between the writes.
929+
--
930+
-- Unless the merge was finished in fewer than stepsToDo steps, we can
931+
-- guarantee that totalSteps' >= totalCredits'
932+
let totalSteps' = totalSteps + stepsDone
933+
let totalCredits' = totalCredits + c
934+
-- If an exception happens between the next two writes, then only
935+
-- totalCreditsVar will be outdated, which is okay because we will
936+
-- resupply credits. It also means we can maintain that @readPrimVar
937+
-- totalStepsVar >= readPrimVar totalCreditsVar@, unless the merge
938+
-- finished in fewer than stepsToDo steps.
928939
writePrimVar totalStepsVar $! totalSteps + stepsDone
929940
writePrimVar totalCreditsVar $! totalCredits + c
941+
assert (case stepResult of
942+
MergeInProgress -> totalSteps' >= totalCredits'
943+
MergeComplete -> totalSteps' <= totalCredits'
944+
) $ pure ()
930945

931946
pure $ stepResult == MergeComplete
932947
when mergeIsDone $

0 commit comments

Comments
 (0)