Skip to content

Commit a69f41f

Browse files
committed
Rename the step and credit related type and var names.
TotalStepsVar becomes StepsPerformedVar for better consistency with the commentary. Add the suffix Var onto all the var names to better distinguish the mutable variable from the current value, and to better match the type names (which already use a Var suffix). And add some read/write wrappers for the vars, using them both internally and in the snapshot module, to slightly increase the level of representation abstraction.
1 parent 75cb65a commit a69f41f

File tree

3 files changed

+72
-55
lines changed

3 files changed

+72
-55
lines changed

src-extras/Database/LSMTree/Extras/NoThunks.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,8 @@ deriving anyclass instance NoThunks NumRuns
324324
deriving stock instance Generic (UnspentCreditsVar s)
325325
deriving anyclass instance Typeable s => NoThunks (UnspentCreditsVar s)
326326

327-
deriving stock instance Generic (TotalStepsVar s)
328-
deriving anyclass instance Typeable s => NoThunks (TotalStepsVar s)
327+
deriving stock instance Generic (StepsPerformedVar s)
328+
deriving anyclass instance Typeable s => NoThunks (StepsPerformedVar s)
329329

330330
deriving stock instance Generic (SpentCreditsVar s)
331331
deriving anyclass instance Typeable s => NoThunks (SpentCreditsVar s)

src/Database/LSMTree/Internal/MergingRun.hs

