Skip to content

Commit 0e041d4

Browse files
committed
Make MergingRun.supplyCredits return the leftover credits
This will be needed for supplying credits to merging trees.
1 parent a69f41f commit 0e041d4

File tree

3 files changed

+28
-11
lines changed

3 files changed

+28
-11
lines changed

src/Database/LSMTree/Internal/MergeSchedule.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ addRunToLevels tr conf@TableConfig{..} resolve hfs hbio root uc r0 reg levels =
673673
OneShot -> do
674674
let !required = MR.Credits (unNumEntries (V.foldMap' Run.size rs))
675675
let !thresh = creditThresholdForLevel conf ln
676-
MR.supplyCredits required thresh mr
676+
_leftoverCredits <- MR.supplyCredits required thresh mr
677677
-- This ensures the merge is really completed. However, we don't
678678
-- release the merge yet and only briefly inspect the resulting run.
679679
bracket (MR.expectCompleted mr) releaseRef $ \r ->
@@ -802,7 +802,8 @@ supplyCredits conf c levels =
802802
Merging mp mr -> do
803803
let !c' = scaleCreditsForMerge mp mr c
804804
let !thresh = creditThresholdForLevel conf ln
805-
MR.supplyCredits c' thresh mr
805+
_leftoverCredits <- MR.supplyCredits c' thresh mr
806+
return ()
806807

807808
-- | Scale a number of credits to a number of merge steps to be performed, based
808809
-- on the merging run.

src/Database/LSMTree/Internal/MergingRun.hs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -353,24 +353,27 @@ writeStepsPerformed (StepsPerformedVar v) x = writePrimVar v x
353353
Credits
354354
-> CreditThreshold
355355
-> Ref (MergingRun IO h)
356-
-> IO () #-}
356+
-> IO Credits #-}
357357
-- | Supply the given amount of credits to a merging run. This /may/ cause an
358358
-- ongoing merge to progress.
359359
supplyCredits ::
360360
forall m h. (MonadSTM m, MonadST m, MonadMVar m, MonadMask m)
361361
=> Credits
362362
-> CreditThreshold
363363
-> Ref (MergingRun m h)
364-
-> m ()
364+
-> m Credits
365365
supplyCredits (Credits c) creditsThresh (DeRef MergingRun {..}) = do
366366
mergeCompleted <- readMutVar mergeKnownCompleted
367367

368368
-- The merge is already finished
369369
if mergeCompleted == MergeKnownCompleted then
370-
pure ()
370+
-- we're already done so all supplied credits are leftovers
371+
pure (Credits c)
371372
else do
372373
-- unspentCredits' is our /estimate/ of what the new total of unspent
373-
-- credits is.
374+
-- credits is. It is an estimate due to potential concurrency: other
375+
-- threads may also by supplying credits. We only check the credit
376+
-- balance once, which is the result of addUnspentCredits here:
374377
Credits unspentCredits' <- addUnspentCredits mergeUnspentCreditsVar (Credits c)
375378
stepsPerformed <- readStepsPerformed mergeStepsPerformedVar
376379

@@ -382,6 +385,9 @@ supplyCredits (Credits c) creditsThresh (DeRef MergingRun {..}) = do
382385
(stepMerge mergeSpentCreditsVar mergeStepsPerformedVar
383386
mergeState)
384387
when isMergeDone $ completeMerge mergeState mergeKnownCompleted
388+
let !leftoverCredits = stepsPerformed + unspentCredits'
389+
- unNumEntries mergeNumEntries
390+
return (Credits leftoverCredits)
385391
else if unspentCredits' >= getCreditThreshold creditsThresh then do
386392
-- We can do some merging work without finishing the merge immediately
387393
isMergeDone <-
@@ -405,9 +411,14 @@ supplyCredits (Credits c) creditsThresh (DeRef MergingRun {..}) = do
405411
-- completion, then that is fine. The next supplyCredits will
406412
-- complete the merge.
407413
when isMergeDone $ completeMerge mergeState mergeKnownCompleted
414+
-- We return 0 credits here, even if we completed the merge. This is
415+
-- because if we did complete the merge, it was due to other threads
416+
-- supplying credits, not due to the credits we supplied here.
417+
return (Credits 0)
408418
else
409-
-- Just accumulate credits, because we are not over the threshold yet
410-
pure ()
419+
-- Just accumulate credits, because we are not over the threshold yet.
420+
-- Thus no leftover credits.
421+
pure (Credits 0)
411422

412423
{-# SPECIALISE addUnspentCredits ::
413424
UnspentCreditsVar RealWorld
@@ -512,11 +523,12 @@ stepMerge spentCreditsVar stepsPerformedVar mergeVar (Credits c) =
512523
CompletedMerge{} -> pure False
513524
(OngoingMerge _rs m) -> do
514525
stepsPerformed <- readStepsPerformed stepsPerformedVar
515-
spentCredits <- readSpentCredits spentCreditsVar
526+
spentCredits <- readSpentCredits spentCreditsVar
516527

517528
-- If we previously performed too many merge steps, then we perform
518529
-- fewer now.
519-
let stepsToDo = max 0 (spentCredits + c - stepsPerformed)
530+
let stepsSurplus = stepsPerformed - spentCredits
531+
stepsToDo = max 0 (c - stepsSurplus)
520532
-- Merge.steps guarantees that @stepsDone >= stepsToDo@ /unless/ the
521533
-- merge was just now finished.
522534
(stepsDone, stepResult) <- Merge.steps m stepsToDo

src/Database/LSMTree/Internal/Snapshot.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,11 @@ fromSnapLevels reg hfs hbio conf@TableConfig{..} uc resolve dir (SnapLevels leve
465465
-- snapshot was taken.
466466
let c = getUnspentCredits unspentCredits
467467
+ getSpentCredits spentCredits
468-
MR.supplyCredits (MR.Credits c) (creditThresholdForLevel conf ln) mr
468+
_c' <- MR.supplyCredits (MR.Credits c)
469+
(creditThresholdForLevel conf ln) mr
470+
-- We would typically expect the leftover credits c' to be 0,
471+
-- but it's hard to reason that this is guaranteed, so we do
472+
-- not assert it here.
469473
return mr
470474

471475
dupRun r = withRollback reg (dupRef r) releaseRef

0 commit comments

Comments
 (0)