{-# OPTIONS_HADDOCK not-home #-}
module Database.LSMTree.Internal.Merge (
Merge (..)
, MergeType (..)
, IsMergeType (..)
, LevelMergeType (..)
, TreeMergeType (..)
, Mappend
, MergeState (..)
, RunParams (..)
, new
, abort
, complete
, stepsToCompletion
, stepsToCompletionCounted
, StepResult (..)
, steps
, mergeRunParams
) where
import Control.DeepSeq (NFData (..))
import Control.Exception (assert)
import Control.Monad (when)
import Control.Monad.Class.MonadST (MonadST)
import Control.Monad.Class.MonadSTM (MonadSTM (..))
import Control.Monad.Class.MonadThrow (MonadMask, MonadThrow)
import Control.Monad.Primitive (PrimState)
import Control.RefCount
import Data.Primitive.MutVar
import Data.Traversable (for)
import qualified Data.Vector as V
import Database.LSMTree.Internal.BlobRef (RawBlobRef)
import Database.LSMTree.Internal.Entry
import Database.LSMTree.Internal.Run (Run)
import qualified Database.LSMTree.Internal.Run as Run
import Database.LSMTree.Internal.RunBuilder (RunBuilder, RunParams)
import qualified Database.LSMTree.Internal.RunBuilder as Builder
import qualified Database.LSMTree.Internal.RunReader as Reader
import Database.LSMTree.Internal.RunReaders (Readers)
import qualified Database.LSMTree.Internal.RunReaders as Readers
import Database.LSMTree.Internal.Serialise
import qualified System.FS.API as FS
import System.FS.API (HasFS)
import System.FS.BlockIO.API (HasBlockIO)
data Merge t m h = Merge {
forall t (m :: * -> *) h. Merge t m h -> t
mergeType :: !t
, forall t (m :: * -> *) h. Merge t m h -> Bool
mergeIsLastLevel :: !Bool
, forall t (m :: * -> *) h. Merge t m h -> Bool
mergeIsUnion :: !Bool
, forall t (m :: * -> *) h. Merge t m h -> Mappend
mergeMappend :: !Mappend
, forall t (m :: * -> *) h. Merge t m h -> Readers m h
mergeReaders :: {-# UNPACK #-} !(Readers m h)
, forall t (m :: * -> *) h. Merge t m h -> RunBuilder m h
mergeBuilder :: !(RunBuilder m h)
, forall t (m :: * -> *) h.
Merge t m h -> MutVar (PrimState m) MergeState
mergeState :: !(MutVar (PrimState m) MergeState)
, forall t (m :: * -> *) h. Merge t m h -> HasFS m h
mergeHasFS :: !(HasFS m h)
, forall t (m :: * -> *) h. Merge t m h -> HasBlockIO m h
mergeHasBlockIO :: !(HasBlockIO m h)
}
mergeRunParams :: Merge t m h -> RunParams
mergeRunParams :: forall t (m :: * -> *) h. Merge t m h -> RunParams
mergeRunParams = RunBuilder m h -> RunParams
forall (m :: * -> *) h. RunBuilder m h -> RunParams
Builder.runBuilderParams (RunBuilder m h -> RunParams)
-> (Merge t m h -> RunBuilder m h) -> Merge t m h -> RunParams
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Merge t m h -> RunBuilder m h
forall t (m :: * -> *) h. Merge t m h -> RunBuilder m h
mergeBuilder
data MergeState =
Merging
| MergingDone
| Completed
| Closed
class IsMergeType t where
isLastLevel :: t -> Bool
isUnion :: t -> Bool
data MergeType = MergeTypeMidLevel | MergeTypeLastLevel | MergeTypeUnion
deriving stock (MergeType -> MergeType -> Bool
(MergeType -> MergeType -> Bool)
-> (MergeType -> MergeType -> Bool) -> Eq MergeType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MergeType -> MergeType -> Bool
== :: MergeType -> MergeType -> Bool
$c/= :: MergeType -> MergeType -> Bool
/= :: MergeType -> MergeType -> Bool
Eq, Int -> MergeType -> ShowS
[MergeType] -> ShowS
MergeType -> String
(Int -> MergeType -> ShowS)
-> (MergeType -> String)
-> ([MergeType] -> ShowS)
-> Show MergeType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MergeType -> ShowS
showsPrec :: Int -> MergeType -> ShowS
$cshow :: MergeType -> String
show :: MergeType -> String
$cshowList :: [MergeType] -> ShowS
showList :: [MergeType] -> ShowS
Show)
instance NFData MergeType where
rnf :: MergeType -> ()
rnf MergeType
MergeTypeMidLevel = ()
rnf MergeType
MergeTypeLastLevel = ()
rnf MergeType
MergeTypeUnion = ()
instance IsMergeType MergeType where
isLastLevel :: MergeType -> Bool
isLastLevel = \case
MergeType
MergeTypeMidLevel -> Bool
False
MergeType
MergeTypeLastLevel -> Bool
True
MergeType
MergeTypeUnion -> Bool
True
isUnion :: MergeType -> Bool
isUnion = \case
MergeType
MergeTypeMidLevel -> Bool
False
MergeType
MergeTypeLastLevel -> Bool
False
MergeType
MergeTypeUnion -> Bool
True
data LevelMergeType = MergeMidLevel | MergeLastLevel
deriving stock (LevelMergeType -> LevelMergeType -> Bool
(LevelMergeType -> LevelMergeType -> Bool)
-> (LevelMergeType -> LevelMergeType -> Bool) -> Eq LevelMergeType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LevelMergeType -> LevelMergeType -> Bool
== :: LevelMergeType -> LevelMergeType -> Bool
$c/= :: LevelMergeType -> LevelMergeType -> Bool
/= :: LevelMergeType -> LevelMergeType -> Bool
Eq, Int -> LevelMergeType -> ShowS
[LevelMergeType] -> ShowS
LevelMergeType -> String
(Int -> LevelMergeType -> ShowS)
-> (LevelMergeType -> String)
-> ([LevelMergeType] -> ShowS)
-> Show LevelMergeType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LevelMergeType -> ShowS
showsPrec :: Int -> LevelMergeType -> ShowS
$cshow :: LevelMergeType -> String
show :: LevelMergeType -> String
$cshowList :: [LevelMergeType] -> ShowS
showList :: [LevelMergeType] -> ShowS
Show)
instance NFData LevelMergeType where
rnf :: LevelMergeType -> ()
rnf LevelMergeType
MergeMidLevel = ()
rnf LevelMergeType
MergeLastLevel = ()
instance IsMergeType LevelMergeType where
isLastLevel :: LevelMergeType -> Bool
isLastLevel = \case
LevelMergeType
MergeMidLevel -> Bool
False
LevelMergeType
MergeLastLevel -> Bool
True
isUnion :: LevelMergeType -> Bool
isUnion = Bool -> LevelMergeType -> Bool
forall a b. a -> b -> a
const Bool
False
data TreeMergeType = MergeLevel | MergeUnion
deriving stock (TreeMergeType -> TreeMergeType -> Bool
(TreeMergeType -> TreeMergeType -> Bool)
-> (TreeMergeType -> TreeMergeType -> Bool) -> Eq TreeMergeType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TreeMergeType -> TreeMergeType -> Bool
== :: TreeMergeType -> TreeMergeType -> Bool
$c/= :: TreeMergeType -> TreeMergeType -> Bool
/= :: TreeMergeType -> TreeMergeType -> Bool
Eq, Int -> TreeMergeType -> ShowS
[TreeMergeType] -> ShowS
TreeMergeType -> String
(Int -> TreeMergeType -> ShowS)
-> (TreeMergeType -> String)
-> ([TreeMergeType] -> ShowS)
-> Show TreeMergeType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TreeMergeType -> ShowS
showsPrec :: Int -> TreeMergeType -> ShowS
$cshow :: TreeMergeType -> String
show :: TreeMergeType -> String
$cshowList :: [TreeMergeType] -> ShowS
showList :: [TreeMergeType] -> ShowS
Show)
instance NFData TreeMergeType where
rnf :: TreeMergeType -> ()
rnf TreeMergeType
MergeLevel = ()
rnf TreeMergeType
MergeUnion = ()
instance IsMergeType TreeMergeType where
isLastLevel :: TreeMergeType -> Bool
isLastLevel = Bool -> TreeMergeType -> Bool
forall a b. a -> b -> a
const Bool
True
isUnion :: TreeMergeType -> Bool
isUnion = \case
TreeMergeType
MergeLevel -> Bool
False
TreeMergeType
MergeUnion -> Bool
True
type Mappend = SerialisedValue -> SerialisedValue -> SerialisedValue
{-# SPECIALISE new ::
IsMergeType t
=> HasFS IO h
-> HasBlockIO IO h
-> RunParams
-> t
-> Mappend
-> Run.RunFsPaths
-> V.Vector (Ref (Run IO h))
-> IO (Maybe (Merge t IO h)) #-}
new ::
(IsMergeType t, MonadMask m, MonadSTM m, MonadST m)
=> HasFS m h
-> HasBlockIO m h
-> RunParams
-> t
-> Mappend
-> Run.RunFsPaths
-> V.Vector (Ref (Run m h))
-> m (Maybe (Merge t m h))
new :: forall t (m :: * -> *) h.
(IsMergeType t, MonadMask m, MonadSTM m, MonadST m) =>
HasFS m h
-> HasBlockIO m h
-> RunParams
-> t
-> Mappend
-> RunFsPaths
-> Vector (Ref (Run m h))
-> m (Maybe (Merge t m h))
new HasFS m h
hfs HasBlockIO m h
hbio RunParams
runParams t
mergeType Mappend
mergeMappend RunFsPaths
targetPaths Vector (Ref (Run m h))
runs = do
Maybe (Readers m h)
mreaders <- OffsetKey
-> Maybe (WriteBuffer, Ref (WriteBufferBlobs m h))
-> Vector (Ref (Run m h))
-> m (Maybe (Readers m h))
forall (m :: * -> *) h.
(MonadMask m, MonadST m, MonadSTM m) =>
OffsetKey
-> Maybe (WriteBuffer, Ref (WriteBufferBlobs m h))
-> Vector (Ref (Run m h))
-> m (Maybe (Readers m h))
Readers.new OffsetKey
Readers.NoOffsetKey Maybe (WriteBuffer, Ref (WriteBufferBlobs m h))
forall a. Maybe a
Nothing Vector (Ref (Run m h))
runs
Maybe (Readers m h)
-> (Readers m h -> m (Merge t m h)) -> m (Maybe (Merge t m h))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for Maybe (Readers m h)
mreaders ((Readers m h -> m (Merge t m h)) -> m (Maybe (Merge t m h)))
-> (Readers m h -> m (Merge t m h)) -> m (Maybe (Merge t m h))
forall a b. (a -> b) -> a -> b
$ \Readers m h
mergeReaders -> do
let numEntries :: NumEntries
numEntries = (Ref (Run m h) -> NumEntries)
-> Vector (Ref (Run m h)) -> NumEntries
forall m a. Monoid m => (a -> m) -> Vector a -> m
V.foldMap' Ref (Run m h) -> NumEntries
forall (m :: * -> *) h. Ref (Run m h) -> NumEntries
Run.size Vector (Ref (Run m h))
runs
RunBuilder m h
mergeBuilder <- HasFS m h
-> HasBlockIO m h
-> RunParams
-> RunFsPaths
-> NumEntries
-> m (RunBuilder m h)
forall (m :: * -> *) h.
(MonadST m, MonadSTM m) =>
HasFS m h
-> HasBlockIO m h
-> RunParams
-> RunFsPaths
-> NumEntries
-> m (RunBuilder m h)
Builder.new HasFS m h
hfs HasBlockIO m h
hbio RunParams
runParams RunFsPaths
targetPaths NumEntries
numEntries
MutVar (PrimState m) MergeState
mergeState <- MergeState -> m (MutVar (PrimState m) MergeState)
forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar (MergeState -> m (MutVar (PrimState m) MergeState))
-> MergeState -> m (MutVar (PrimState m) MergeState)
forall a b. (a -> b) -> a -> b
$! MergeState
Merging
Merge t m h -> m (Merge t m h)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Merge {
mergeIsLastLevel :: Bool
mergeIsLastLevel = t -> Bool
forall t. IsMergeType t => t -> Bool
isLastLevel t
mergeType
, mergeIsUnion :: Bool
mergeIsUnion = t -> Bool
forall t. IsMergeType t => t -> Bool
isUnion t
mergeType
, mergeHasFS :: HasFS m h
mergeHasFS = HasFS m h
hfs
, mergeHasBlockIO :: HasBlockIO m h
mergeHasBlockIO = HasBlockIO m h
hbio
, t
MutVar (PrimState m) MergeState
RunBuilder m h
Readers m h
Mappend
mergeType :: t
mergeMappend :: Mappend
mergeReaders :: Readers m h
mergeBuilder :: RunBuilder m h
mergeState :: MutVar (PrimState m) MergeState
mergeType :: t
mergeMappend :: Mappend
mergeReaders :: Readers m h
mergeBuilder :: RunBuilder m h
mergeState :: MutVar (PrimState m) MergeState
..
}
{-# SPECIALISE abort :: Merge t IO (FS.Handle h) -> IO () #-}
abort :: (MonadMask m, MonadSTM m, MonadST m) => Merge t m h -> m ()
abort :: forall (m :: * -> *) t h.
(MonadMask m, MonadSTM m, MonadST m) =>
Merge t m h -> m ()
abort Merge {t
Bool
HasFS m h
HasBlockIO m h
MutVar (PrimState m) MergeState
RunBuilder m h
Readers m h
Mappend
mergeType :: forall t (m :: * -> *) h. Merge t m h -> t
mergeIsLastLevel :: forall t (m :: * -> *) h. Merge t m h -> Bool
mergeIsUnion :: forall t (m :: * -> *) h. Merge t m h -> Bool
mergeMappend :: forall t (m :: * -> *) h. Merge t m h -> Mappend
mergeReaders :: forall t (m :: * -> *) h. Merge t m h -> Readers m h
mergeBuilder :: forall t (m :: * -> *) h. Merge t m h -> RunBuilder m h
mergeState :: forall t (m :: * -> *) h.
Merge t m h -> MutVar (PrimState m) MergeState
mergeHasFS :: forall t (m :: * -> *) h. Merge t m h -> HasFS m h
mergeHasBlockIO :: forall t (m :: * -> *) h. Merge t m h -> HasBlockIO m h
mergeType :: t
mergeIsLastLevel :: Bool
mergeIsUnion :: Bool
mergeMappend :: Mappend
mergeReaders :: Readers m h
mergeBuilder :: RunBuilder m h
mergeState :: MutVar (PrimState m) MergeState
mergeHasFS :: HasFS m h
mergeHasBlockIO :: HasBlockIO m h
..} = do
MutVar (PrimState m) MergeState -> m MergeState
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar (PrimState m) MergeState
mergeState m MergeState -> (MergeState -> m ()) -> m ()
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
MergeState
Merging -> do
Readers m h -> m ()
forall (m :: * -> *) h.
(MonadMask m, MonadSTM m, PrimMonad m) =>
Readers m h -> m ()
Readers.close Readers m h
mergeReaders
RunBuilder m h -> m ()
forall (m :: * -> *) h. MonadSTM m => RunBuilder m h -> m ()
Builder.close RunBuilder m h
mergeBuilder
MergeState
MergingDone -> do
RunBuilder m h -> m ()
forall (m :: * -> *) h. MonadSTM m => RunBuilder m h -> m ()
Builder.close RunBuilder m h
mergeBuilder
MergeState
Completed ->
Bool -> m () -> m ()
forall a. (?callStack::CallStack) => Bool -> a -> a
assert Bool
False (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
MergeState
Closed ->
Bool -> m () -> m ()
forall a. (?callStack::CallStack) => Bool -> a -> a
assert Bool
False (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
MutVar (PrimState m) MergeState -> MergeState -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar MutVar (PrimState m) MergeState
mergeState (MergeState -> m ()) -> MergeState -> m ()
forall a b. (a -> b) -> a -> b
$! MergeState
Closed
{-# SPECIALISE complete ::
Merge t IO h
-> IO (Ref (Run IO h)) #-}
complete ::
(MonadSTM m, MonadST m, MonadMask m)
=> Merge t m h
-> m (Ref (Run m h))
complete :: forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadMask m) =>
Merge t m h -> m (Ref (Run m h))
complete Merge{t
Bool
HasFS m h
HasBlockIO m h
MutVar (PrimState m) MergeState
RunBuilder m h
Readers m h
Mappend
mergeType :: forall t (m :: * -> *) h. Merge t m h -> t
mergeIsLastLevel :: forall t (m :: * -> *) h. Merge t m h -> Bool
mergeIsUnion :: forall t (m :: * -> *) h. Merge t m h -> Bool
mergeMappend :: forall t (m :: * -> *) h. Merge t m h -> Mappend
mergeReaders :: forall t (m :: * -> *) h. Merge t m h -> Readers m h
mergeBuilder :: forall t (m :: * -> *) h. Merge t m h -> RunBuilder m h
mergeState :: forall t (m :: * -> *) h.
Merge t m h -> MutVar (PrimState m) MergeState
mergeHasFS :: forall t (m :: * -> *) h. Merge t m h -> HasFS m h
mergeHasBlockIO :: forall t (m :: * -> *) h. Merge t m h -> HasBlockIO m h
mergeType :: t
mergeIsLastLevel :: Bool
mergeIsUnion :: Bool
mergeMappend :: Mappend
mergeReaders :: Readers m h
mergeBuilder :: RunBuilder m h
mergeState :: MutVar (PrimState m) MergeState
mergeHasFS :: HasFS m h
mergeHasBlockIO :: HasBlockIO m h
..} = do
MutVar (PrimState m) MergeState -> m MergeState
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar (PrimState m) MergeState
mergeState m MergeState
-> (MergeState -> m (Ref (Run m h))) -> m (Ref (Run m h))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
MergeState
Merging -> String -> m (Ref (Run m h))
forall a. (?callStack::CallStack) => String -> a
error String
"complete: Merge is not done"
MergeState
MergingDone -> do
Ref (Run m h)
r <- RunBuilder m h -> m (Ref (Run m h))
forall (m :: * -> *) h.
(MonadST m, MonadSTM m, MonadMask m) =>
RunBuilder m h -> m (Ref (Run m h))
Run.fromBuilder RunBuilder m h
mergeBuilder
MutVar (PrimState m) MergeState -> MergeState -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar MutVar (PrimState m) MergeState
mergeState (MergeState -> m ()) -> MergeState -> m ()
forall a b. (a -> b) -> a -> b
$! MergeState
Completed
Ref (Run m h) -> m (Ref (Run m h))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Ref (Run m h)
r
MergeState
Completed -> String -> m (Ref (Run m h))
forall a. (?callStack::CallStack) => String -> a
error String
"complete: Merge is already completed"
MergeState
Closed -> String -> m (Ref (Run m h))
forall a. (?callStack::CallStack) => String -> a
error String
"complete: Merge is closed"
{-# SPECIALISE stepsToCompletion ::
Merge t IO h
-> Int
-> IO (Ref (Run IO h)) #-}
stepsToCompletion ::
(MonadMask m, MonadSTM m, MonadST m)
=> Merge t m h
-> Int
-> m (Ref (Run m h))
stepsToCompletion :: forall (m :: * -> *) t h.
(MonadMask m, MonadSTM m, MonadST m) =>
Merge t m h -> Int -> m (Ref (Run m h))
stepsToCompletion Merge t m h
m Int
stepBatchSize = m (Ref (Run m h))
go
where
go :: m (Ref (Run m h))
go = do
Merge t m h -> Int -> m (Int, StepResult)
forall (m :: * -> *) t h.
(MonadMask m, MonadSTM m, MonadST m) =>
Merge t m h -> Int -> m (Int, StepResult)
steps Merge t m h
m Int
stepBatchSize m (Int, StepResult)
-> ((Int, StepResult) -> m (Ref (Run m h))) -> m (Ref (Run m h))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
(Int
_, StepResult
MergeInProgress) -> m (Ref (Run m h))
go
(Int
_, StepResult
MergeDone) -> Merge t m h -> m (Ref (Run m h))
forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadMask m) =>
Merge t m h -> m (Ref (Run m h))
complete Merge t m h
m
{-# SPECIALISE stepsToCompletionCounted ::
Merge t IO h
-> Int
-> IO (Int, Ref (Run IO h)) #-}
stepsToCompletionCounted ::
(MonadMask m, MonadSTM m, MonadST m)
=> Merge t m h
-> Int
-> m (Int, Ref (Run m h))
stepsToCompletionCounted :: forall (m :: * -> *) t h.
(MonadMask m, MonadSTM m, MonadST m) =>
Merge t m h -> Int -> m (Int, Ref (Run m h))
stepsToCompletionCounted Merge t m h
m Int
stepBatchSize = Int -> m (Int, Ref (Run m h))
go Int
0
where
go :: Int -> m (Int, Ref (Run m h))
go !Int
stepsSum = do
Merge t m h -> Int -> m (Int, StepResult)
forall (m :: * -> *) t h.
(MonadMask m, MonadSTM m, MonadST m) =>
Merge t m h -> Int -> m (Int, StepResult)
steps Merge t m h
m Int
stepBatchSize m (Int, StepResult)
-> ((Int, StepResult) -> m (Int, Ref (Run m h)))
-> m (Int, Ref (Run m h))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
(Int
n, StepResult
MergeInProgress) -> Int -> m (Int, Ref (Run m h))
go (Int
stepsSum Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
(Int
n, StepResult
MergeDone) -> let !stepsSum' :: Int
stepsSum' = Int
stepsSum Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n
in (Int
stepsSum',) (Ref (Run m h) -> (Int, Ref (Run m h)))
-> m (Ref (Run m h)) -> m (Int, Ref (Run m h))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Merge t m h -> m (Ref (Run m h))
forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadMask m) =>
Merge t m h -> m (Ref (Run m h))
complete Merge t m h
m
data StepResult = MergeInProgress | MergeDone
deriving stock StepResult -> StepResult -> Bool
(StepResult -> StepResult -> Bool)
-> (StepResult -> StepResult -> Bool) -> Eq StepResult
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StepResult -> StepResult -> Bool
== :: StepResult -> StepResult -> Bool
$c/= :: StepResult -> StepResult -> Bool
/= :: StepResult -> StepResult -> Bool
Eq
stepsInvariant :: Int -> (Int, StepResult) -> Bool
stepsInvariant :: Int -> (Int, StepResult) -> Bool
stepsInvariant Int
requestedSteps = \case
(Int
n, StepResult
MergeInProgress) -> Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
requestedSteps
(Int, StepResult)
_ -> Bool
True
{-# SPECIALISE steps ::
Merge t IO h
-> Int
-> IO (Int, StepResult) #-}
steps ::
(MonadMask m, MonadSTM m, MonadST m)
=> Merge t m h
-> Int
-> m (Int, StepResult)
steps :: forall (m :: * -> *) t h.
(MonadMask m, MonadSTM m, MonadST m) =>
Merge t m h -> Int -> m (Int, StepResult)
steps m :: Merge t m h
m@Merge {t
Bool
HasFS m h
HasBlockIO m h
MutVar (PrimState m) MergeState
RunBuilder m h
Readers m h
Mappend
mergeType :: forall t (m :: * -> *) h. Merge t m h -> t
mergeIsLastLevel :: forall t (m :: * -> *) h. Merge t m h -> Bool
mergeIsUnion :: forall t (m :: * -> *) h. Merge t m h -> Bool
mergeMappend :: forall t (m :: * -> *) h. Merge t m h -> Mappend
mergeReaders :: forall t (m :: * -> *) h. Merge t m h -> Readers m h
mergeBuilder :: forall t (m :: * -> *) h. Merge t m h -> RunBuilder m h
mergeState :: forall t (m :: * -> *) h.
Merge t m h -> MutVar (PrimState m) MergeState
mergeHasFS :: forall t (m :: * -> *) h. Merge t m h -> HasFS m h
mergeHasBlockIO :: forall t (m :: * -> *) h. Merge t m h -> HasBlockIO m h
mergeType :: t
mergeIsLastLevel :: Bool
mergeIsUnion :: Bool
mergeMappend :: Mappend
mergeReaders :: Readers m h
mergeBuilder :: RunBuilder m h
mergeState :: MutVar (PrimState m) MergeState
mergeHasFS :: HasFS m h
mergeHasBlockIO :: HasBlockIO m h
..} Int
requestedSteps = (Int, StepResult) -> (Int, StepResult)
assertStepsInvariant ((Int, StepResult) -> (Int, StepResult))
-> m (Int, StepResult) -> m (Int, StepResult)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do
MutVar (PrimState m) MergeState -> m MergeState
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar (PrimState m) MergeState
mergeState m MergeState
-> (MergeState -> m (Int, StepResult)) -> m (Int, StepResult)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
MergeState
Merging -> if Bool
mergeIsUnion then Merge t m h -> Int -> m (Int, StepResult)
forall (m :: * -> *) t h.
(MonadMask m, MonadSTM m, MonadST m) =>
Merge t m h -> Int -> m (Int, StepResult)
doStepsUnion Merge t m h
m Int
requestedSteps
else Merge t m h -> Int -> m (Int, StepResult)
forall (m :: * -> *) t h.
(MonadMask m, MonadSTM m, MonadST m) =>
Merge t m h -> Int -> m (Int, StepResult)
doStepsLevel Merge t m h
m Int
requestedSteps
MergeState
MergingDone -> (Int, StepResult) -> m (Int, StepResult)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
0, StepResult
MergeDone)
MergeState
Completed -> String -> m (Int, StepResult)
forall a. (?callStack::CallStack) => String -> a
error String
"steps: Merge is completed"
MergeState
Closed -> String -> m (Int, StepResult)
forall a. (?callStack::CallStack) => String -> a
error String
"steps: Merge is closed"
where
assertStepsInvariant :: (Int, StepResult) -> (Int, StepResult)
assertStepsInvariant (Int, StepResult)
res = Bool -> (Int, StepResult) -> (Int, StepResult)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int -> (Int, StepResult) -> Bool
stepsInvariant Int
requestedSteps (Int, StepResult)
res) (Int, StepResult)
res
{-# SPECIALISE doStepsLevel ::
Merge t IO h
-> Int
-> IO (Int, StepResult) #-}
doStepsLevel ::
(MonadMask m, MonadSTM m, MonadST m)
=> Merge t m h
-> Int
-> m (Int, StepResult)
doStepsLevel :: forall (m :: * -> *) t h.
(MonadMask m, MonadSTM m, MonadST m) =>
Merge t m h -> Int -> m (Int, StepResult)
doStepsLevel m :: Merge t m h
m@Merge {t
Bool
HasFS m h
HasBlockIO m h
MutVar (PrimState m) MergeState
RunBuilder m h
Readers m h
Mappend
mergeType :: forall t (m :: * -> *) h. Merge t m h -> t
mergeIsLastLevel :: forall t (m :: * -> *) h. Merge t m h -> Bool
mergeIsUnion :: forall t (m :: * -> *) h. Merge t m h -> Bool
mergeMappend :: forall t (m :: * -> *) h. Merge t m h -> Mappend
mergeReaders :: forall t (m :: * -> *) h. Merge t m h -> Readers m h
mergeBuilder :: forall t (m :: * -> *) h. Merge t m h -> RunBuilder m h
mergeState :: forall t (m :: * -> *) h.
Merge t m h -> MutVar (PrimState m) MergeState
mergeHasFS :: forall t (m :: * -> *) h. Merge t m h -> HasFS m h
mergeHasBlockIO :: forall t (m :: * -> *) h. Merge t m h -> HasBlockIO m h
mergeType :: t
mergeIsLastLevel :: Bool
mergeIsUnion :: Bool
mergeMappend :: Mappend
mergeReaders :: Readers m h
mergeBuilder :: RunBuilder m h
mergeState :: MutVar (PrimState m) MergeState
mergeHasFS :: HasFS m h
mergeHasBlockIO :: HasBlockIO m h
..} Int
requestedSteps = Int -> m (Int, StepResult)
go Int
0
where
go :: Int -> m (Int, StepResult)
go !Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
requestedSteps =
(Int, StepResult) -> m (Int, StepResult)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
n, StepResult
MergeInProgress)
| Bool
otherwise = do
(SerialisedKey
key, Entry m h
entry, HasMore
hasMore) <- Readers m h -> m (SerialisedKey, Entry m h, HasMore)
forall (m :: * -> *) h.
(MonadMask m, MonadSTM m, MonadST m) =>
Readers m h -> m (SerialisedKey, Entry m h, HasMore)
Readers.pop Readers m h
mergeReaders
case HasMore
hasMore of
HasMore
Readers.HasMore ->
Int -> SerialisedKey -> Entry m h -> m (Int, StepResult)
handleEntry (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) SerialisedKey
key Entry m h
entry
HasMore
Readers.Drained -> do
Merge t m h -> SerialisedKey -> Entry m h -> m ()
forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadThrow m) =>
Merge t m h -> SerialisedKey -> Entry m h -> m ()
writeReaderEntry Merge t m h
m SerialisedKey
key Entry m h
entry
MutVar (PrimState m) MergeState -> MergeState -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar MutVar (PrimState m) MergeState
mergeState (MergeState -> m ()) -> MergeState -> m ()
forall a b. (a -> b) -> a -> b
$! MergeState
MergingDone
(Int, StepResult) -> m (Int, StepResult)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, StepResult
MergeDone)
handleEntry :: Int -> SerialisedKey -> Entry m h -> m (Int, StepResult)
handleEntry !Int
n !SerialisedKey
key (Reader.Entry (Mupdate SerialisedValue
v)) =
Int -> SerialisedKey -> SerialisedValue -> m (Int, StepResult)
handleMupdate Int
n SerialisedKey
key SerialisedValue
v
handleEntry !Int
n !SerialisedKey
key (Reader.EntryOverflow (Mupdate SerialisedValue
v) RawPage
_ Word32
len [RawOverflowPage]
overflowPages) =
Int -> SerialisedKey -> SerialisedValue -> m (Int, StepResult)
handleMupdate Int
n SerialisedKey
key (Word32 -> [RawOverflowPage] -> SerialisedValue -> SerialisedValue
Reader.appendOverflow Word32
len [RawOverflowPage]
overflowPages SerialisedValue
v)
handleEntry !Int
n !SerialisedKey
key Entry m h
entry = do
Merge t m h -> SerialisedKey -> Entry m h -> m ()
forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadThrow m) =>
Merge t m h -> SerialisedKey -> Entry m h -> m ()
writeReaderEntry Merge t m h
m SerialisedKey
key Entry m h
entry
Int -> SerialisedKey -> m (Int, StepResult)
dropRemaining Int
n SerialisedKey
key
handleMupdate :: Int -> SerialisedKey -> SerialisedValue -> m (Int, StepResult)
handleMupdate !Int
n !SerialisedKey
key !SerialisedValue
v = do
SerialisedKey
nextKey <- Readers m h -> m SerialisedKey
forall (m :: * -> *) h.
PrimMonad m =>
Readers m h -> m SerialisedKey
Readers.peekKey Readers m h
mergeReaders
if SerialisedKey
nextKey SerialisedKey -> SerialisedKey -> Bool
forall a. Eq a => a -> a -> Bool
/= SerialisedKey
key
then do
Merge t m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadThrow m) =>
Merge t m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
writeSerialisedEntry Merge t m h
m SerialisedKey
key (SerialisedValue -> Entry SerialisedValue (RawBlobRef m h)
forall v b. v -> Entry v b
Mupdate SerialisedValue
v)
Int -> m (Int, StepResult)
go Int
n
else do
(SerialisedKey
_, Entry m h
nextEntry, HasMore
hasMore) <- Readers m h -> m (SerialisedKey, Entry m h, HasMore)
forall (m :: * -> *) h.
(MonadMask m, MonadSTM m, MonadST m) =>
Readers m h -> m (SerialisedKey, Entry m h, HasMore)
Readers.pop Readers m h
mergeReaders
let resolved :: Entry SerialisedValue (RawBlobRef m h)
resolved = Mappend
-> Entry SerialisedValue (RawBlobRef m h)
-> Entry SerialisedValue (RawBlobRef m h)
-> Entry SerialisedValue (RawBlobRef m h)
forall v b. (v -> v -> v) -> Entry v b -> Entry v b -> Entry v b
combine Mappend
mergeMappend
(SerialisedValue -> Entry SerialisedValue (RawBlobRef m h)
forall v b. v -> Entry v b
Mupdate SerialisedValue
v)
(Entry m h -> Entry SerialisedValue (RawBlobRef m h)
forall (m :: * -> *) h.
Entry m h -> Entry SerialisedValue (RawBlobRef m h)
Reader.toFullEntry Entry m h
nextEntry)
case HasMore
hasMore of
HasMore
Readers.HasMore -> case Entry SerialisedValue (RawBlobRef m h)
resolved of
Mupdate SerialisedValue
v' ->
Int -> SerialisedKey -> SerialisedValue -> m (Int, StepResult)
handleMupdate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) SerialisedKey
key SerialisedValue
v'
Entry SerialisedValue (RawBlobRef m h)
_ -> do
Merge t m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadThrow m) =>
Merge t m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
writeSerialisedEntry Merge t m h
m SerialisedKey
key Entry SerialisedValue (RawBlobRef m h)
resolved
Int -> SerialisedKey -> m (Int, StepResult)
dropRemaining (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) SerialisedKey
key
HasMore
Readers.Drained -> do
Merge t m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadThrow m) =>
Merge t m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
writeSerialisedEntry Merge t m h
m SerialisedKey
key Entry SerialisedValue (RawBlobRef m h)
resolved
MutVar (PrimState m) MergeState -> MergeState -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar MutVar (PrimState m) MergeState
mergeState (MergeState -> m ()) -> MergeState -> m ()
forall a b. (a -> b) -> a -> b
$! MergeState
MergingDone
(Int, StepResult) -> m (Int, StepResult)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, StepResult
MergeDone)
dropRemaining :: Int -> SerialisedKey -> m (Int, StepResult)
dropRemaining !Int
n !SerialisedKey
key = do
(Int
dropped, HasMore
hasMore) <- Readers m h -> SerialisedKey -> m (Int, HasMore)
forall (m :: * -> *) h.
(MonadMask m, MonadSTM m, MonadST m) =>
Readers m h -> SerialisedKey -> m (Int, HasMore)
Readers.dropWhileKey Readers m h
mergeReaders SerialisedKey
key
case HasMore
hasMore of
HasMore
Readers.HasMore -> Int -> m (Int, StepResult)
go (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dropped)
HasMore
Readers.Drained -> do
MutVar (PrimState m) MergeState -> MergeState -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar MutVar (PrimState m) MergeState
mergeState (MergeState -> m ()) -> MergeState -> m ()
forall a b. (a -> b) -> a -> b
$! MergeState
MergingDone
(Int, StepResult) -> m (Int, StepResult)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dropped, StepResult
MergeDone)
{-# SPECIALISE doStepsUnion ::
Merge t IO h
-> Int
-> IO (Int, StepResult) #-}
doStepsUnion ::
(MonadMask m, MonadSTM m, MonadST m)
=> Merge t m h
-> Int
-> m (Int, StepResult)
doStepsUnion :: forall (m :: * -> *) t h.
(MonadMask m, MonadSTM m, MonadST m) =>
Merge t m h -> Int -> m (Int, StepResult)
doStepsUnion m :: Merge t m h
m@Merge {t
Bool
HasFS m h
HasBlockIO m h
MutVar (PrimState m) MergeState
RunBuilder m h
Readers m h
Mappend
mergeType :: forall t (m :: * -> *) h. Merge t m h -> t
mergeIsLastLevel :: forall t (m :: * -> *) h. Merge t m h -> Bool
mergeIsUnion :: forall t (m :: * -> *) h. Merge t m h -> Bool
mergeMappend :: forall t (m :: * -> *) h. Merge t m h -> Mappend
mergeReaders :: forall t (m :: * -> *) h. Merge t m h -> Readers m h
mergeBuilder :: forall t (m :: * -> *) h. Merge t m h -> RunBuilder m h
mergeState :: forall t (m :: * -> *) h.
Merge t m h -> MutVar (PrimState m) MergeState
mergeHasFS :: forall t (m :: * -> *) h. Merge t m h -> HasFS m h
mergeHasBlockIO :: forall t (m :: * -> *) h. Merge t m h -> HasBlockIO m h
mergeType :: t
mergeIsLastLevel :: Bool
mergeIsUnion :: Bool
mergeMappend :: Mappend
mergeReaders :: Readers m h
mergeBuilder :: RunBuilder m h
mergeState :: MutVar (PrimState m) MergeState
mergeHasFS :: HasFS m h
mergeHasBlockIO :: HasBlockIO m h
..} Int
requestedSteps = Int -> m (Int, StepResult)
go Int
0
where
go :: Int -> m (Int, StepResult)
go !Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
requestedSteps =
(Int, StepResult) -> m (Int, StepResult)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
n, StepResult
MergeInProgress)
| Bool
otherwise = do
(SerialisedKey
key, Entry m h
entry, HasMore
hasMore) <- Readers m h -> m (SerialisedKey, Entry m h, HasMore)
forall (m :: * -> *) h.
(MonadMask m, MonadSTM m, MonadST m) =>
Readers m h -> m (SerialisedKey, Entry m h, HasMore)
Readers.pop Readers m h
mergeReaders
Int -> SerialisedKey -> Entry m h -> HasMore -> m (Int, StepResult)
handleEntry (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) SerialisedKey
key Entry m h
entry HasMore
hasMore
handleEntry :: Int -> SerialisedKey -> Entry m h -> HasMore -> m (Int, StepResult)
handleEntry !Int
n !SerialisedKey
key !Entry m h
entry HasMore
Readers.Drained = do
Merge t m h -> SerialisedKey -> Entry m h -> m ()
forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadThrow m) =>
Merge t m h -> SerialisedKey -> Entry m h -> m ()
writeReaderEntry Merge t m h
m SerialisedKey
key Entry m h
entry
MutVar (PrimState m) MergeState -> MergeState -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar MutVar (PrimState m) MergeState
mergeState (MergeState -> m ()) -> MergeState -> m ()
forall a b. (a -> b) -> a -> b
$! MergeState
MergingDone
(Int, StepResult) -> m (Int, StepResult)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
n, StepResult
MergeDone)
handleEntry !Int
n !SerialisedKey
key !Entry m h
entry HasMore
Readers.HasMore = do
SerialisedKey
nextKey <- Readers m h -> m SerialisedKey
forall (m :: * -> *) h.
PrimMonad m =>
Readers m h -> m SerialisedKey
Readers.peekKey Readers m h
mergeReaders
if SerialisedKey
nextKey SerialisedKey -> SerialisedKey -> Bool
forall a. Eq a => a -> a -> Bool
/= SerialisedKey
key
then do
Merge t m h -> SerialisedKey -> Entry m h -> m ()
forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadThrow m) =>
Merge t m h -> SerialisedKey -> Entry m h -> m ()
writeReaderEntry Merge t m h
m SerialisedKey
key Entry m h
entry
Int -> m (Int, StepResult)
go Int
n
else do
(SerialisedKey
_, Entry m h
nextEntry, HasMore
hasMore) <- Readers m h -> m (SerialisedKey, Entry m h, HasMore)
forall (m :: * -> *) h.
(MonadMask m, MonadSTM m, MonadST m) =>
Readers m h -> m (SerialisedKey, Entry m h, HasMore)
Readers.pop Readers m h
mergeReaders
let resolved :: Entry SerialisedValue (RawBlobRef m h)
resolved = Mappend
-> Entry SerialisedValue (RawBlobRef m h)
-> Entry SerialisedValue (RawBlobRef m h)
-> Entry SerialisedValue (RawBlobRef m h)
forall v b. (v -> v -> v) -> Entry v b -> Entry v b -> Entry v b
combineUnion Mappend
mergeMappend
(Entry m h -> Entry SerialisedValue (RawBlobRef m h)
forall (m :: * -> *) h.
Entry m h -> Entry SerialisedValue (RawBlobRef m h)
Reader.toFullEntry Entry m h
entry)
(Entry m h -> Entry SerialisedValue (RawBlobRef m h)
forall (m :: * -> *) h.
Entry m h -> Entry SerialisedValue (RawBlobRef m h)
Reader.toFullEntry Entry m h
nextEntry)
Int -> SerialisedKey -> Entry m h -> HasMore -> m (Int, StepResult)
handleEntry (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) SerialisedKey
key (Entry SerialisedValue (RawBlobRef m h) -> Entry m h
forall (m :: * -> *) h.
Entry SerialisedValue (RawBlobRef m h) -> Entry m h
Reader.Entry Entry SerialisedValue (RawBlobRef m h)
resolved) HasMore
hasMore
{-# INLINE writeReaderEntry #-}
writeReaderEntry ::
(MonadSTM m, MonadST m, MonadThrow m)
=> Merge t m h
-> SerialisedKey
-> Reader.Entry m h
-> m ()
writeReaderEntry :: forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadThrow m) =>
Merge t m h -> SerialisedKey -> Entry m h -> m ()
writeReaderEntry Merge t m h
m SerialisedKey
key (Reader.Entry Entry SerialisedValue (RawBlobRef m h)
entryFull) =
Merge t m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadThrow m) =>
Merge t m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
writeSerialisedEntry Merge t m h
m SerialisedKey
key Entry SerialisedValue (RawBlobRef m h)
entryFull
writeReaderEntry Merge t m h
m SerialisedKey
key entry :: Entry m h
entry@(Reader.EntryOverflow Entry SerialisedValue (RawBlobRef m h)
prefix RawPage
page Word32
_ [RawOverflowPage]
overflowPages)
| InsertWithBlob {} <- Entry SerialisedValue (RawBlobRef m h)
prefix =
Bool -> m () -> m ()
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Merge t m h -> Entry SerialisedValue (RawBlobRef m h) -> Bool
forall t (m :: * -> *) h v b. Merge t m h -> Entry v b -> Bool
shouldWriteEntry Merge t m h
m Entry SerialisedValue (RawBlobRef m h)
prefix) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
RunBuilder m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
forall (m :: * -> *) h.
(MonadST m, MonadSTM m, MonadThrow m) =>
RunBuilder m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
Builder.addKeyOp (Merge t m h -> RunBuilder m h
forall t (m :: * -> *) h. Merge t m h -> RunBuilder m h
mergeBuilder Merge t m h
m) SerialisedKey
key (Entry m h -> Entry SerialisedValue (RawBlobRef m h)
forall (m :: * -> *) h.
Entry m h -> Entry SerialisedValue (RawBlobRef m h)
Reader.toFullEntry Entry m h
entry)
| Bool
otherwise =
Bool -> m () -> m ()
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Merge t m h -> Entry SerialisedValue (RawBlobRef m h) -> Bool
forall t (m :: * -> *) h v b. Merge t m h -> Entry v b -> Bool
shouldWriteEntry Merge t m h
m Entry SerialisedValue (RawBlobRef m h)
prefix) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
RunBuilder m h
-> SerialisedKey -> RawPage -> [RawOverflowPage] -> m ()
forall (m :: * -> *) h.
(MonadST m, MonadSTM m) =>
RunBuilder m h
-> SerialisedKey -> RawPage -> [RawOverflowPage] -> m ()
Builder.addLargeSerialisedKeyOp (Merge t m h -> RunBuilder m h
forall t (m :: * -> *) h. Merge t m h -> RunBuilder m h
mergeBuilder Merge t m h
m) SerialisedKey
key RawPage
page [RawOverflowPage]
overflowPages
{-# INLINE writeSerialisedEntry #-}
writeSerialisedEntry ::
(MonadSTM m, MonadST m, MonadThrow m)
=> Merge t m h
-> SerialisedKey
-> Entry SerialisedValue (RawBlobRef m h)
-> m ()
writeSerialisedEntry :: forall (m :: * -> *) t h.
(MonadSTM m, MonadST m, MonadThrow m) =>
Merge t m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
writeSerialisedEntry Merge t m h
m SerialisedKey
key Entry SerialisedValue (RawBlobRef m h)
entry =
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Merge t m h -> Entry SerialisedValue (RawBlobRef m h) -> Bool
forall t (m :: * -> *) h v b. Merge t m h -> Entry v b -> Bool
shouldWriteEntry Merge t m h
m Entry SerialisedValue (RawBlobRef m h)
entry) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
RunBuilder m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
forall (m :: * -> *) h.
(MonadST m, MonadSTM m, MonadThrow m) =>
RunBuilder m h
-> SerialisedKey -> Entry SerialisedValue (RawBlobRef m h) -> m ()
Builder.addKeyOp (Merge t m h -> RunBuilder m h
forall t (m :: * -> *) h. Merge t m h -> RunBuilder m h
mergeBuilder Merge t m h
m) SerialisedKey
key Entry SerialisedValue (RawBlobRef m h)
entry
shouldWriteEntry :: Merge t m h -> Entry v b -> Bool
shouldWriteEntry :: forall t (m :: * -> *) h v b. Merge t m h -> Entry v b -> Bool
shouldWriteEntry Merge t m h
m Entry v b
Delete = Bool -> Bool
not (Merge t m h -> Bool
forall t (m :: * -> *) h. Merge t m h -> Bool
mergeIsLastLevel Merge t m h
m)
shouldWriteEntry Merge t m h
_ Entry v b
_ = Bool
True