Lines changed: 68 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ module Database.LSMTree.Internal.MergingRun (
1919
, CreditThreshold (..)
2020
, UnspentCreditsVar (..)
2121
, SpentCreditsVar (..)
22-
, TotalStepsVar (..)
22+
, StepsPerformedVar (..)
23+
, readUnspentCredits
24+
, readSpentCredits
2325

2426
-- * Internal state
2527
, MergingRunState (..)
@@ -54,28 +56,28 @@ import System.FS.API (HasFS)
5456
import System.FS.BlockIO.API (HasBlockIO)
5557

5658
data MergingRun m h = MergingRun {
57-
mergeNumRuns :: !NumRuns
59+
mergeNumRuns :: !NumRuns
5860
-- | Sum of number of entries in the input runs
59-
, mergeNumEntries :: !NumEntries
61+
, mergeNumEntries :: !NumEntries
6062

6163
-- See $credittracking
6264

6365
-- | The current number of credits supplied but as yet /unspent/.
64-
, mergeUnspentCredits :: !(UnspentCreditsVar (PrimState m))
66+
, mergeUnspentCreditsVar :: !(UnspentCreditsVar (PrimState m))
6567
-- | The current number of credits supplied but already spent. Note that
6668
-- the total number of credits supplied is this plus the unspent credits.
67-
, mergeSpentCredits :: !(SpentCreditsVar (PrimState m))
69+
, mergeSpentCreditsVar :: !(SpentCreditsVar (PrimState m))
6870
-- | The current number of merging steps actually performed. This is
6971
-- always at least as big as the total number of credits supplied.
70-
, mergeStepsPerformed :: !(TotalStepsVar (PrimState m))
72+
, mergeStepsPerformedVar :: !(StepsPerformedVar (PrimState m))
7173

7274
-- | A variable that caches knowledge about whether the merge has been
7375
-- completed. If 'MergeKnownCompleted', then we are sure the merge has
7476
-- been completed, otherwise if 'MergeMaybeCompleted' we have to check the
7577
-- 'MergingRunState'.
76-
, mergeKnownCompleted :: !(MutVar (PrimState m) MergeKnownCompleted)
77-
, mergeState :: !(StrictMVar m (MergingRunState m h))
78-
, mergeRefCounter :: !(RefCounter m)
78+
, mergeKnownCompleted :: !(MutVar (PrimState m) MergeKnownCompleted)
79+
, mergeState :: !(StrictMVar m (MergingRunState m h))
80+
, mergeRefCounter :: !(RefCounter m)
7981
}
8082

8183
instance RefCounted m (MergingRun m h) where
@@ -172,9 +174,9 @@ unsafeNew ::
172174
-> MergingRunState m h
173175
-> m (Ref (MergingRun m h))
174176
unsafeNew mergeNumRuns mergeNumEntries knownCompleted state = do
175-
mergeUnspentCredits <- UnspentCreditsVar <$> newPrimVar 0
176-
mergeSpentCredits <- SpentCreditsVar <$> newPrimVar 0
177-
mergeStepsPerformed <- TotalStepsVar <$> newPrimVar 0
177+
mergeUnspentCreditsVar <- UnspentCreditsVar <$> newPrimVar 0
178+
mergeSpentCreditsVar <- SpentCreditsVar <$> newPrimVar 0
179+
mergeStepsPerformedVar <- StepsPerformedVar <$> newPrimVar 0
178180
case state of
179181
OngoingMerge{} -> assert (knownCompleted == MergeMaybeCompleted) (pure ())
180182
CompletedMerge{} -> pure ()
@@ -184,9 +186,9 @@ unsafeNew mergeNumRuns mergeNumEntries knownCompleted state = do
184186
MergingRun {
185187
mergeNumRuns
186188
, mergeNumEntries
187-
, mergeUnspentCredits
188-
, mergeSpentCredits
189-
, mergeStepsPerformed
189+
, mergeUnspentCreditsVar
190+
, mergeSpentCreditsVar
191+
, mergeStepsPerformedVar
190192
, mergeKnownCompleted
191193
, mergeState
192194
, mergeRefCounter
@@ -245,7 +247,7 @@ duplicateRuns (DeRef mr) =
245247
246248
* credits unspent ('UnspentCreditsVar')
247249
* credits spent ('SpentCreditsVar')
248-
* steps performed ('TotalStepsVar')
250+
* steps performed ('StepsPerformedVar')
249251
250252
The credits supplied is the sum of the credits spent and unspent. The credits
251253
supplied and the steps performed will be close but not exactly the same in
@@ -326,9 +328,26 @@ newtype Credits = Credits Int
326328
-- achieving good (concurrent) performance.
327329
newtype CreditThreshold = CreditThreshold { getCreditThreshold :: Int }
328330

329-
newtype UnspentCreditsVar s = UnspentCreditsVar { getUnspentCreditsVar :: PrimVar s Int }
330-
newtype SpentCreditsVar s = SpentCreditsVar { getSpentCreditsVar :: PrimVar s Int }
331-
newtype TotalStepsVar s = TotalStepsVar { getTotalStepsVar :: PrimVar s Int }
331+
newtype UnspentCreditsVar s = UnspentCreditsVar (PrimVar s Int)
332+
newtype SpentCreditsVar s = SpentCreditsVar (PrimVar s Int)
333+
newtype StepsPerformedVar s = StepsPerformedVar (PrimVar s Int)
334+
335+
{-# INLINE readUnspentCredits #-}
336+
{-# INLINE readSpentCredits #-}
337+
{-# INLINE readStepsPerformed #-}
338+
readUnspentCredits :: PrimMonad m => UnspentCreditsVar (PrimState m) -> m Int
339+
readSpentCredits :: PrimMonad m => SpentCreditsVar (PrimState m) -> m Int
340+
readStepsPerformed :: PrimMonad m => StepsPerformedVar (PrimState m) -> m Int
341+
readUnspentCredits (UnspentCreditsVar v) = readPrimVar v
342+
readSpentCredits (SpentCreditsVar v) = readPrimVar v
343+
readStepsPerformed (StepsPerformedVar v) = readPrimVar v
344+
345+
{-# INLINE writeSpentCredits #-}
346+
{-# INLINE writeStepsPerformed #-}
347+
writeSpentCredits :: PrimMonad m => SpentCreditsVar (PrimState m) -> Int -> m ()
348+
writeStepsPerformed :: PrimMonad m => StepsPerformedVar (PrimState m) -> Int -> m ()
349+
writeSpentCredits (SpentCreditsVar v) x = writePrimVar v x
350+
writeStepsPerformed (StepsPerformedVar v) x = writePrimVar v x
332351

333352
{-# SPECIALISE supplyCredits ::
334353
Credits
@@ -352,15 +371,15 @@ supplyCredits (Credits c) creditsThresh (DeRef MergingRun {..}) = do
352371
else do
353372
-- unspentCredits' is our /estimate/ of what the new total of unspent
354373
-- credits is.
355-
Credits unspentCredits' <- addUnspentCredits mergeUnspentCredits (Credits c)
356-
totalSteps <- readPrimVar (getTotalStepsVar mergeStepsPerformed)
374+
Credits unspentCredits' <- addUnspentCredits mergeUnspentCreditsVar (Credits c)
375+
stepsPerformed <- readStepsPerformed mergeStepsPerformedVar
357376

358-
if totalSteps + unspentCredits' >= unNumEntries mergeNumEntries then do
377+
if stepsPerformed + unspentCredits' >= unNumEntries mergeNumEntries then do
359378
-- We can finish the merge immediately
360379
isMergeDone <-
361-
bracketOnError (takeAllUnspentCredits mergeUnspentCredits)
362-
(putBackUnspentCredits mergeUnspentCredits)
363-
(stepMerge mergeSpentCredits mergeStepsPerformed
380+
bracketOnError (takeAllUnspentCredits mergeUnspentCreditsVar)
381+
(putBackUnspentCredits mergeUnspentCreditsVar)
382+
(stepMerge mergeSpentCreditsVar mergeStepsPerformedVar
364383
mergeState)
365384
when isMergeDone $ completeMerge mergeState mergeKnownCompleted
366385
else if unspentCredits' >= getCreditThreshold creditsThresh then do
@@ -373,10 +392,10 @@ supplyCredits (Credits c) creditsThresh (DeRef MergingRun {..}) = do
373392
-- credits as we took, even if the merge has progressed. See Note
374393
-- [Merge Batching] to see why this is okay.
375394
bracketOnError
376-
(tryTakeUnspentCredits mergeUnspentCredits creditsThresh (Credits unspentCredits'))
377-
(mapM_ (putBackUnspentCredits mergeUnspentCredits)) $ \case
395+
(tryTakeUnspentCredits mergeUnspentCreditsVar creditsThresh (Credits unspentCredits'))
396+
(mapM_ (putBackUnspentCredits mergeUnspentCreditsVar)) $ \case
378397
Nothing -> pure False
379-
Just c' -> stepMerge mergeSpentCredits mergeStepsPerformed
398+
Just c' -> stepMerge mergeSpentCreditsVar mergeStepsPerformedVar
380399
mergeState c'
381400

382401
-- If we just finished the merge, then we convert the output of the
@@ -419,7 +438,7 @@ addUnspentCredits (UnspentCreditsVar !var) (Credits c) =
419438
--
420439
-- Nothing can be returned if the variable has already gone below the threshold,
421440
-- which may happen if another thread is concurrently doing the same loop on
422-
-- 'mergeUnspentCredits'.
441+
-- 'mergeUnspentCreditsVar'.
423442
tryTakeUnspentCredits ::
424443
PrimMonad m
425444
=> UnspentCreditsVar (PrimState m)
@@ -463,42 +482,41 @@ takeAllUnspentCredits ::
463482
PrimMonad m
464483
=> UnspentCreditsVar (PrimState m)
465484
-> m Credits
466-
takeAllUnspentCredits (UnspentCreditsVar !unspentCreditsVar) = do
467-
prev <- readPrimVar unspentCreditsVar
485+
takeAllUnspentCredits
486+
unspentCreditsVar@(UnspentCreditsVar !var) = do
487+
prev <- readUnspentCredits unspentCreditsVar
468488
casLoop prev
469489
where
470490
casLoop !prev = do
471-
prev' <- casInt unspentCreditsVar prev 0
491+
prev' <- casInt var prev 0
472492
if prev' == prev then
473493
pure (Credits prev)
474494
else
475495
casLoop prev'
476496

477497
{-# SPECIALISE stepMerge ::
478498
SpentCreditsVar RealWorld
479-
-> TotalStepsVar RealWorld
499+
-> StepsPerformedVar RealWorld
480500
-> StrictMVar IO (MergingRunState IO h)
481501
-> Credits
482502
-> IO Bool #-}
483503
stepMerge ::
484504
(MonadMVar m, MonadMask m, MonadSTM m, MonadST m)
485505
=> SpentCreditsVar (PrimState m)
486-
-> TotalStepsVar (PrimState m)
506+
-> StepsPerformedVar (PrimState m)
487507
-> StrictMVar m (MergingRunState m h)
488508
-> Credits
489509
-> m Bool
490-
stepMerge (SpentCreditsVar spentCreditsVar)
491-
(TotalStepsVar totalStepsVar)
492-
mergeVar (Credits c) =
510+
stepMerge spentCreditsVar stepsPerformedVar mergeVar (Credits c) =
493511
withMVar mergeVar $ \case
494512
CompletedMerge{} -> pure False
495513
(OngoingMerge _rs m) -> do
496-
totalSteps <- readPrimVar totalStepsVar
497-
spentCredits <- readPrimVar spentCreditsVar
514+
stepsPerformed <- readStepsPerformed stepsPerformedVar
515+
spentCredits <- readSpentCredits spentCreditsVar
498516

499517
-- If we previously performed too many merge steps, then we perform
500518
-- fewer now.
501-
let stepsToDo = max 0 (spentCredits + c - totalSteps)
519+
let stepsToDo = max 0 (spentCredits + c - stepsPerformed)
502520
-- Merge.steps guarantees that @stepsDone >= stepsToDo@ /unless/ the
503521
-- merge was just now finished.
504522
(stepsDone, stepResult) <- Merge.steps m stepsToDo
@@ -509,17 +527,17 @@ stepMerge (SpentCreditsVar spentCreditsVar)
509527

510528
-- This should be the only point at which we write to these variables.
511529
--
512-
-- It is guaranteed that @totalSteps' >= spentCredits'@ /unless/ the
530+
-- It is guaranteed that @stepsPerformed' >= spentCredits'@ /unless/ the
513531
-- merge was just now finished.
514-
let totalSteps' = totalSteps + stepsDone
515-
let spentCredits' = spentCredits + c
532+
let !stepsPerformed' = stepsPerformed + stepsDone
533+
let !spentCredits' = spentCredits + c
516534
-- It is guaranteed that
517-
-- @readPrimVar totalStepsVar >= readPrimVar spentCreditsVar@,
535+
-- @readStepsPerformed stepsPerformedVar >= readSpentCredits spentCreditsVar@,
518536
-- /unless/ the merge was just now finished.
519-
writePrimVar totalStepsVar $! totalSteps'
520-
writePrimVar spentCreditsVar $! spentCredits'
537+
writeStepsPerformed stepsPerformedVar stepsPerformed'
538+
writeSpentCredits spentCreditsVar spentCredits'
521539
assert (case stepResult of
522-
MergeInProgress -> totalSteps' >= spentCredits'
540+
MergeInProgress -> stepsPerformed' >= spentCredits'
523541
MergeDone -> True
524542
) $ pure ()
525543

@@ -559,9 +577,9 @@ expectCompleted (DeRef MergingRun {..}) = do
559577
knownCompleted <- readMutVar mergeKnownCompleted
560578
-- The merge is not guaranteed to be complete, so we do the remaining steps
561579
when (knownCompleted == MergeMaybeCompleted) $ do
562-
totalSteps <- readPrimVar (getTotalStepsVar mergeStepsPerformed)
563-
let !credits = Credits (unNumEntries mergeNumEntries - totalSteps)
564-
isMergeDone <- stepMerge mergeSpentCredits mergeStepsPerformed
580+
stepsPerformed <- readStepsPerformed mergeStepsPerformedVar
581+
let !credits = Credits (unNumEntries mergeNumEntries - stepsPerformed)
582+
isMergeDone <- stepMerge mergeSpentCreditsVar mergeStepsPerformedVar
565583
mergeState credits
566584
when isMergeDone $ completeMerge mergeState mergeKnownCompleted
567585
-- TODO: can we think of a check to see if we did not do too much work

src/Database/LSMTree/Internal/Snapshot.hs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import Control.Monad.Class.MonadThrow (MonadMask)
3636
import Control.Monad.Primitive (PrimMonad)
3737
import Control.RefCount
3838
import Data.Foldable (sequenceA_, traverse_)
39-
import Data.Primitive.PrimVar
4039
import Data.Text (Text)
4140
import Data.Traversable (for)
4241
import qualified Data.Vector as V
@@ -201,8 +200,8 @@ toSnapIncomingRun (Merging mergePolicy (DeRef MR.MergingRun {..})) = do
201200
-- restore merge work on snapshot load. No need to snapshot the contents
202201
-- of totalStepsVar here, since we still start counting from 0 again when
203202
-- loading the snapshot.
204-
unspentCredits <- readPrimVar (MR.getUnspentCreditsVar mergeUnspentCredits)
205-
spentCredits <- readPrimVar (MR.getSpentCreditsVar mergeSpentCredits)
203+
unspentCredits <- MR.readUnspentCredits mergeUnspentCreditsVar
204+
spentCredits <- MR.readSpentCredits mergeSpentCreditsVar
206205
smrs <- toSnapMergingRunState <$> readMVar mergeState
207206
pure $
208207
SnapMergingRun

0 commit comments

Comments
 (0)