{-# LANGUAGE PatternSynonyms #-}
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
{-# OPTIONS_GHC -Wno-partial-fields #-}
module ScheduledMerges (
LSM,
LSMConfig (..),
Key (K), Value (V), resolveValue, Blob (B),
new,
newWith,
LookupResult (..),
lookup, lookups,
Op,
Update (..),
update, updates,
insert, inserts,
delete, deletes,
mupsert, mupserts,
supplyMergeCredits,
duplicate,
unions,
Credit,
Debt,
remainingUnionDebt,
supplyUnionCredits,
MTree (..),
logicalValue,
Representation,
dumpRepresentation,
representationShape,
Event,
EventAt(..),
EventDetail(..),
MergingTree(..),
MergingTreeState(..),
PendingMerge(..),
PreExistingRun(..),
MergingRun(..),
MergingRunState(..),
MergePolicy(..),
IsMergeType(..),
TreeMergeType(..),
LevelMergeType(..),
MergeCredit(..),
MergeDebt(..),
NominalCredit(..),
NominalDebt(..),
Run,
runSize,
UnionCredits (..),
supplyCreditsMergingTree,
UnionDebt(..),
remainingDebtMergingTree,
mergek,
mergeBatchSize,
Invariant,
evalInvariant,
treeInvariant,
mergeDebtInvariant,
levelNumberToMaxRunSize,
runSizeToLevelNumber,
maxWriteBufferSize,
runSizeFitsInLevel,
runSizeTooSmallForLevel,
runSizeTooLargeForLevel,
levelIsFull,
) where
import Prelude hiding (lookup)
import Data.Foldable (for_, toList, traverse_)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (catMaybes)
import Data.STRef
import qualified Control.Exception as Exc (assert)
import Control.Monad (foldM, forM, when)
import Control.Monad.ST
import qualified Control.Monad.Trans.Except as E
import Control.Tracer (Tracer, contramap, traceWith)
import GHC.Stack (HasCallStack, callStack)
import Text.Printf (printf)
import qualified Test.QuickCheck as QC
data LSM s = LSMHandle !(STRef s Counter)
!LSMConfig
!(STRef s (LSMContent s))
data LSMConfig = LSMConfig {
LSMConfig -> Credit
configMaxWriteBufferSize :: !Int
, LSMConfig -> Credit
configSizeRatio :: !Int
}
deriving stock (Credit -> LSMConfig -> ShowS
[LSMConfig] -> ShowS
LSMConfig -> String
(Credit -> LSMConfig -> ShowS)
-> (LSMConfig -> String)
-> ([LSMConfig] -> ShowS)
-> Show LSMConfig
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> LSMConfig -> ShowS
showsPrec :: Credit -> LSMConfig -> ShowS
$cshow :: LSMConfig -> String
show :: LSMConfig -> String
$cshowList :: [LSMConfig] -> ShowS
showList :: [LSMConfig] -> ShowS
Show, LSMConfig -> LSMConfig -> Bool
(LSMConfig -> LSMConfig -> Bool)
-> (LSMConfig -> LSMConfig -> Bool) -> Eq LSMConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LSMConfig -> LSMConfig -> Bool
== :: LSMConfig -> LSMConfig -> Bool
$c/= :: LSMConfig -> LSMConfig -> Bool
/= :: LSMConfig -> LSMConfig -> Bool
Eq)
type Counter = Int
data LSMContent s =
LSMContent
Buffer
(Levels s)
(UnionLevel s)
type Levels s = [Level s]
type LevelNo = Int
data Level s = Level !(IncomingRun s) ![Run]
data IncomingRun s = Merging !MergePolicy
!NominalDebt !(STRef s NominalCredit)
!(MergingRun LevelMergeType s)
| Single !Run
data MergePolicy = MergePolicyTiering | MergePolicyLevelling
deriving stock (MergePolicy -> MergePolicy -> Bool
(MergePolicy -> MergePolicy -> Bool)
-> (MergePolicy -> MergePolicy -> Bool) -> Eq MergePolicy
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MergePolicy -> MergePolicy -> Bool
== :: MergePolicy -> MergePolicy -> Bool
$c/= :: MergePolicy -> MergePolicy -> Bool
/= :: MergePolicy -> MergePolicy -> Bool
Eq, Credit -> MergePolicy -> ShowS
[MergePolicy] -> ShowS
MergePolicy -> String
(Credit -> MergePolicy -> ShowS)
-> (MergePolicy -> String)
-> ([MergePolicy] -> ShowS)
-> Show MergePolicy
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> MergePolicy -> ShowS
showsPrec :: Credit -> MergePolicy -> ShowS
$cshow :: MergePolicy -> String
show :: MergePolicy -> String
$cshowList :: [MergePolicy] -> ShowS
showList :: [MergePolicy] -> ShowS
Show)
data MergingRun t s = MergingRun !t !MergeDebt
!(STRef s MergingRunState)
data MergingRunState = CompletedMerge !Run
| OngoingMerge
!MergeCredit
![Run]
Run
class Show t => IsMergeType t where
isLastLevel :: t -> Bool
isUnion :: t -> Bool
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, Credit -> LevelMergeType -> ShowS
[LevelMergeType] -> ShowS
LevelMergeType -> String
(Credit -> LevelMergeType -> ShowS)
-> (LevelMergeType -> String)
-> ([LevelMergeType] -> ShowS)
-> Show LevelMergeType
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> LevelMergeType -> ShowS
showsPrec :: Credit -> LevelMergeType -> ShowS
$cshow :: LevelMergeType -> String
show :: LevelMergeType -> String
$cshowList :: [LevelMergeType] -> ShowS
showList :: [LevelMergeType] -> ShowS
Show)
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, Credit -> TreeMergeType -> ShowS
[TreeMergeType] -> ShowS
TreeMergeType -> String
(Credit -> TreeMergeType -> ShowS)
-> (TreeMergeType -> String)
-> ([TreeMergeType] -> ShowS)
-> Show TreeMergeType
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> TreeMergeType -> ShowS
showsPrec :: Credit -> TreeMergeType -> ShowS
$cshow :: TreeMergeType -> String
show :: TreeMergeType -> String
$cshowList :: [TreeMergeType] -> ShowS
showList :: [TreeMergeType] -> ShowS
Show)
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
data UnionLevel s = NoUnion
| Union !(MergingTree s) !(STRef s Debt)
newtype MergingTree s = MergingTree (STRef s (MergingTreeState s))
data MergingTreeState s = CompletedTreeMerge !Run
| OngoingTreeMerge !(MergingRun TreeMergeType s)
| PendingTreeMerge !(PendingMerge s)
data PendingMerge s =
PendingLevelMerge ![PreExistingRun s] !(Maybe (MergingTree s))
| PendingUnionMerge ![MergingTree s]
data PreExistingRun s = PreExistingRun !Run
| PreExistingMergingRun !(MergingRun LevelMergeType s)
pendingContent :: PendingMerge s
-> (TreeMergeType, [PreExistingRun s], [MergingTree s])
pendingContent :: forall s.
PendingMerge s
-> (TreeMergeType, [PreExistingRun s], [MergingTree s])
pendingContent = \case
PendingLevelMerge [PreExistingRun s]
prs Maybe (MergingTree s)
t -> (TreeMergeType
MergeLevel, [PreExistingRun s]
prs, Maybe (MergingTree s) -> [MergingTree s]
forall a. Maybe a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Maybe (MergingTree s)
t)
PendingUnionMerge [MergingTree s]
ts -> (TreeMergeType
MergeUnion, [], [MergingTree s]
ts)
{-# COMPLETE PendingMerge #-}
pattern PendingMerge :: TreeMergeType
-> [PreExistingRun s]
-> [MergingTree s]
-> PendingMerge s
pattern $mPendingMerge :: forall {r} {s}.
PendingMerge s
-> (TreeMergeType -> [PreExistingRun s] -> [MergingTree s] -> r)
-> ((# #) -> r)
-> r
PendingMerge mt prs ts <- (pendingContent -> (mt, prs, ts))
type Run = Map Key Op
type Buffer = Map Key Op
bufferToRun :: Buffer -> Run
bufferToRun :: Buffer -> Buffer
bufferToRun = Buffer -> Buffer
forall a. a -> a
id
runSize :: Run -> Int
runSize :: Buffer -> Credit
runSize = Buffer -> Credit
forall k a. Map k a -> Credit
Map.size
bufferSize :: Buffer -> Int
bufferSize :: Buffer -> Credit
bufferSize = Buffer -> Credit
forall k a. Map k a -> Credit
Map.size
type Op = Update Value Blob
newtype Key = K Int
deriving stock (Key -> Key -> Bool
(Key -> Key -> Bool) -> (Key -> Key -> Bool) -> Eq Key
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Key -> Key -> Bool
== :: Key -> Key -> Bool
$c/= :: Key -> Key -> Bool
/= :: Key -> Key -> Bool
Eq, Eq Key
Eq Key =>
(Key -> Key -> Ordering)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Key)
-> (Key -> Key -> Key)
-> Ord Key
Key -> Key -> Bool
Key -> Key -> Ordering
Key -> Key -> Key
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Key -> Key -> Ordering
compare :: Key -> Key -> Ordering
$c< :: Key -> Key -> Bool
< :: Key -> Key -> Bool
$c<= :: Key -> Key -> Bool
<= :: Key -> Key -> Bool
$c> :: Key -> Key -> Bool
> :: Key -> Key -> Bool
$c>= :: Key -> Key -> Bool
>= :: Key -> Key -> Bool
$cmax :: Key -> Key -> Key
max :: Key -> Key -> Key
$cmin :: Key -> Key -> Key
min :: Key -> Key -> Key
Ord, Credit -> Key -> ShowS
[Key] -> ShowS
Key -> String
(Credit -> Key -> ShowS)
-> (Key -> String) -> ([Key] -> ShowS) -> Show Key
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> Key -> ShowS
showsPrec :: Credit -> Key -> ShowS
$cshow :: Key -> String
show :: Key -> String
$cshowList :: [Key] -> ShowS
showList :: [Key] -> ShowS
Show)
deriving newtype Credit -> Key
Key -> Credit
Key -> [Key]
Key -> Key
Key -> Key -> [Key]
Key -> Key -> Key -> [Key]
(Key -> Key)
-> (Key -> Key)
-> (Credit -> Key)
-> (Key -> Credit)
-> (Key -> [Key])
-> (Key -> Key -> [Key])
-> (Key -> Key -> [Key])
-> (Key -> Key -> Key -> [Key])
-> Enum Key
forall a.
(a -> a)
-> (a -> a)
-> (Credit -> a)
-> (a -> Credit)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Key -> Key
succ :: Key -> Key
$cpred :: Key -> Key
pred :: Key -> Key
$ctoEnum :: Credit -> Key
toEnum :: Credit -> Key
$cfromEnum :: Key -> Credit
fromEnum :: Key -> Credit
$cenumFrom :: Key -> [Key]
enumFrom :: Key -> [Key]
$cenumFromThen :: Key -> Key -> [Key]
enumFromThen :: Key -> Key -> [Key]
$cenumFromTo :: Key -> Key -> [Key]
enumFromTo :: Key -> Key -> [Key]
$cenumFromThenTo :: Key -> Key -> Key -> [Key]
enumFromThenTo :: Key -> Key -> Key -> [Key]
Enum
newtype Value = V Int
deriving stock (Value -> Value -> Bool
(Value -> Value -> Bool) -> (Value -> Value -> Bool) -> Eq Value
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Value -> Value -> Bool
== :: Value -> Value -> Bool
$c/= :: Value -> Value -> Bool
/= :: Value -> Value -> Bool
Eq, Credit -> Value -> ShowS
[Value] -> ShowS
Value -> String
(Credit -> Value -> ShowS)
-> (Value -> String) -> ([Value] -> ShowS) -> Show Value
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> Value -> ShowS
showsPrec :: Credit -> Value -> ShowS
$cshow :: Value -> String
show :: Value -> String
$cshowList :: [Value] -> ShowS
showList :: [Value] -> ShowS
Show)
resolveValue :: Value -> Value -> Value
resolveValue :: Value -> Value -> Value
resolveValue (V Credit
x) (V Credit
y) = Credit -> Value
V (Credit
x Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
y)
newtype Blob = B Int
deriving stock (Blob -> Blob -> Bool
(Blob -> Blob -> Bool) -> (Blob -> Blob -> Bool) -> Eq Blob
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Blob -> Blob -> Bool
== :: Blob -> Blob -> Bool
$c/= :: Blob -> Blob -> Bool
/= :: Blob -> Blob -> Bool
Eq, Credit -> Blob -> ShowS
[Blob] -> ShowS
Blob -> String
(Credit -> Blob -> ShowS)
-> (Blob -> String) -> ([Blob] -> ShowS) -> Show Blob
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> Blob -> ShowS
showsPrec :: Credit -> Blob -> ShowS
$cshow :: Blob -> String
show :: Blob -> String
$cshowList :: [Blob] -> ShowS
showList :: [Blob] -> ShowS
Show)
mergePolicyForLevel :: Int -> [Level s] -> UnionLevel s -> MergePolicy
mergePolicyForLevel :: forall s. Credit -> [Level s] -> UnionLevel s -> MergePolicy
mergePolicyForLevel Credit
1 [Level s]
_ UnionLevel s
_ = MergePolicy
MergePolicyTiering
mergePolicyForLevel Credit
_ [] UnionLevel s
NoUnion = MergePolicy
MergePolicyLevelling
mergePolicyForLevel Credit
_ [Level s]
_ UnionLevel s
_ = MergePolicy
MergePolicyTiering
mergeTypeForLevel :: [Level s] -> UnionLevel s -> LevelMergeType
mergeTypeForLevel :: forall s. [Level s] -> UnionLevel s -> LevelMergeType
mergeTypeForLevel [] UnionLevel s
NoUnion = LevelMergeType
MergeLastLevel
mergeTypeForLevel [Level s]
_ UnionLevel s
_ = LevelMergeType
MergeMidLevel
invariant :: forall s. LSMConfig -> LSMContent s -> ST s ()
invariant :: forall s. LSMConfig -> LSMContent s -> ST s ()
invariant conf :: LSMConfig
conf@LSMConfig{Credit
configMaxWriteBufferSize :: LSMConfig -> Credit
configSizeRatio :: LSMConfig -> Credit
configMaxWriteBufferSize :: Credit
configSizeRatio :: Credit
..} (LSMContent Buffer
_ Levels s
levels UnionLevel s
ul) = do
Credit -> Levels s -> ST s ()
levelsInvariant Credit
1 Levels s
levels
case UnionLevel s
ul of
UnionLevel s
NoUnion -> () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Union MergingTree s
tree STRef s Credit
_ -> Invariant s () -> ST s ()
forall s a. HasCallStack => Invariant s a -> ST s a
expectInvariant (MergingTree s -> Invariant s ()
forall s. MergingTree s -> Invariant s ()
treeInvariant MergingTree s
tree)
where
levelsInvariant :: Int -> Levels s -> ST s ()
levelsInvariant :: Credit -> Levels s -> ST s ()
levelsInvariant !Credit
_ [] = () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
levelsInvariant !Credit
ln (Level IncomingRun s
ir [Buffer]
rs : Levels s
ls) = do
MergingRunState
mrs <- case IncomingRun s
ir of
Single Buffer
r ->
MergingRunState -> ST s MergingRunState
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Buffer -> MergingRunState
CompletedMerge Buffer
r)
Merging MergePolicy
mp NominalDebt
_ STRef s NominalCredit
_ (MergingRun LevelMergeType
mt MergeDebt
_ STRef s MergingRunState
ref) -> do
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ Credit
ln Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
1
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ MergePolicy
mp MergePolicy -> MergePolicy -> Bool
forall a. Eq a => a -> a -> Bool
== Credit -> Levels s -> UnionLevel s -> MergePolicy
forall s. Credit -> [Level s] -> UnionLevel s -> MergePolicy
mergePolicyForLevel Credit
ln Levels s
ls UnionLevel s
ul
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ LevelMergeType
mt LevelMergeType -> LevelMergeType -> Bool
forall a. Eq a => a -> a -> Bool
== Levels s -> UnionLevel s -> LevelMergeType
forall s. [Level s] -> UnionLevel s -> LevelMergeType
mergeTypeForLevel Levels s
ls UnionLevel s
ul
STRef s MergingRunState -> ST s MergingRunState
forall s a. STRef s a -> ST s a
readSTRef STRef s MergingRunState
ref
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ [Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
rs Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
configSizeRatio Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- Credit
1
Credit -> [Buffer] -> Levels s -> ST s ()
expectedRunLengths Credit
ln [Buffer]
rs Levels s
ls
Credit -> IncomingRun s -> MergingRunState -> Levels s -> ST s ()
expectedMergingRunLengths Credit
ln IncomingRun s
ir MergingRunState
mrs Levels s
ls
Credit -> Levels s -> ST s ()
levelsInvariant (Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1) Levels s
ls
expectedRunLengths :: Int -> [Run] -> [Level s] -> ST s ()
expectedRunLengths :: Credit -> [Buffer] -> Levels s -> ST s ()
expectedRunLengths Credit
ln [Buffer]
rs Levels s
ls =
case Credit -> Levels s -> UnionLevel s -> MergePolicy
forall s. Credit -> [Level s] -> UnionLevel s -> MergePolicy
mergePolicyForLevel Credit
ln Levels s
ls UnionLevel s
ul of
MergePolicy
MergePolicyLevelling -> Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ [Buffer] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Buffer]
rs
MergePolicy
MergePolicyTiering -> Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ (Buffer -> Bool) -> [Buffer] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\Buffer
r -> HasCallStack => MergePolicy -> LSMConfig -> Buffer -> Credit
MergePolicy -> LSMConfig -> Buffer -> Credit
runToLevelNumber MergePolicy
MergePolicyTiering LSMConfig
conf Buffer
r Credit -> [Credit] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Credit
ln, Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1]) [Buffer]
rs
expectedMergingRunLengths :: Int -> IncomingRun s -> MergingRunState
-> [Level s] -> ST s ()
expectedMergingRunLengths :: Credit -> IncomingRun s -> MergingRunState -> Levels s -> ST s ()
expectedMergingRunLengths Credit
ln IncomingRun s
ir MergingRunState
mrs Levels s
ls =
case Credit -> Levels s -> UnionLevel s -> MergePolicy
forall s. Credit -> [Level s] -> UnionLevel s -> MergePolicy
mergePolicyForLevel Credit
ln Levels s
ls UnionLevel s
ul of
MergePolicy
MergePolicyLevelling -> do
case (IncomingRun s
ir, MergingRunState
mrs) of
(Single Buffer
r, MergingRunState
m) -> do
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ case MergingRunState
m of CompletedMerge{} -> Bool
True
OngoingMerge{} -> Bool
False
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ HasCallStack => MergePolicy -> LSMConfig -> Buffer -> Credit
MergePolicy -> LSMConfig -> Buffer -> Credit
runToLevelNumber MergePolicy
MergePolicyLevelling LSMConfig
conf Buffer
r Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
ln
(IncomingRun s
_, CompletedMerge Buffer
r) ->
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ HasCallStack => MergePolicy -> LSMConfig -> Buffer -> Credit
MergePolicy -> LSMConfig -> Buffer -> Credit
runToLevelNumber MergePolicy
MergePolicyLevelling LSMConfig
conf Buffer
r Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1
(IncomingRun s
_, OngoingMerge MergeCredit
_ [Buffer]
rs Buffer
_) -> do
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ [Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
rs Credit -> [Credit] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Credit
configSizeRatio, Credit
configSizeRatio Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
1]
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ (Buffer -> Bool) -> [Buffer] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\Buffer
r -> Buffer -> Credit
runSize Buffer
r Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
0) [Buffer]
rs
let incoming :: [Buffer]
incoming = Credit -> [Buffer] -> [Buffer]
forall a. Credit -> [a] -> [a]
take Credit
configSizeRatio [Buffer]
rs
let resident :: [Buffer]
resident = Credit -> [Buffer] -> [Buffer]
forall a. Credit -> [a] -> [a]
drop Credit
configSizeRatio [Buffer]
rs
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ (Buffer -> Bool) -> [Buffer] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\Buffer
r -> HasCallStack => MergePolicy -> LSMConfig -> Buffer -> Credit
MergePolicy -> LSMConfig -> Buffer -> Credit
runToLevelNumber MergePolicy
MergePolicyTiering LSMConfig
conf Buffer
r Credit -> [Credit] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
-Credit
1, Credit
ln]) [Buffer]
incoming
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ (Buffer -> Bool) -> [Buffer] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\Buffer
r -> HasCallStack => MergePolicy -> LSMConfig -> Buffer -> Credit
MergePolicy -> LSMConfig -> Buffer -> Credit
runToLevelNumber MergePolicy
MergePolicyLevelling LSMConfig
conf Buffer
r Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1) [Buffer]
resident
MergePolicy
MergePolicyTiering ->
case (IncomingRun s
ir, MergingRunState
mrs, Levels s -> UnionLevel s -> LevelMergeType
forall s. [Level s] -> UnionLevel s -> LevelMergeType
mergeTypeForLevel Levels s
ls UnionLevel s
ul) of
(Single Buffer
r, MergingRunState
m, LevelMergeType
_) -> do
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ case MergingRunState
m of CompletedMerge{} -> Bool
True
OngoingMerge{} -> Bool
False
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ HasCallStack => MergePolicy -> LSMConfig -> Buffer -> Credit
MergePolicy -> LSMConfig -> Buffer -> Credit
runToLevelNumber MergePolicy
MergePolicyTiering LSMConfig
conf Buffer
r Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
ln
(IncomingRun s
_, CompletedMerge Buffer
r, LevelMergeType
MergeLastLevel) -> do
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ Credit
ln Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
1
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ HasCallStack => MergePolicy -> LSMConfig -> Buffer -> Credit
MergePolicy -> LSMConfig -> Buffer -> Credit
runToLevelNumber MergePolicy
MergePolicyTiering LSMConfig
conf Buffer
r Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1
(IncomingRun s
_, CompletedMerge Buffer
r, LevelMergeType
MergeMidLevel) ->
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ HasCallStack => MergePolicy -> LSMConfig -> Buffer -> Credit
MergePolicy -> LSMConfig -> Buffer -> Credit
runToLevelNumber MergePolicy
MergePolicyTiering LSMConfig
conf Buffer
r Credit -> [Credit] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
-Credit
1, Credit
ln, Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1]
(IncomingRun s
_, OngoingMerge MergeCredit
_ [Buffer]
rs Buffer
_, LevelMergeType
_) -> do
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ [Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
rs Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
configSizeRatio Bool -> Bool -> Bool
|| [Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
rs Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
configSizeRatio Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
1
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ (Buffer -> Bool) -> [Buffer] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\Buffer
r -> HasCallStack => MergePolicy -> LSMConfig -> Buffer -> Credit
MergePolicy -> LSMConfig -> Buffer -> Credit
runToLevelNumber MergePolicy
MergePolicyTiering LSMConfig
conf Buffer
r Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
-Credit
1) [Buffer]
rs
treeInvariant :: MergingTree s -> Invariant s ()
treeInvariant :: forall s. MergingTree s -> Invariant s ()
treeInvariant tree :: MergingTree s
tree@(MergingTree STRef s (MergingTreeState s)
treeState) = do
ST s (MergingTreeState s) -> Invariant s (MergingTreeState s)
forall s a. ST s a -> Invariant s a
liftI (STRef s (MergingTreeState s) -> ST s (MergingTreeState s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (MergingTreeState s)
treeState) Invariant s (MergingTreeState s)
-> (MergingTreeState s -> Invariant s ()) -> Invariant s ()
forall a b.
ExceptT String (ST s) a
-> (a -> ExceptT String (ST s) b) -> ExceptT String (ST s) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
CompletedTreeMerge Buffer
_ ->
() -> Invariant s ()
forall a. a -> ExceptT String (ST s) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
OngoingTreeMerge MergingRun TreeMergeType s
mr ->
MergingRun TreeMergeType s -> Invariant s ()
forall t s. MergingRun t s -> Invariant s ()
mergeInvariant MergingRun TreeMergeType s
mr
PendingTreeMerge (PendingLevelMerge [PreExistingRun s]
prs Maybe (MergingTree s)
t) -> do
String -> Bool -> Invariant s ()
forall s. String -> Bool -> Invariant s ()
assertI String
"pending level merges have at least one input" (Bool -> Invariant s ()) -> Bool -> Invariant s ()
forall a b. (a -> b) -> a -> b
$
[PreExistingRun s] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [PreExistingRun s]
prs Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Maybe (MergingTree s) -> Credit
forall a. Maybe a -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length Maybe (MergingTree s)
t Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
0
[PreExistingRun s]
-> (PreExistingRun s -> Invariant s ()) -> Invariant s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [PreExistingRun s]
prs ((PreExistingRun s -> Invariant s ()) -> Invariant s ())
-> (PreExistingRun s -> Invariant s ()) -> Invariant s ()
forall a b. (a -> b) -> a -> b
$ \case
PreExistingRun Buffer
_r -> () -> Invariant s ()
forall a. a -> ExceptT String (ST s) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
PreExistingMergingRun MergingRun LevelMergeType s
mr -> MergingRun LevelMergeType s -> Invariant s ()
forall t s. MergingRun t s -> Invariant s ()
mergeInvariant MergingRun LevelMergeType s
mr
Maybe (MergingTree s)
-> (MergingTree s -> Invariant s ()) -> Invariant s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Maybe (MergingTree s)
t MergingTree s -> Invariant s ()
forall s. MergingTree s -> Invariant s ()
treeInvariant
PendingTreeMerge (PendingUnionMerge [MergingTree s]
ts) -> do
String -> Bool -> Invariant s ()
forall s. String -> Bool -> Invariant s ()
assertI String
"pending union merges are non-trivial (at least two inputs)" (Bool -> Invariant s ()) -> Bool -> Invariant s ()
forall a b. (a -> b) -> a -> b
$
[MergingTree s] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [MergingTree s]
ts Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
1
[MergingTree s]
-> (MergingTree s -> Invariant s ()) -> Invariant s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [MergingTree s]
ts MergingTree s -> Invariant s ()
forall s. MergingTree s -> Invariant s ()
treeInvariant
(Credit
debt, Credit
_) <- ST s (Credit, Credit) -> Invariant s (Credit, Credit)
forall s a. ST s a -> Invariant s a
liftI (ST s (Credit, Credit) -> Invariant s (Credit, Credit))
-> ST s (Credit, Credit) -> Invariant s (Credit, Credit)
forall a b. (a -> b) -> a -> b
$ MergingTree s -> ST s (Credit, Credit)
forall s. MergingTree s -> ST s (Credit, Credit)
remainingDebtMergingTree MergingTree s
tree
Bool -> Invariant s () -> Invariant s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Credit
debt Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
0) (Invariant s () -> Invariant s ())
-> Invariant s () -> Invariant s ()
forall a b. (a -> b) -> a -> b
$ do
Buffer
_ <- MergingTree s -> Invariant s Buffer
forall s. MergingTree s -> Invariant s Buffer
isCompletedMergingTree MergingTree s
tree
() -> Invariant s ()
forall a. a -> ExceptT String (ST s) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
mergeInvariant :: MergingRun t s -> Invariant s ()
mergeInvariant :: forall t s. MergingRun t s -> Invariant s ()
mergeInvariant (MergingRun t
_ MergeDebt
mergeDebt STRef s MergingRunState
ref) =
ST s MergingRunState -> Invariant s MergingRunState
forall s a. ST s a -> Invariant s a
liftI (STRef s MergingRunState -> ST s MergingRunState
forall s a. STRef s a -> ST s a
readSTRef STRef s MergingRunState
ref) Invariant s MergingRunState
-> (MergingRunState -> ExceptT String (ST s) ())
-> ExceptT String (ST s) ()
forall a b.
ExceptT String (ST s) a
-> (a -> ExceptT String (ST s) b) -> ExceptT String (ST s) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
CompletedMerge Buffer
_ -> () -> ExceptT String (ST s) ()
forall a. a -> ExceptT String (ST s) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
OngoingMerge MergeCredit
mergeCredit [Buffer]
rs Buffer
_ -> do
String -> Bool -> ExceptT String (ST s) ()
forall s. String -> Bool -> Invariant s ()
assertI String
"merge debt & credit invariant" (Bool -> ExceptT String (ST s) ())
-> Bool -> ExceptT String (ST s) ()
forall a b. (a -> b) -> a -> b
$
MergeDebt -> MergeCredit -> Bool
mergeDebtInvariant MergeDebt
mergeDebt MergeCredit
mergeCredit
String -> Bool -> ExceptT String (ST s) ()
forall s. String -> Bool -> Invariant s ()
assertI String
"inputs to ongoing merges aren't empty" (Bool -> ExceptT String (ST s) ())
-> Bool -> ExceptT String (ST s) ()
forall a b. (a -> b) -> a -> b
$
(Buffer -> Bool) -> [Buffer] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\Buffer
r -> Buffer -> Credit
runSize Buffer
r Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
0) [Buffer]
rs
String -> Bool -> ExceptT String (ST s) ()
forall s. String -> Bool -> Invariant s ()
assertI String
"ongoing merges are non-trivial (at least two inputs)" (Bool -> ExceptT String (ST s) ())
-> Bool -> ExceptT String (ST s) ()
forall a b. (a -> b) -> a -> b
$
[Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
rs Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
1
isCompletedMergingRun :: MergingRun t s -> Invariant s Run
isCompletedMergingRun :: forall t s. MergingRun t s -> Invariant s Buffer
isCompletedMergingRun (MergingRun t
_ MergeDebt
d STRef s MergingRunState
ref) = do
MergingRunState
mrs <- ST s MergingRunState -> Invariant s MergingRunState
forall s a. ST s a -> Invariant s a
liftI (ST s MergingRunState -> Invariant s MergingRunState)
-> ST s MergingRunState -> Invariant s MergingRunState
forall a b. (a -> b) -> a -> b
$ STRef s MergingRunState -> ST s MergingRunState
forall s a. STRef s a -> ST s a
readSTRef STRef s MergingRunState
ref
case MergingRunState
mrs of
CompletedMerge Buffer
r -> Buffer -> Invariant s Buffer
forall a. a -> ExceptT String (ST s) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Buffer
r
OngoingMerge MergeCredit
c [Buffer]
_ Buffer
_ -> String -> Invariant s Buffer
forall s a. String -> Invariant s a
failI (String -> Invariant s Buffer) -> String -> Invariant s Buffer
forall a b. (a -> b) -> a -> b
$ String
"not completed: OngoingMerge with"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" remaining debt "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ Credit -> String
forall a. Show a => a -> String
show (HasCallStack => MergeDebt -> MergeCredit -> Credit
MergeDebt -> MergeCredit -> Credit
mergeDebtLeft MergeDebt
d MergeCredit
c)
isCompletedMergingTree :: MergingTree s -> Invariant s Run
isCompletedMergingTree :: forall s. MergingTree s -> Invariant s Buffer
isCompletedMergingTree (MergingTree STRef s (MergingTreeState s)
ref) = do
MergingTreeState s
mts <- ST s (MergingTreeState s) -> Invariant s (MergingTreeState s)
forall s a. ST s a -> Invariant s a
liftI (ST s (MergingTreeState s) -> Invariant s (MergingTreeState s))
-> ST s (MergingTreeState s) -> Invariant s (MergingTreeState s)
forall a b. (a -> b) -> a -> b
$ STRef s (MergingTreeState s) -> ST s (MergingTreeState s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (MergingTreeState s)
ref
case MergingTreeState s
mts of
CompletedTreeMerge Buffer
r -> Buffer -> Invariant s Buffer
forall a. a -> ExceptT String (ST s) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Buffer
r
OngoingTreeMerge MergingRun TreeMergeType s
mr -> MergingRun TreeMergeType s -> Invariant s Buffer
forall t s. MergingRun t s -> Invariant s Buffer
isCompletedMergingRun MergingRun TreeMergeType s
mr
PendingTreeMerge PendingMerge s
_ -> String -> Invariant s Buffer
forall s a. String -> Invariant s a
failI (String -> Invariant s Buffer) -> String -> Invariant s Buffer
forall a b. (a -> b) -> a -> b
$ String
"not completed: PendingTreeMerge"
type Invariant s = E.ExceptT String (ST s)
assertI :: String -> Bool -> Invariant s ()
assertI :: forall s. String -> Bool -> Invariant s ()
assertI String
_ Bool
True = () -> ExceptT String (ST s) ()
forall a. a -> ExceptT String (ST s) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
assertI String
e Bool
False = String -> ExceptT String (ST s) ()
forall s a. String -> Invariant s a
failI String
e
failI :: String -> Invariant s a
failI :: forall s a. String -> Invariant s a
failI = String -> ExceptT String (ST s) a
forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
E.throwE
liftI :: ST s a -> Invariant s a
liftI :: forall s a. ST s a -> Invariant s a
liftI = ST s (Either String a) -> ExceptT String (ST s) a
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
E.ExceptT (ST s (Either String a) -> ExceptT String (ST s) a)
-> (ST s a -> ST s (Either String a))
-> ST s a
-> ExceptT String (ST s) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Either String a) -> ST s a -> ST s (Either String a)
forall a b. (a -> b) -> ST s a -> ST s b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Either String a
forall a b. b -> Either a b
Right
expectInvariant :: HasCallStack => Invariant s a -> ST s a
expectInvariant :: forall s a. HasCallStack => Invariant s a -> ST s a
expectInvariant Invariant s a
act = Invariant s a -> ST s (Either String a)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
E.runExceptT Invariant s a
act ST s (Either String a) -> (Either String a -> ST s a) -> ST s a
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (String -> ST s a) -> (a -> ST s a) -> Either String a -> ST s a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> ST s a
forall a. HasCallStack => String -> a
error a -> ST s a
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
evalInvariant :: Invariant s a -> ST s (Either String a)
evalInvariant :: forall s a. Invariant s a -> ST s (Either String a)
evalInvariant = ExceptT String (ST s) a -> ST s (Either String a)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
E.runExceptT
assert :: HasCallStack => Bool -> a -> a
assert :: forall a. HasCallStack => Bool -> a -> a
assert Bool
p a
x = Bool -> a -> a
forall a. HasCallStack => Bool -> a -> a
Exc.assert Bool
p (a -> CallStack -> a
forall a b. a -> b -> a
const a
x CallStack
HasCallStack => CallStack
callStack)
assertST :: HasCallStack => Bool -> ST s ()
assertST :: forall s. HasCallStack => Bool -> ST s ()
assertST Bool
p = Bool -> ST s () -> ST s ()
forall a. HasCallStack => Bool -> a -> a
assert Bool
p (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
levelNumberToMaxRunSize :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Int
levelNumberToMaxRunSize :: HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize = \case
MergePolicy
MergePolicyTiering -> HasCallStack => LSMConfig -> Credit -> Credit
LSMConfig -> Credit -> Credit
levelNumberToMaxRunSizeTiering
MergePolicy
MergePolicyLevelling -> HasCallStack => LSMConfig -> Credit -> Credit
LSMConfig -> Credit -> Credit
levelNumberToMaxRunSizeLevelling
levelNumberToMaxRunSizeTiering :: HasCallStack => LSMConfig -> LevelNo -> Int
levelNumberToMaxRunSizeTiering :: HasCallStack => LSMConfig -> Credit -> Credit
levelNumberToMaxRunSizeTiering
LSMConfig {configMaxWriteBufferSize :: LSMConfig -> Credit
configMaxWriteBufferSize = Credit
bufSize, configSizeRatio :: LSMConfig -> Credit
configSizeRatio = Credit
sizeRatio}
Credit
ln
| Credit
ln Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
< Credit
0 = String -> Credit
forall a. HasCallStack => String -> a
error String
"level number must be non-negative"
| Credit
ln Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
0 = Credit
0
| Bool
otherwise = Integer -> Credit
forall a. (HasCallStack, Integral a) => Integer -> a
fromIntegerChecked (Credit -> Integer
forall a. Integral a => a -> Integer
toInteger Credit
bufSize Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Credit -> Integer
forall a. Integral a => a -> Integer
toInteger Credit
sizeRatio Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer -> Integer
forall a. Enum a => a -> a
pred (Credit -> Integer
forall a. Integral a => a -> Integer
toInteger Credit
ln))
levelNumberToMaxRunSizeLevelling :: HasCallStack => LSMConfig -> LevelNo -> Int
levelNumberToMaxRunSizeLevelling :: HasCallStack => LSMConfig -> Credit -> Credit
levelNumberToMaxRunSizeLevelling LSMConfig
conf Credit
ln
| Credit
ln Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
< Credit
0 = String -> Credit
forall a. HasCallStack => String -> a
error String
"level number must be non-negative"
| Credit
ln Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
0 = Credit
0
| Bool
otherwise = HasCallStack => LSMConfig -> Credit -> Credit
LSMConfig -> Credit -> Credit
levelNumberToMaxRunSizeTiering LSMConfig
conf (Credit -> Credit
forall a. Enum a => a -> a
succ Credit
ln)
runToLevelNumber :: HasCallStack => MergePolicy -> LSMConfig -> Run -> LevelNo
runToLevelNumber :: HasCallStack => MergePolicy -> LSMConfig -> Buffer -> Credit
runToLevelNumber MergePolicy
mpl LSMConfig
conf Buffer
run = HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
runSizeToLevelNumber MergePolicy
mpl LSMConfig
conf (Buffer -> Credit
runSize Buffer
run)
runSizeToLevelNumber :: HasCallStack => MergePolicy -> LSMConfig -> Int -> LevelNo
runSizeToLevelNumber :: HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
runSizeToLevelNumber = \case
MergePolicy
MergePolicyTiering -> HasCallStack => LSMConfig -> Credit -> Credit
LSMConfig -> Credit -> Credit
runSizeToLevelNumberTiering
MergePolicy
MergePolicyLevelling -> HasCallStack => LSMConfig -> Credit -> Credit
LSMConfig -> Credit -> Credit
runSizeToLevelNumberLevelling
runSizeToLevelNumberTiering :: HasCallStack => LSMConfig -> Int -> LevelNo
runSizeToLevelNumberTiering :: HasCallStack => LSMConfig -> Credit -> Credit
runSizeToLevelNumberTiering LSMConfig
conf Credit
n
| Credit
n Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
< Credit
0 = String -> Credit
forall a. HasCallStack => String -> a
error String
"run size must be positive"
| Bool
otherwise = [Credit] -> Credit
forall a. HasCallStack => [a] -> a
head ([Credit] -> Credit) -> [Credit] -> Credit
forall a b. (a -> b) -> a -> b
$
[ Credit
ln
| Credit
ln <- [Credit
0..]
, Credit
n Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= HasCallStack => LSMConfig -> Credit -> Credit
LSMConfig -> Credit -> Credit
levelNumberToMaxRunSizeTiering LSMConfig
conf Credit
ln
]
runSizeToLevelNumberLevelling :: HasCallStack => LSMConfig -> Int -> LevelNo
runSizeToLevelNumberLevelling :: HasCallStack => LSMConfig -> Credit -> Credit
runSizeToLevelNumberLevelling LSMConfig
conf Credit
n
| Credit
n Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
< Credit
0 = String -> Credit
forall a. HasCallStack => String -> a
error String
"run size must be positive"
| Bool
otherwise = [Credit] -> Credit
forall a. HasCallStack => [a] -> a
head ([Credit] -> Credit) -> [Credit] -> Credit
forall a b. (a -> b) -> a -> b
$
[ Credit
ln
| Credit
ln <- [Credit
0..]
, Credit
n Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= HasCallStack => LSMConfig -> Credit -> Credit
LSMConfig -> Credit -> Credit
levelNumberToMaxRunSizeLevelling LSMConfig
conf Credit
ln
]
maxWriteBufferSize :: HasCallStack => LSMConfig -> Int
maxWriteBufferSize :: HasCallStack => LSMConfig -> Credit
maxWriteBufferSize LSMConfig
conf = HasCallStack => LSMConfig -> Credit -> Credit
LSMConfig -> Credit -> Credit
levelNumberToMaxRunSizeTiering LSMConfig
conf Credit
1
{-# INLINABLE fromIntegerChecked #-}
fromIntegerChecked :: (HasCallStack, Integral a) => Integer -> a
fromIntegerChecked :: forall a. (HasCallStack, Integral a) => Integer -> a
fromIntegerChecked Integer
x
| Integer
x'' Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
x
= a
x'
| Bool
otherwise
= String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String -> String -> ShowS
forall r. PrintfType r => String -> r
printf String
"fromIntegerChecked: conversion failed, %s /= %s" (Integer -> String
forall a. Show a => a -> String
show Integer
x) (Integer -> String
forall a. Show a => a -> String
show Integer
x'')
where
x' :: a
x' = Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
x
x'' :: Integer
x'' = a -> Integer
forall a. Integral a => a -> Integer
toInteger a
x'
_runFitsInLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Run -> Bool
_runFitsInLevel :: HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Buffer -> Bool
_runFitsInLevel MergePolicy
mpl LSMConfig
conf Credit
ln Buffer
r = HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Credit -> Bool
MergePolicy -> LSMConfig -> Credit -> Credit -> Bool
runSizeFitsInLevel MergePolicy
mpl LSMConfig
conf Credit
ln (Buffer -> Credit
runSize Buffer
r)
runSizeFitsInLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Int -> Bool
runSizeFitsInLevel :: HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Credit -> Bool
runSizeFitsInLevel MergePolicy
mpl LSMConfig
conf Credit
ln Credit
n
| Credit
ln Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
< Credit
0 = String -> Bool
forall a. HasCallStack => String -> a
error String
"level number must be non-negative"
| Credit
ln Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
0 = Credit
n Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
0
| Bool
otherwise =
HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize MergePolicy
mpl LSMConfig
conf (Credit -> Credit
forall a. Enum a => a -> a
pred Credit
ln) Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
< Credit
n
Bool -> Bool -> Bool
&& Credit
n Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize MergePolicy
mpl LSMConfig
conf Credit
ln
runTooSmallForLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Run -> Bool
runTooSmallForLevel :: HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Buffer -> Bool
runTooSmallForLevel MergePolicy
mpl LSMConfig
conf Credit
ln Buffer
r = HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Credit -> Bool
MergePolicy -> LSMConfig -> Credit -> Credit -> Bool
runSizeTooSmallForLevel MergePolicy
mpl LSMConfig
conf Credit
ln (Buffer -> Credit
runSize Buffer
r)
runSizeTooSmallForLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Int -> Bool
runSizeTooSmallForLevel :: HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Credit -> Bool
runSizeTooSmallForLevel MergePolicy
mpl LSMConfig
conf Credit
ln Credit
n
| Credit
ln Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
< Credit
0 = String -> Bool
forall a. HasCallStack => String -> a
error String
"level number must be non-negative"
| Credit
ln Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
0 = Bool
False
| Bool
otherwise = case MergePolicy
mpl of
MergePolicy
MergePolicyTiering ->
Credit
n Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize MergePolicy
MergePolicyTiering LSMConfig
conf (Credit -> Credit
forall a. Enum a => a -> a
pred Credit
ln)
MergePolicy
MergePolicyLevelling ->
Credit
n Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize MergePolicy
MergePolicyLevelling LSMConfig
conf (Credit -> Credit
forall a. Enum a => a -> a
pred Credit
ln)
runTooLargeForLevel :: HasCallStack =>MergePolicy -> LSMConfig -> LevelNo -> Run -> Bool
runTooLargeForLevel :: HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Buffer -> Bool
runTooLargeForLevel MergePolicy
mpl LSMConfig
conf Credit
ln Buffer
r = HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Credit -> Bool
MergePolicy -> LSMConfig -> Credit -> Credit -> Bool
runSizeTooLargeForLevel MergePolicy
mpl LSMConfig
conf Credit
ln (Buffer -> Credit
runSize Buffer
r)
runSizeTooLargeForLevel :: HasCallStack => MergePolicy -> LSMConfig -> LevelNo -> Int -> Bool
runSizeTooLargeForLevel :: HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Credit -> Bool
runSizeTooLargeForLevel MergePolicy
mpl LSMConfig
conf Credit
ln Credit
n
| Credit
ln Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
< Credit
0 = String -> Bool
forall a. HasCallStack => String -> a
error String
"level number must be non-negative"
| Credit
ln Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
0 = Bool -> Bool
not (Credit
n Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
0)
| Bool
otherwise = case MergePolicy
mpl of
MergePolicy
MergePolicyTiering ->
Credit
n Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize MergePolicy
MergePolicyTiering LSMConfig
conf Credit
ln
MergePolicy
MergePolicyLevelling ->
Credit
n Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize MergePolicy
MergePolicyLevelling LSMConfig
conf Credit
ln
levelIsFull :: MergePolicy -> LSMConfig -> LevelNo -> [Run] -> [Run] -> Bool
levelIsFull :: MergePolicy -> LSMConfig -> Credit -> [Buffer] -> [Buffer] -> Bool
levelIsFull MergePolicy
mpl LSMConfig
conf Credit
ln [Buffer]
incoming [Buffer]
resident = case MergePolicy
mpl of
MergePolicy
MergePolicyTiering -> LSMConfig -> Credit -> [Buffer] -> [Buffer] -> Bool
levelIsFullTiering LSMConfig
conf Credit
ln [Buffer]
incoming [Buffer]
resident
MergePolicy
MergePolicyLevelling ->
Bool -> Bool -> Bool
forall a. HasCallStack => Bool -> a -> a
assert ([Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
resident Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
1) (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$
LSMConfig -> Credit -> [Buffer] -> Buffer -> Bool
levelIsFullLevelling LSMConfig
conf Credit
ln [Buffer]
incoming ([Buffer] -> Buffer
forall a. HasCallStack => [a] -> a
head [Buffer]
resident)
levelIsFullTiering :: LSMConfig -> LevelNo -> [Run] -> [Run] -> Bool
levelIsFullTiering :: LSMConfig -> Credit -> [Buffer] -> [Buffer] -> Bool
levelIsFullTiering LSMConfig{Credit
configMaxWriteBufferSize :: LSMConfig -> Credit
configSizeRatio :: LSMConfig -> Credit
configMaxWriteBufferSize :: Credit
configSizeRatio :: Credit
..} Credit
_ln [Buffer]
_incoming [Buffer]
resident =
[Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
resident Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
configSizeRatio
levelIsFullLevelling :: LSMConfig -> LevelNo -> [Run] -> Run -> Bool
levelIsFullLevelling :: LSMConfig -> Credit -> [Buffer] -> Buffer -> Bool
levelIsFullLevelling LSMConfig
conf Credit
ln [Buffer]
_incoming Buffer
resident =
HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Buffer -> Bool
MergePolicy -> LSMConfig -> Credit -> Buffer -> Bool
runTooLargeForLevel MergePolicy
MergePolicyLevelling LSMConfig
conf Credit
ln Buffer
resident
type Credit = Int
type Debt = Int
data MergeCredit =
MergeCredit {
MergeCredit -> Credit
spentCredits :: !Credit,
MergeCredit -> Credit
unspentCredits :: !Credit
}
deriving stock Credit -> MergeCredit -> ShowS
[MergeCredit] -> ShowS
MergeCredit -> String
(Credit -> MergeCredit -> ShowS)
-> (MergeCredit -> String)
-> ([MergeCredit] -> ShowS)
-> Show MergeCredit
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> MergeCredit -> ShowS
showsPrec :: Credit -> MergeCredit -> ShowS
$cshow :: MergeCredit -> String
show :: MergeCredit -> String
$cshowList :: [MergeCredit] -> ShowS
showList :: [MergeCredit] -> ShowS
Show
newtype MergeDebt =
MergeDebt {
MergeDebt -> Credit
totalDebt :: Debt
}
deriving stock Credit -> MergeDebt -> ShowS
[MergeDebt] -> ShowS
MergeDebt -> String
(Credit -> MergeDebt -> ShowS)
-> (MergeDebt -> String)
-> ([MergeDebt] -> ShowS)
-> Show MergeDebt
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> MergeDebt -> ShowS
showsPrec :: Credit -> MergeDebt -> ShowS
$cshow :: MergeDebt -> String
show :: MergeDebt -> String
$cshowList :: [MergeDebt] -> ShowS
showList :: [MergeDebt] -> ShowS
Show
zeroMergeCredit :: MergeCredit
zeroMergeCredit :: MergeCredit
zeroMergeCredit =
MergeCredit {
spentCredits :: Credit
spentCredits = Credit
0,
unspentCredits :: Credit
unspentCredits = Credit
0
}
mergeDebtInvariant :: MergeDebt -> MergeCredit -> Bool
mergeDebtInvariant :: MergeDebt -> MergeCredit -> Bool
mergeDebtInvariant MergeDebt {Credit
totalDebt :: MergeDebt -> Credit
totalDebt :: Credit
totalDebt}
MergeCredit {Credit
spentCredits :: MergeCredit -> Credit
spentCredits :: Credit
spentCredits, Credit
unspentCredits :: MergeCredit -> Credit
unspentCredits :: Credit
unspentCredits} =
let suppliedCredits :: Credit
suppliedCredits = Credit
spentCredits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
unspentCredits
in Credit
spentCredits Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0
Bool -> Bool -> Bool
&& Credit
suppliedCredits Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0
Bool -> Bool -> Bool
&& Credit
suppliedCredits Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
totalDebt
mergeDebtLeft :: HasCallStack => MergeDebt -> MergeCredit -> Debt
mergeDebtLeft :: HasCallStack => MergeDebt -> MergeCredit -> Credit
mergeDebtLeft MergeDebt {Credit
totalDebt :: MergeDebt -> Credit
totalDebt :: Credit
totalDebt}
MergeCredit {Credit
spentCredits :: MergeCredit -> Credit
spentCredits :: Credit
spentCredits, Credit
unspentCredits :: MergeCredit -> Credit
unspentCredits :: Credit
unspentCredits} =
let suppliedCredits :: Credit
suppliedCredits = Credit
spentCredits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
unspentCredits
in Bool -> Credit -> Credit
forall a. HasCallStack => Bool -> a -> a
assert (Credit
suppliedCredits Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
totalDebt)
(Credit
totalDebt Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- Credit
suppliedCredits)
data MergeDebtPaydown =
MergeDebtDischarged !Debt !Credit
| MergeDebtPaydownCredited !MergeCredit
| MergeDebtPaydownPerform !Debt !MergeCredit
deriving stock Credit -> MergeDebtPaydown -> ShowS
[MergeDebtPaydown] -> ShowS
MergeDebtPaydown -> String
(Credit -> MergeDebtPaydown -> ShowS)
-> (MergeDebtPaydown -> String)
-> ([MergeDebtPaydown] -> ShowS)
-> Show MergeDebtPaydown
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> MergeDebtPaydown -> ShowS
showsPrec :: Credit -> MergeDebtPaydown -> ShowS
$cshow :: MergeDebtPaydown -> String
show :: MergeDebtPaydown -> String
$cshowList :: [MergeDebtPaydown] -> ShowS
showList :: [MergeDebtPaydown] -> ShowS
Show
paydownMergeDebt :: MergeDebt -> MergeCredit -> Credit -> MergeDebtPaydown
paydownMergeDebt :: MergeDebt -> MergeCredit -> Credit -> MergeDebtPaydown
paydownMergeDebt MergeDebt {Credit
totalDebt :: MergeDebt -> Credit
totalDebt :: Credit
totalDebt}
MergeCredit {Credit
spentCredits :: MergeCredit -> Credit
spentCredits :: Credit
spentCredits, Credit
unspentCredits :: MergeCredit -> Credit
unspentCredits :: Credit
unspentCredits}
Credit
c
| Credit
suppliedCredits' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
totalDebt
, let !leftover :: Credit
leftover = Credit
suppliedCredits' Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- Credit
totalDebt
!perform :: Credit
perform = Credit
c Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- Credit
leftover
= Bool -> MergeDebtPaydown -> MergeDebtPaydown
forall a. HasCallStack => Bool -> a -> a
assert (Credit -> Credit -> Bool
dischargePostcondition Credit
perform Credit
leftover) (MergeDebtPaydown -> MergeDebtPaydown)
-> MergeDebtPaydown -> MergeDebtPaydown
forall a b. (a -> b) -> a -> b
$
Credit -> Credit -> MergeDebtPaydown
MergeDebtDischarged Credit
perform Credit
leftover
| Credit
unspentCredits' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
mergeBatchSize
, let (!Credit
b, !Credit
r) = Credit -> Credit -> (Credit, Credit)
forall a. Integral a => a -> a -> (a, a)
divMod Credit
unspentCredits' Credit
mergeBatchSize
!perform :: Credit
perform = Credit
b Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
* Credit
mergeBatchSize
= Bool -> MergeDebtPaydown -> MergeDebtPaydown
forall a. HasCallStack => Bool -> a -> a
assert (Credit -> Credit -> Bool
performPostcondition Credit
perform Credit
r) (MergeDebtPaydown -> MergeDebtPaydown)
-> MergeDebtPaydown -> MergeDebtPaydown
forall a b. (a -> b) -> a -> b
$
Credit -> MergeCredit -> MergeDebtPaydown
MergeDebtPaydownPerform
Credit
perform
MergeCredit {
spentCredits :: Credit
spentCredits = Credit
spentCredits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
perform,
unspentCredits :: Credit
unspentCredits = Credit
unspentCredits' Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- Credit
perform
}
| Bool
otherwise
= Bool -> MergeDebtPaydown -> MergeDebtPaydown
forall a. HasCallStack => Bool -> a -> a
assert Bool
creditedPostcondition (MergeDebtPaydown -> MergeDebtPaydown)
-> MergeDebtPaydown -> MergeDebtPaydown
forall a b. (a -> b) -> a -> b
$
MergeCredit -> MergeDebtPaydown
MergeDebtPaydownCredited
MergeCredit {
Credit
spentCredits :: Credit
spentCredits :: Credit
spentCredits,
unspentCredits :: Credit
unspentCredits = Credit
unspentCredits'
}
where
suppliedCredits' :: Credit
suppliedCredits' = Credit
spentCredits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
unspentCredits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
c
unspentCredits' :: Credit
unspentCredits' = Credit
unspentCredits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
c
dischargePostcondition :: Credit -> Credit -> Bool
dischargePostcondition Credit
perform Credit
leftover =
(Credit
c Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0)
Bool -> Bool -> Bool
&& (Credit
perform Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0 Bool -> Bool -> Bool
&& Credit
leftover Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0)
Bool -> Bool -> Bool
&& (Credit
c Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
perform Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
leftover)
Bool -> Bool -> Bool
&& (Credit
spentCredits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
unspentCredits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
perform Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
totalDebt)
performPostcondition :: Credit -> Credit -> Bool
performPostcondition Credit
perform Credit
r =
let spentCredits' :: Credit
spentCredits' = Credit
spentCredits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
perform
unspentCredits'' :: Credit
unspentCredits'' = Credit
unspentCredits' Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- Credit
perform
in (Credit
c Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0)
Bool -> Bool -> Bool
&& (Credit
unspentCredits'' Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
r)
Bool -> Bool -> Bool
&& (Credit
suppliedCredits' Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
spentCredits' Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
unspentCredits'')
Bool -> Bool -> Bool
&& (Credit
suppliedCredits' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
< Credit
totalDebt)
creditedPostcondition :: Bool
creditedPostcondition =
(Credit
c Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0)
Bool -> Bool -> Bool
&& (Credit
suppliedCredits' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
< Credit
totalDebt)
mergeBatchSize :: Int
mergeBatchSize :: Credit
mergeBatchSize = Credit
32
newMergingRun :: IsMergeType t => t -> [Run] -> ST s (MergingRun t s)
newMergingRun :: forall t s. IsMergeType t => t -> [Buffer] -> ST s (MergingRun t s)
newMergingRun t
mergeType [Buffer]
runs = do
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ [Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
runs Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
1
(Credit
debt, MergingRunState
state) <- case (Buffer -> Bool) -> [Buffer] -> [Buffer]
forall a. (a -> Bool) -> [a] -> [a]
filter (\Buffer
r -> Buffer -> Credit
runSize Buffer
r Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
0) [Buffer]
runs of
[] -> let (Buffer
r:[Buffer]
_) = [Buffer]
runs
in (Credit, MergingRunState) -> ST s (Credit, MergingRunState)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Buffer -> Credit
runSize Buffer
r, Buffer -> MergingRunState
CompletedMerge Buffer
r)
[Buffer
r] -> (Credit, MergingRunState) -> ST s (Credit, MergingRunState)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Buffer -> Credit
runSize Buffer
r, Buffer -> MergingRunState
CompletedMerge Buffer
r)
[Buffer]
rs -> do
let !debt :: Credit
debt = [Credit] -> Credit
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((Buffer -> Credit) -> [Buffer] -> [Credit]
forall a b. (a -> b) -> [a] -> [b]
map Buffer -> Credit
runSize [Buffer]
rs)
let merged :: Buffer
merged = t -> [Buffer] -> Buffer
forall t. IsMergeType t => t -> [Buffer] -> Buffer
mergek t
mergeType [Buffer]
rs
(Credit, MergingRunState) -> ST s (Credit, MergingRunState)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
debt, MergeCredit -> [Buffer] -> Buffer -> MergingRunState
OngoingMerge MergeCredit
zeroMergeCredit [Buffer]
rs Buffer
merged)
t -> MergeDebt -> STRef s MergingRunState -> MergingRun t s
forall t s.
t -> MergeDebt -> STRef s MergingRunState -> MergingRun t s
MergingRun t
mergeType (Credit -> MergeDebt
MergeDebt Credit
debt) (STRef s MergingRunState -> MergingRun t s)
-> ST s (STRef s MergingRunState) -> ST s (MergingRun t s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MergingRunState -> ST s (STRef s MergingRunState)
forall a s. a -> ST s (STRef s a)
newSTRef MergingRunState
state
mergek :: IsMergeType t => t -> [Run] -> Run
mergek :: forall t. IsMergeType t => t -> [Buffer] -> Buffer
mergek t
t =
(if t -> Bool
forall t. IsMergeType t => t -> Bool
isLastLevel t
t then (Op -> Bool) -> Buffer -> Buffer
forall a k. (a -> Bool) -> Map k a -> Map k a
Map.filter (Op -> Op -> Bool
forall a. Eq a => a -> a -> Bool
/= Op
forall v b. Update v b
Delete) else Buffer -> Buffer
forall a. a -> a
id)
(Buffer -> Buffer) -> ([Buffer] -> Buffer) -> [Buffer] -> Buffer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Op -> Op -> Op) -> [Buffer] -> Buffer
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
(a -> a -> a) -> f (Map k a) -> Map k a
Map.unionsWith (if t -> Bool
forall t. IsMergeType t => t -> Bool
isUnion t
t then Op -> Op -> Op
combineUnion else Op -> Op -> Op
combine)
combine :: Op -> Op -> Op
combine :: Op -> Op -> Op
combine Op
new_ Op
old = case Op
new_ of
Insert{} -> Op
new_
Delete{} -> Op
new_
Mupsert Value
v -> case Op
old of
Insert Value
v' Maybe Blob
_ -> Value -> Maybe Blob -> Op
forall v b. v -> Maybe b -> Update v b
Insert (Value -> Value -> Value
resolveValue Value
v Value
v') Maybe Blob
forall a. Maybe a
Nothing
Op
Delete -> Value -> Maybe Blob -> Op
forall v b. v -> Maybe b -> Update v b
Insert Value
v Maybe Blob
forall a. Maybe a
Nothing
Mupsert Value
v' -> Value -> Op
forall v b. v -> Update v b
Mupsert (Value -> Value -> Value
resolveValue Value
v Value
v')
combineUnion :: Op -> Op -> Op
combineUnion :: Op -> Op -> Op
combineUnion Op
Delete (Mupsert Value
v) = Value -> Maybe Blob -> Op
forall v b. v -> Maybe b -> Update v b
Insert Value
v Maybe Blob
forall a. Maybe a
Nothing
combineUnion Op
Delete Op
old = Op
old
combineUnion (Mupsert Value
u) Op
Delete = Value -> Maybe Blob -> Op
forall v b. v -> Maybe b -> Update v b
Insert Value
u Maybe Blob
forall a. Maybe a
Nothing
combineUnion Op
new_ Op
Delete = Op
new_
combineUnion (Mupsert Value
v') (Mupsert Value
v ) = Value -> Maybe Blob -> Op
forall v b. v -> Maybe b -> Update v b
Insert (Value -> Value -> Value
resolveValue Value
v' Value
v) Maybe Blob
forall a. Maybe a
Nothing
combineUnion (Mupsert Value
v') (Insert Value
v Maybe Blob
_) = Value -> Maybe Blob -> Op
forall v b. v -> Maybe b -> Update v b
Insert (Value -> Value -> Value
resolveValue Value
v' Value
v) Maybe Blob
forall a. Maybe a
Nothing
combineUnion (Insert Value
v' Maybe Blob
b') (Mupsert Value
v) = Value -> Maybe Blob -> Op
forall v b. v -> Maybe b -> Update v b
Insert (Value -> Value -> Value
resolveValue Value
v' Value
v) Maybe Blob
b'
combineUnion (Insert Value
v' Maybe Blob
b') (Insert Value
v Maybe Blob
_) = Value -> Maybe Blob -> Op
forall v b. v -> Maybe b -> Update v b
Insert (Value -> Value -> Value
resolveValue Value
v' Value
v) Maybe Blob
b'
expectCompletedMergingRun :: HasCallStack => MergingRun t s -> ST s Run
expectCompletedMergingRun :: forall t s. HasCallStack => MergingRun t s -> ST s Buffer
expectCompletedMergingRun = Invariant s Buffer -> ST s Buffer
forall s a. HasCallStack => Invariant s a -> ST s a
expectInvariant (Invariant s Buffer -> ST s Buffer)
-> (MergingRun t s -> Invariant s Buffer)
-> MergingRun t s
-> ST s Buffer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MergingRun t s -> Invariant s Buffer
forall t s. MergingRun t s -> Invariant s Buffer
isCompletedMergingRun
supplyCreditsMergingRun :: Credit -> MergingRun t s -> ST s Credit
supplyCreditsMergingRun :: forall t s. Credit -> MergingRun t s -> ST s Credit
supplyCreditsMergingRun =
(MergingRun t s -> ST s (Credit, Credit))
-> (Credit -> MergingRun t s -> ST s Credit)
-> Credit
-> MergingRun t s
-> ST s Credit
forall a s.
HasCallStack =>
(a -> ST s (Credit, Credit))
-> (Credit -> a -> ST s Credit) -> Credit -> a -> ST s Credit
checked MergingRun t s -> ST s (Credit, Credit)
forall t s. MergingRun t s -> ST s (Credit, Credit)
remainingDebtMergingRun ((Credit -> MergingRun t s -> ST s Credit)
-> Credit -> MergingRun t s -> ST s Credit)
-> (Credit -> MergingRun t s -> ST s Credit)
-> Credit
-> MergingRun t s
-> ST s Credit
forall a b. (a -> b) -> a -> b
$ \Credit
credits (MergingRun t
_ MergeDebt
mergeDebt STRef s MergingRunState
ref) -> do
MergingRunState
mrs <- STRef s MergingRunState -> ST s MergingRunState
forall s a. STRef s a -> ST s a
readSTRef STRef s MergingRunState
ref
case MergingRunState
mrs of
CompletedMerge{} -> Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
credits
OngoingMerge MergeCredit
mergeCredit [Buffer]
rs Buffer
r ->
case MergeDebt -> MergeCredit -> Credit -> MergeDebtPaydown
paydownMergeDebt MergeDebt
mergeDebt MergeCredit
mergeCredit Credit
credits of
MergeDebtDischarged Credit
_ Credit
leftover -> do
STRef s MergingRunState -> MergingRunState -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s MergingRunState
ref (Buffer -> MergingRunState
CompletedMerge Buffer
r)
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
leftover
MergeDebtPaydownCredited MergeCredit
mergeCredit' -> do
STRef s MergingRunState -> MergingRunState -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s MergingRunState
ref (MergeCredit -> [Buffer] -> Buffer -> MergingRunState
OngoingMerge MergeCredit
mergeCredit' [Buffer]
rs Buffer
r)
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
0
MergeDebtPaydownPerform Credit
_mergeSteps MergeCredit
mergeCredit' -> do
STRef s MergingRunState -> MergingRunState -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s MergingRunState
ref (MergeCredit -> [Buffer] -> Buffer -> MergingRunState
OngoingMerge MergeCredit
mergeCredit' [Buffer]
rs Buffer
r)
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
0
suppliedCreditMergingRun :: MergingRun t s -> ST s Credit
suppliedCreditMergingRun :: forall t s. MergingRun t s -> ST s Credit
suppliedCreditMergingRun (MergingRun t
_ MergeDebt
d STRef s MergingRunState
ref) =
STRef s MergingRunState -> ST s MergingRunState
forall s a. STRef s a -> ST s a
readSTRef STRef s MergingRunState
ref ST s MergingRunState
-> (MergingRunState -> ST s Credit) -> ST s Credit
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
CompletedMerge{} ->
let MergeDebt { Credit
totalDebt :: MergeDebt -> Credit
totalDebt :: Credit
totalDebt } = MergeDebt
d in
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
totalDebt
OngoingMerge MergeCredit {Credit
spentCredits :: MergeCredit -> Credit
spentCredits :: Credit
spentCredits, Credit
unspentCredits :: MergeCredit -> Credit
unspentCredits :: Credit
unspentCredits} [Buffer]
_ Buffer
_ ->
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
spentCredits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
unspentCredits)
new :: ST s (LSM s)
new :: forall s. ST s (LSM s)
new = LSMConfig -> ST s (LSM s)
forall s. LSMConfig -> ST s (LSM s)
newWith LSMConfig
conf
where
conf :: LSMConfig
conf = LSMConfig {
configMaxWriteBufferSize :: Credit
configMaxWriteBufferSize = Credit
4
, configSizeRatio :: Credit
configSizeRatio = Credit
4
}
newWith :: LSMConfig -> ST s (LSM s)
newWith :: forall s. LSMConfig -> ST s (LSM s)
newWith LSMConfig
conf
| LSMConfig -> Credit
configMaxWriteBufferSize LSMConfig
conf Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
0 =
String -> ST s (LSM s)
forall a. HasCallStack => String -> a
error String
"newWith: configMaxWriteBufferSize should be positive"
| LSMConfig -> Credit
configSizeRatio LSMConfig
conf Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
1 =
String -> ST s (LSM s)
forall a. HasCallStack => String -> a
error String
"newWith: configSizeRatio should be larger than 1"
| Bool
otherwise = do
STRef s Credit
c <- Credit -> ST s (STRef s Credit)
forall a s. a -> ST s (STRef s a)
newSTRef Credit
0
STRef s (LSMContent s)
lsm <- LSMContent s -> ST s (STRef s (LSMContent s))
forall a s. a -> ST s (STRef s a)
newSTRef (Buffer -> Levels s -> UnionLevel s -> LSMContent s
forall s. Buffer -> Levels s -> UnionLevel s -> LSMContent s
LSMContent Buffer
forall k a. Map k a
Map.empty [] UnionLevel s
forall s. UnionLevel s
NoUnion)
LSM s -> ST s (LSM s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (STRef s Credit -> LSMConfig -> STRef s (LSMContent s) -> LSM s
forall s.
STRef s Credit -> LSMConfig -> STRef s (LSMContent s) -> LSM s
LSMHandle STRef s Credit
c LSMConfig
conf STRef s (LSMContent s)
lsm)
inserts :: Tracer (ST s) Event -> LSM s -> [(Key, Value, Maybe Blob)] -> ST s ()
inserts :: forall s.
Tracer (ST s) Event
-> LSM s -> [(Key, Value, Maybe Blob)] -> ST s ()
inserts Tracer (ST s) Event
tr LSM s
lsm [(Key, Value, Maybe Blob)]
kvbs = Tracer (ST s) Event -> LSM s -> [(Key, Op)] -> ST s ()
forall s. Tracer (ST s) Event -> LSM s -> [(Key, Op)] -> ST s ()
updates Tracer (ST s) Event
tr LSM s
lsm [ (Key
k, Value -> Maybe Blob -> Op
forall v b. v -> Maybe b -> Update v b
Insert Value
v Maybe Blob
b) | (Key
k, Value
v, Maybe Blob
b) <- [(Key, Value, Maybe Blob)]
kvbs ]
insert :: Tracer (ST s) Event -> LSM s -> Key -> Value -> Maybe Blob -> ST s ()
insert :: forall s.
Tracer (ST s) Event
-> LSM s -> Key -> Value -> Maybe Blob -> ST s ()
insert Tracer (ST s) Event
tr LSM s
lsm Key
k Value
v Maybe Blob
b = Tracer (ST s) Event -> LSM s -> Key -> Op -> ST s ()
forall s. Tracer (ST s) Event -> LSM s -> Key -> Op -> ST s ()
update Tracer (ST s) Event
tr LSM s
lsm Key
k (Value -> Maybe Blob -> Op
forall v b. v -> Maybe b -> Update v b
Insert Value
v Maybe Blob
b)
deletes :: Tracer (ST s) Event -> LSM s -> [Key] -> ST s ()
deletes :: forall s. Tracer (ST s) Event -> LSM s -> [Key] -> ST s ()
deletes Tracer (ST s) Event
tr LSM s
lsm [Key]
ks = Tracer (ST s) Event -> LSM s -> [(Key, Op)] -> ST s ()
forall s. Tracer (ST s) Event -> LSM s -> [(Key, Op)] -> ST s ()
updates Tracer (ST s) Event
tr LSM s
lsm [ (Key
k, Op
forall v b. Update v b
Delete) | Key
k <- [Key]
ks ]
delete :: Tracer (ST s) Event -> LSM s -> Key -> ST s ()
delete :: forall s. Tracer (ST s) Event -> LSM s -> Key -> ST s ()
delete Tracer (ST s) Event
tr LSM s
lsm Key
k = Tracer (ST s) Event -> LSM s -> Key -> Op -> ST s ()
forall s. Tracer (ST s) Event -> LSM s -> Key -> Op -> ST s ()
update Tracer (ST s) Event
tr LSM s
lsm Key
k Op
forall v b. Update v b
Delete
mupserts :: Tracer (ST s) Event -> LSM s -> [(Key, Value)] -> ST s ()
mupserts :: forall s. Tracer (ST s) Event -> LSM s -> [(Key, Value)] -> ST s ()
mupserts Tracer (ST s) Event
tr LSM s
lsm [(Key, Value)]
kvbs = Tracer (ST s) Event -> LSM s -> [(Key, Op)] -> ST s ()
forall s. Tracer (ST s) Event -> LSM s -> [(Key, Op)] -> ST s ()
updates Tracer (ST s) Event
tr LSM s
lsm [ (Key
k, Value -> Op
forall v b. v -> Update v b
Mupsert Value
v) | (Key
k, Value
v) <- [(Key, Value)]
kvbs ]
mupsert :: Tracer (ST s) Event -> LSM s -> Key -> Value -> ST s ()
mupsert :: forall s. Tracer (ST s) Event -> LSM s -> Key -> Value -> ST s ()
mupsert Tracer (ST s) Event
tr LSM s
lsm Key
k Value
v = Tracer (ST s) Event -> LSM s -> Key -> Op -> ST s ()
forall s. Tracer (ST s) Event -> LSM s -> Key -> Op -> ST s ()
update Tracer (ST s) Event
tr LSM s
lsm Key
k (Value -> Op
forall v b. v -> Update v b
Mupsert Value
v)
data Update v b =
Insert !v !(Maybe b)
| Mupsert !v
| Delete
deriving stock (Update v b -> Update v b -> Bool
(Update v b -> Update v b -> Bool)
-> (Update v b -> Update v b -> Bool) -> Eq (Update v b)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall v b. (Eq b, Eq v) => Update v b -> Update v b -> Bool
$c== :: forall v b. (Eq b, Eq v) => Update v b -> Update v b -> Bool
== :: Update v b -> Update v b -> Bool
$c/= :: forall v b. (Eq b, Eq v) => Update v b -> Update v b -> Bool
/= :: Update v b -> Update v b -> Bool
Eq, Credit -> Update v b -> ShowS
[Update v b] -> ShowS
Update v b -> String
(Credit -> Update v b -> ShowS)
-> (Update v b -> String)
-> ([Update v b] -> ShowS)
-> Show (Update v b)
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall v b. (Show b, Show v) => Credit -> Update v b -> ShowS
forall v b. (Show b, Show v) => [Update v b] -> ShowS
forall v b. (Show b, Show v) => Update v b -> String
$cshowsPrec :: forall v b. (Show b, Show v) => Credit -> Update v b -> ShowS
showsPrec :: Credit -> Update v b -> ShowS
$cshow :: forall v b. (Show b, Show v) => Update v b -> String
show :: Update v b -> String
$cshowList :: forall v b. (Show b, Show v) => [Update v b] -> ShowS
showList :: [Update v b] -> ShowS
Show)
updates :: Tracer (ST s) Event -> LSM s -> [(Key, Op)] -> ST s ()
updates :: forall s. Tracer (ST s) Event -> LSM s -> [(Key, Op)] -> ST s ()
updates Tracer (ST s) Event
tr LSM s
lsm = ((Key, Op) -> ST s ()) -> [(Key, Op)] -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((Key -> Op -> ST s ()) -> (Key, Op) -> ST s ()
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Tracer (ST s) Event -> LSM s -> Key -> Op -> ST s ()
forall s. Tracer (ST s) Event -> LSM s -> Key -> Op -> ST s ()
update Tracer (ST s) Event
tr LSM s
lsm))
update :: Tracer (ST s) Event -> LSM s -> Key -> Op -> ST s ()
update :: forall s. Tracer (ST s) Event -> LSM s -> Key -> Op -> ST s ()
update Tracer (ST s) Event
tr (LSMHandle STRef s Credit
scr LSMConfig
conf STRef s (LSMContent s)
lsmr) Key
k Op
op = do
Credit
sc <- STRef s Credit -> ST s Credit
forall s a. STRef s a -> ST s a
readSTRef STRef s Credit
scr
content :: LSMContent s
content@(LSMContent Buffer
wb Levels s
ls UnionLevel s
unionLevel) <- STRef s (LSMContent s) -> ST s (LSMContent s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (LSMContent s)
lsmr
STRef s Credit -> (Credit -> Credit) -> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef' STRef s Credit
scr (Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1)
NominalCredit -> Levels s -> ST s ()
forall s. NominalCredit -> Levels s -> ST s ()
supplyCreditsLevels (Credit -> NominalCredit
NominalCredit Credit
1) Levels s
ls
LSMConfig -> LSMContent s -> ST s ()
forall s. LSMConfig -> LSMContent s -> ST s ()
invariant LSMConfig
conf LSMContent s
content
let wb' :: Buffer
wb' = (Op -> Op -> Op) -> Key -> Op -> Buffer -> Buffer
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith Op -> Op -> Op
combine Key
k Op
op Buffer
wb
if Buffer -> Credit
bufferSize Buffer
wb' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= HasCallStack => LSMConfig -> Credit
LSMConfig -> Credit
maxWriteBufferSize LSMConfig
conf
then do
Levels s
ls' <- Tracer (ST s) Event
-> Credit
-> LSMConfig
-> Buffer
-> Levels s
-> UnionLevel s
-> ST s (Levels s)
forall s.
Tracer (ST s) Event
-> Credit
-> LSMConfig
-> Buffer
-> Levels s
-> UnionLevel s
-> ST s (Levels s)
increment Tracer (ST s) Event
tr Credit
sc LSMConfig
conf (Buffer -> Buffer
bufferToRun Buffer
wb') Levels s
ls UnionLevel s
unionLevel
let content' :: LSMContent s
content' = Buffer -> Levels s -> UnionLevel s -> LSMContent s
forall s. Buffer -> Levels s -> UnionLevel s -> LSMContent s
LSMContent Buffer
forall k a. Map k a
Map.empty Levels s
ls' UnionLevel s
unionLevel
LSMConfig -> LSMContent s -> ST s ()
forall s. LSMConfig -> LSMContent s -> ST s ()
invariant LSMConfig
conf LSMContent s
content'
STRef s (LSMContent s) -> LSMContent s -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s (LSMContent s)
lsmr LSMContent s
content'
else
STRef s (LSMContent s) -> LSMContent s -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s (LSMContent s)
lsmr (Buffer -> Levels s -> UnionLevel s -> LSMContent s
forall s. Buffer -> Levels s -> UnionLevel s -> LSMContent s
LSMContent Buffer
wb' Levels s
ls UnionLevel s
unionLevel)
supplyMergeCredits :: LSM s -> NominalCredit -> ST s ()
supplyMergeCredits :: forall s. LSM s -> NominalCredit -> ST s ()
supplyMergeCredits (LSMHandle STRef s Credit
scr LSMConfig
conf STRef s (LSMContent s)
lsmr) NominalCredit
credits = do
content :: LSMContent s
content@(LSMContent Buffer
_ Levels s
ls UnionLevel s
_) <- STRef s (LSMContent s) -> ST s (LSMContent s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (LSMContent s)
lsmr
STRef s Credit -> (Credit -> Credit) -> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef' STRef s Credit
scr (Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1)
NominalCredit -> Levels s -> ST s ()
forall s. NominalCredit -> Levels s -> ST s ()
supplyCreditsLevels NominalCredit
credits Levels s
ls
LSMConfig -> LSMContent s -> ST s ()
forall s. LSMConfig -> LSMContent s -> ST s ()
invariant LSMConfig
conf LSMContent s
content
data LookupResult v b =
NotFound
| Found !v !(Maybe b)
deriving stock (LookupResult v b -> LookupResult v b -> Bool
(LookupResult v b -> LookupResult v b -> Bool)
-> (LookupResult v b -> LookupResult v b -> Bool)
-> Eq (LookupResult v b)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall v b.
(Eq v, Eq b) =>
LookupResult v b -> LookupResult v b -> Bool
$c== :: forall v b.
(Eq v, Eq b) =>
LookupResult v b -> LookupResult v b -> Bool
== :: LookupResult v b -> LookupResult v b -> Bool
$c/= :: forall v b.
(Eq v, Eq b) =>
LookupResult v b -> LookupResult v b -> Bool
/= :: LookupResult v b -> LookupResult v b -> Bool
Eq, Credit -> LookupResult v b -> ShowS
[LookupResult v b] -> ShowS
LookupResult v b -> String
(Credit -> LookupResult v b -> ShowS)
-> (LookupResult v b -> String)
-> ([LookupResult v b] -> ShowS)
-> Show (LookupResult v b)
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall v b. (Show v, Show b) => Credit -> LookupResult v b -> ShowS
forall v b. (Show v, Show b) => [LookupResult v b] -> ShowS
forall v b. (Show v, Show b) => LookupResult v b -> String
$cshowsPrec :: forall v b. (Show v, Show b) => Credit -> LookupResult v b -> ShowS
showsPrec :: Credit -> LookupResult v b -> ShowS
$cshow :: forall v b. (Show v, Show b) => LookupResult v b -> String
show :: LookupResult v b -> String
$cshowList :: forall v b. (Show v, Show b) => [LookupResult v b] -> ShowS
showList :: [LookupResult v b] -> ShowS
Show)
lookups :: LSM s -> [Key] -> ST s [LookupResult Value Blob]
lookups :: forall s. LSM s -> [Key] -> ST s [LookupResult Value Blob]
lookups (LSMHandle STRef s Credit
_ LSMConfig
_conf STRef s (LSMContent s)
lsmr) [Key]
ks = do
LSMContent Buffer
wb Levels s
ls UnionLevel s
ul <- STRef s (LSMContent s) -> ST s (LSMContent s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (LSMContent s)
lsmr
[Buffer]
runs <- [[Buffer]] -> [Buffer]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Buffer]] -> [Buffer]) -> ST s [[Buffer]] -> ST s [Buffer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Levels s -> ST s [[Buffer]]
forall s. Levels s -> ST s [[Buffer]]
flattenLevels Levels s
ls
(Key -> ST s (LookupResult Value Blob))
-> [Key] -> ST s [LookupResult Value Blob]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (Buffer
-> [Buffer]
-> UnionLevel s
-> Key
-> ST s (LookupResult Value Blob)
forall s.
Buffer
-> [Buffer]
-> UnionLevel s
-> Key
-> ST s (LookupResult Value Blob)
doLookup Buffer
wb [Buffer]
runs UnionLevel s
ul) [Key]
ks
lookup :: LSM s -> Key -> ST s (LookupResult Value Blob)
lookup :: forall s. LSM s -> Key -> ST s (LookupResult Value Blob)
lookup (LSMHandle STRef s Credit
_ LSMConfig
_conf STRef s (LSMContent s)
lsmr) Key
k = do
LSMContent Buffer
wb Levels s
ls UnionLevel s
ul <- STRef s (LSMContent s) -> ST s (LSMContent s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (LSMContent s)
lsmr
[Buffer]
runs <- [[Buffer]] -> [Buffer]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Buffer]] -> [Buffer]) -> ST s [[Buffer]] -> ST s [Buffer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Levels s -> ST s [[Buffer]]
forall s. Levels s -> ST s [[Buffer]]
flattenLevels Levels s
ls
Buffer
-> [Buffer]
-> UnionLevel s
-> Key
-> ST s (LookupResult Value Blob)
forall s.
Buffer
-> [Buffer]
-> UnionLevel s
-> Key
-> ST s (LookupResult Value Blob)
doLookup Buffer
wb [Buffer]
runs UnionLevel s
ul Key
k
duplicate :: LSM s -> ST s (LSM s)
duplicate :: forall s. LSM s -> ST s (LSM s)
duplicate (LSMHandle STRef s Credit
_scr LSMConfig
conf STRef s (LSMContent s)
lsmr) = do
STRef s Credit
scr' <- Credit -> ST s (STRef s Credit)
forall a s. a -> ST s (STRef s a)
newSTRef Credit
0
STRef s (LSMContent s)
lsmr' <- LSMContent s -> ST s (STRef s (LSMContent s))
forall a s. a -> ST s (STRef s a)
newSTRef (LSMContent s -> ST s (STRef s (LSMContent s)))
-> ST s (LSMContent s) -> ST s (STRef s (LSMContent s))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< STRef s (LSMContent s) -> ST s (LSMContent s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (LSMContent s)
lsmr
LSM s -> ST s (LSM s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (STRef s Credit -> LSMConfig -> STRef s (LSMContent s) -> LSM s
forall s.
STRef s Credit -> LSMConfig -> STRef s (LSMContent s) -> LSM s
LSMHandle STRef s Credit
scr' LSMConfig
conf STRef s (LSMContent s)
lsmr')
unions :: [LSM s] -> ST s (LSM s)
unions :: forall s. [LSM s] -> ST s (LSM s)
unions [LSM s]
lsms = do
([LSMConfig]
confs, [Maybe (MergingTree s)]
trees) <- ([(LSMConfig, Maybe (MergingTree s))]
-> ([LSMConfig], [Maybe (MergingTree s)]))
-> ST s [(LSMConfig, Maybe (MergingTree s))]
-> ST s ([LSMConfig], [Maybe (MergingTree s)])
forall a b. (a -> b) -> ST s a -> ST s b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(LSMConfig, Maybe (MergingTree s))]
-> ([LSMConfig], [Maybe (MergingTree s)])
forall a b. [(a, b)] -> ([a], [b])
unzip (ST s [(LSMConfig, Maybe (MergingTree s))]
-> ST s ([LSMConfig], [Maybe (MergingTree s)]))
-> ST s [(LSMConfig, Maybe (MergingTree s))]
-> ST s ([LSMConfig], [Maybe (MergingTree s)])
forall a b. (a -> b) -> a -> b
$ [LSM s]
-> (LSM s -> ST s (LSMConfig, Maybe (MergingTree s)))
-> ST s [(LSMConfig, Maybe (MergingTree s))]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [LSM s]
lsms ((LSM s -> ST s (LSMConfig, Maybe (MergingTree s)))
-> ST s [(LSMConfig, Maybe (MergingTree s))])
-> (LSM s -> ST s (LSMConfig, Maybe (MergingTree s)))
-> ST s [(LSMConfig, Maybe (MergingTree s))]
forall a b. (a -> b) -> a -> b
$ \(LSMHandle STRef s Credit
_ LSMConfig
conf STRef s (LSMContent s)
lsmr) ->
(LSMConfig
conf,) (Maybe (MergingTree s) -> (LSMConfig, Maybe (MergingTree s)))
-> ST s (Maybe (MergingTree s))
-> ST s (LSMConfig, Maybe (MergingTree s))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LSMContent s -> ST s (Maybe (MergingTree s))
forall s. LSMContent s -> ST s (Maybe (MergingTree s))
contentToMergingTree (LSMContent s -> ST s (Maybe (MergingTree s)))
-> ST s (LSMContent s) -> ST s (Maybe (MergingTree s))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< STRef s (LSMContent s) -> ST s (LSMContent s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (LSMContent s)
lsmr)
LSMConfig
conf <- case [LSMConfig]
confs of
[] -> String -> ST s LSMConfig
forall a. HasCallStack => String -> a
error String
"unions: 0 tables"
LSMConfig
conf : [LSMConfig]
_ -> Bool -> ST s LSMConfig -> ST s LSMConfig
forall a. HasCallStack => Bool -> a -> a
assert ((LSMConfig -> Bool) -> [LSMConfig] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (LSMConfig
conf==) [LSMConfig]
confs) (ST s LSMConfig -> ST s LSMConfig)
-> ST s LSMConfig -> ST s LSMConfig
forall a b. (a -> b) -> a -> b
$ LSMConfig -> ST s LSMConfig
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure LSMConfig
conf
UnionLevel s
unionLevel <- [MergingTree s] -> ST s (Maybe (MergingTree s))
forall s. [MergingTree s] -> ST s (Maybe (MergingTree s))
newPendingUnionMerge ([Maybe (MergingTree s)] -> [MergingTree s]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (MergingTree s)]
trees) ST s (Maybe (MergingTree s))
-> (Maybe (MergingTree s) -> ST s (UnionLevel s))
-> ST s (UnionLevel s)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe (MergingTree s)
Nothing -> UnionLevel s -> ST s (UnionLevel s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure UnionLevel s
forall s. UnionLevel s
NoUnion
Just MergingTree s
tree -> do
Credit
debt <- (Credit, Credit) -> Credit
forall a b. (a, b) -> a
fst ((Credit, Credit) -> Credit)
-> ST s (Credit, Credit) -> ST s Credit
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MergingTree s -> ST s (Credit, Credit)
forall s. MergingTree s -> ST s (Credit, Credit)
remainingDebtMergingTree MergingTree s
tree
MergingTree s -> STRef s Credit -> UnionLevel s
forall s. MergingTree s -> STRef s Credit -> UnionLevel s
Union MergingTree s
tree (STRef s Credit -> UnionLevel s)
-> ST s (STRef s Credit) -> ST s (UnionLevel s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Credit -> ST s (STRef s Credit)
forall a s. a -> ST s (STRef s a)
newSTRef Credit
debt
STRef s (LSMContent s)
lsmr <- LSMContent s -> ST s (STRef s (LSMContent s))
forall a s. a -> ST s (STRef s a)
newSTRef (Buffer -> Levels s -> UnionLevel s -> LSMContent s
forall s. Buffer -> Levels s -> UnionLevel s -> LSMContent s
LSMContent Buffer
forall k a. Map k a
Map.empty [] UnionLevel s
unionLevel)
STRef s Credit
c <- Credit -> ST s (STRef s Credit)
forall a s. a -> ST s (STRef s a)
newSTRef Credit
0
LSM s -> ST s (LSM s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (STRef s Credit -> LSMConfig -> STRef s (LSMContent s) -> LSM s
forall s.
STRef s Credit -> LSMConfig -> STRef s (LSMContent s) -> LSM s
LSMHandle STRef s Credit
c LSMConfig
conf STRef s (LSMContent s)
lsmr)
newtype UnionDebt = UnionDebt Debt
deriving stock (Credit -> UnionDebt -> ShowS
[UnionDebt] -> ShowS
UnionDebt -> String
(Credit -> UnionDebt -> ShowS)
-> (UnionDebt -> String)
-> ([UnionDebt] -> ShowS)
-> Show UnionDebt
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> UnionDebt -> ShowS
showsPrec :: Credit -> UnionDebt -> ShowS
$cshow :: UnionDebt -> String
show :: UnionDebt -> String
$cshowList :: [UnionDebt] -> ShowS
showList :: [UnionDebt] -> ShowS
Show, UnionDebt -> UnionDebt -> Bool
(UnionDebt -> UnionDebt -> Bool)
-> (UnionDebt -> UnionDebt -> Bool) -> Eq UnionDebt
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UnionDebt -> UnionDebt -> Bool
== :: UnionDebt -> UnionDebt -> Bool
$c/= :: UnionDebt -> UnionDebt -> Bool
/= :: UnionDebt -> UnionDebt -> Bool
Eq, Eq UnionDebt
Eq UnionDebt =>
(UnionDebt -> UnionDebt -> Ordering)
-> (UnionDebt -> UnionDebt -> Bool)
-> (UnionDebt -> UnionDebt -> Bool)
-> (UnionDebt -> UnionDebt -> Bool)
-> (UnionDebt -> UnionDebt -> Bool)
-> (UnionDebt -> UnionDebt -> UnionDebt)
-> (UnionDebt -> UnionDebt -> UnionDebt)
-> Ord UnionDebt
UnionDebt -> UnionDebt -> Bool
UnionDebt -> UnionDebt -> Ordering
UnionDebt -> UnionDebt -> UnionDebt
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: UnionDebt -> UnionDebt -> Ordering
compare :: UnionDebt -> UnionDebt -> Ordering
$c< :: UnionDebt -> UnionDebt -> Bool
< :: UnionDebt -> UnionDebt -> Bool
$c<= :: UnionDebt -> UnionDebt -> Bool
<= :: UnionDebt -> UnionDebt -> Bool
$c> :: UnionDebt -> UnionDebt -> Bool
> :: UnionDebt -> UnionDebt -> Bool
$c>= :: UnionDebt -> UnionDebt -> Bool
>= :: UnionDebt -> UnionDebt -> Bool
$cmax :: UnionDebt -> UnionDebt -> UnionDebt
max :: UnionDebt -> UnionDebt -> UnionDebt
$cmin :: UnionDebt -> UnionDebt -> UnionDebt
min :: UnionDebt -> UnionDebt -> UnionDebt
Ord)
deriving newtype Integer -> UnionDebt
UnionDebt -> UnionDebt
UnionDebt -> UnionDebt -> UnionDebt
(UnionDebt -> UnionDebt -> UnionDebt)
-> (UnionDebt -> UnionDebt -> UnionDebt)
-> (UnionDebt -> UnionDebt -> UnionDebt)
-> (UnionDebt -> UnionDebt)
-> (UnionDebt -> UnionDebt)
-> (UnionDebt -> UnionDebt)
-> (Integer -> UnionDebt)
-> Num UnionDebt
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: UnionDebt -> UnionDebt -> UnionDebt
+ :: UnionDebt -> UnionDebt -> UnionDebt
$c- :: UnionDebt -> UnionDebt -> UnionDebt
- :: UnionDebt -> UnionDebt -> UnionDebt
$c* :: UnionDebt -> UnionDebt -> UnionDebt
* :: UnionDebt -> UnionDebt -> UnionDebt
$cnegate :: UnionDebt -> UnionDebt
negate :: UnionDebt -> UnionDebt
$cabs :: UnionDebt -> UnionDebt
abs :: UnionDebt -> UnionDebt
$csignum :: UnionDebt -> UnionDebt
signum :: UnionDebt -> UnionDebt
$cfromInteger :: Integer -> UnionDebt
fromInteger :: Integer -> UnionDebt
Num
remainingUnionDebt :: LSM s -> ST s UnionDebt
remainingUnionDebt :: forall s. LSM s -> ST s UnionDebt
remainingUnionDebt (LSMHandle STRef s Credit
_ LSMConfig
_conf STRef s (LSMContent s)
lsmr) = do
LSMContent Buffer
_ Levels s
_ UnionLevel s
ul <- STRef s (LSMContent s) -> ST s (LSMContent s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (LSMContent s)
lsmr
Credit -> UnionDebt
UnionDebt (Credit -> UnionDebt) -> ST s Credit -> ST s UnionDebt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case UnionLevel s
ul of
UnionLevel s
NoUnion -> Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
0
Union MergingTree s
tree STRef s Credit
d -> MergingTree s -> STRef s Credit -> ST s Credit
forall s. MergingTree s -> STRef s Credit -> ST s Credit
checkedUnionDebt MergingTree s
tree STRef s Credit
d
newtype UnionCredits = UnionCredits Credit
deriving stock (Credit -> UnionCredits -> ShowS
[UnionCredits] -> ShowS
UnionCredits -> String
(Credit -> UnionCredits -> ShowS)
-> (UnionCredits -> String)
-> ([UnionCredits] -> ShowS)
-> Show UnionCredits
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> UnionCredits -> ShowS
showsPrec :: Credit -> UnionCredits -> ShowS
$cshow :: UnionCredits -> String
show :: UnionCredits -> String
$cshowList :: [UnionCredits] -> ShowS
showList :: [UnionCredits] -> ShowS
Show, UnionCredits -> UnionCredits -> Bool
(UnionCredits -> UnionCredits -> Bool)
-> (UnionCredits -> UnionCredits -> Bool) -> Eq UnionCredits
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UnionCredits -> UnionCredits -> Bool
== :: UnionCredits -> UnionCredits -> Bool
$c/= :: UnionCredits -> UnionCredits -> Bool
/= :: UnionCredits -> UnionCredits -> Bool
Eq, Eq UnionCredits
Eq UnionCredits =>
(UnionCredits -> UnionCredits -> Ordering)
-> (UnionCredits -> UnionCredits -> Bool)
-> (UnionCredits -> UnionCredits -> Bool)
-> (UnionCredits -> UnionCredits -> Bool)
-> (UnionCredits -> UnionCredits -> Bool)
-> (UnionCredits -> UnionCredits -> UnionCredits)
-> (UnionCredits -> UnionCredits -> UnionCredits)
-> Ord UnionCredits
UnionCredits -> UnionCredits -> Bool
UnionCredits -> UnionCredits -> Ordering
UnionCredits -> UnionCredits -> UnionCredits
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: UnionCredits -> UnionCredits -> Ordering
compare :: UnionCredits -> UnionCredits -> Ordering
$c< :: UnionCredits -> UnionCredits -> Bool
< :: UnionCredits -> UnionCredits -> Bool
$c<= :: UnionCredits -> UnionCredits -> Bool
<= :: UnionCredits -> UnionCredits -> Bool
$c> :: UnionCredits -> UnionCredits -> Bool
> :: UnionCredits -> UnionCredits -> Bool
$c>= :: UnionCredits -> UnionCredits -> Bool
>= :: UnionCredits -> UnionCredits -> Bool
$cmax :: UnionCredits -> UnionCredits -> UnionCredits
max :: UnionCredits -> UnionCredits -> UnionCredits
$cmin :: UnionCredits -> UnionCredits -> UnionCredits
min :: UnionCredits -> UnionCredits -> UnionCredits
Ord)
deriving newtype Integer -> UnionCredits
UnionCredits -> UnionCredits
UnionCredits -> UnionCredits -> UnionCredits
(UnionCredits -> UnionCredits -> UnionCredits)
-> (UnionCredits -> UnionCredits -> UnionCredits)
-> (UnionCredits -> UnionCredits -> UnionCredits)
-> (UnionCredits -> UnionCredits)
-> (UnionCredits -> UnionCredits)
-> (UnionCredits -> UnionCredits)
-> (Integer -> UnionCredits)
-> Num UnionCredits
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: UnionCredits -> UnionCredits -> UnionCredits
+ :: UnionCredits -> UnionCredits -> UnionCredits
$c- :: UnionCredits -> UnionCredits -> UnionCredits
- :: UnionCredits -> UnionCredits -> UnionCredits
$c* :: UnionCredits -> UnionCredits -> UnionCredits
* :: UnionCredits -> UnionCredits -> UnionCredits
$cnegate :: UnionCredits -> UnionCredits
negate :: UnionCredits -> UnionCredits
$cabs :: UnionCredits -> UnionCredits
abs :: UnionCredits -> UnionCredits
$csignum :: UnionCredits -> UnionCredits
signum :: UnionCredits -> UnionCredits
$cfromInteger :: Integer -> UnionCredits
fromInteger :: Integer -> UnionCredits
Num
supplyUnionCredits :: LSM s -> UnionCredits -> ST s UnionCredits
supplyUnionCredits :: forall s. LSM s -> UnionCredits -> ST s UnionCredits
supplyUnionCredits (LSMHandle STRef s Credit
scr LSMConfig
conf STRef s (LSMContent s)
lsmr) (UnionCredits Credit
credits)
| Credit
credits Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
0 = UnionCredits -> ST s UnionCredits
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit -> UnionCredits
UnionCredits Credit
0)
| Bool
otherwise = do
content :: LSMContent s
content@(LSMContent Buffer
_ Levels s
_ UnionLevel s
ul) <- STRef s (LSMContent s) -> ST s (LSMContent s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (LSMContent s)
lsmr
Credit -> UnionCredits
UnionCredits (Credit -> UnionCredits) -> ST s Credit -> ST s UnionCredits
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case UnionLevel s
ul of
UnionLevel s
NoUnion ->
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
credits
Union MergingTree s
tree STRef s Credit
debtRef -> do
STRef s Credit -> (Credit -> Credit) -> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef' STRef s Credit
scr (Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1)
Credit
_debt <- MergingTree s -> STRef s Credit -> ST s Credit
forall s. MergingTree s -> STRef s Credit -> ST s Credit
checkedUnionDebt MergingTree s
tree STRef s Credit
debtRef
Credit
c' <- Credit -> MergingTree s -> ST s Credit
forall s. Credit -> MergingTree s -> ST s Credit
supplyCreditsMergingTree Credit
credits MergingTree s
tree
Credit
debt' <- MergingTree s -> STRef s Credit -> ST s Credit
forall s. MergingTree s -> STRef s Credit -> ST s Credit
checkedUnionDebt MergingTree s
tree STRef s Credit
debtRef
Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Credit
debt' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
0) (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ Credit
c' Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
0
LSMConfig -> LSMContent s -> ST s ()
forall s. LSMConfig -> LSMContent s -> ST s ()
invariant LSMConfig
conf LSMContent s
content
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
c'
checkedUnionDebt :: MergingTree s -> STRef s Debt -> ST s Debt
checkedUnionDebt :: forall s. MergingTree s -> STRef s Credit -> ST s Credit
checkedUnionDebt MergingTree s
tree STRef s Credit
debtRef = do
Credit
storedDebt <- STRef s Credit -> ST s Credit
forall s a. STRef s a -> ST s a
readSTRef STRef s Credit
debtRef
Credit
debt <- (Credit, Credit) -> Credit
forall a b. (a, b) -> a
fst ((Credit, Credit) -> Credit)
-> ST s (Credit, Credit) -> ST s Credit
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MergingTree s -> ST s (Credit, Credit)
forall s. MergingTree s -> ST s (Credit, Credit)
remainingDebtMergingTree MergingTree s
tree
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ Credit
debt Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
storedDebt
STRef s Credit -> Credit -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s Credit
debtRef Credit
debt
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
debt
type LookupAcc = Maybe Op
updateAcc :: (Op -> Op -> Op) -> LookupAcc -> Op -> LookupAcc
updateAcc :: (Op -> Op -> Op) -> LookupAcc -> Op -> LookupAcc
updateAcc Op -> Op -> Op
_ LookupAcc
Nothing Op
old = Op -> LookupAcc
forall a. a -> Maybe a
Just Op
old
updateAcc Op -> Op -> Op
f (Just Op
new_) Op
old = Op -> LookupAcc
forall a. a -> Maybe a
Just (Op -> Op -> Op
f Op
new_ Op
old)
mergeAcc :: TreeMergeType -> [LookupAcc] -> LookupAcc
mergeAcc :: TreeMergeType -> [LookupAcc] -> LookupAcc
mergeAcc TreeMergeType
mt = (LookupAcc -> Op -> LookupAcc) -> LookupAcc -> [Op] -> LookupAcc
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ((Op -> Op -> Op) -> LookupAcc -> Op -> LookupAcc
updateAcc Op -> Op -> Op
com) LookupAcc
forall a. Maybe a
Nothing ([Op] -> LookupAcc)
-> ([LookupAcc] -> [Op]) -> [LookupAcc] -> LookupAcc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [LookupAcc] -> [Op]
forall a. [Maybe a] -> [a]
catMaybes
where
com :: Op -> Op -> Op
com = case TreeMergeType
mt of
TreeMergeType
MergeLevel -> Op -> Op -> Op
combine
TreeMergeType
MergeUnion -> Op -> Op -> Op
combineUnion
doLookup :: Buffer -> [Run] -> UnionLevel s -> Key -> ST s (LookupResult Value Blob)
doLookup :: forall s.
Buffer
-> [Buffer]
-> UnionLevel s
-> Key
-> ST s (LookupResult Value Blob)
doLookup Buffer
wb [Buffer]
runs UnionLevel s
ul Key
k = do
let acc0 :: LookupAcc
acc0 = LookupAcc -> Key -> [Buffer] -> LookupAcc
lookupBatch (Key -> Buffer -> LookupAcc
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Key
k Buffer
wb) Key
k [Buffer]
runs
case UnionLevel s
ul of
UnionLevel s
NoUnion ->
LookupResult Value Blob -> ST s (LookupResult Value Blob)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LookupAcc -> LookupResult Value Blob
convertAcc LookupAcc
acc0)
Union MergingTree s
tree STRef s Credit
_ -> do
LookupTree [Buffer]
treeBatches <- MergingTree s -> ST s (LookupTree [Buffer])
forall s. MergingTree s -> ST s (LookupTree [Buffer])
buildLookupTree MergingTree s
tree
let treeResults :: LookupTree LookupAcc
treeResults = LookupAcc -> Key -> [Buffer] -> LookupAcc
lookupBatch LookupAcc
forall a. Maybe a
Nothing Key
k ([Buffer] -> LookupAcc)
-> LookupTree [Buffer] -> LookupTree LookupAcc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LookupTree [Buffer]
treeBatches
LookupResult Value Blob -> ST s (LookupResult Value Blob)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LookupResult Value Blob -> ST s (LookupResult Value Blob))
-> LookupResult Value Blob -> ST s (LookupResult Value Blob)
forall a b. (a -> b) -> a -> b
$ LookupAcc -> LookupResult Value Blob
convertAcc (LookupAcc -> LookupResult Value Blob)
-> LookupAcc -> LookupResult Value Blob
forall a b. (a -> b) -> a -> b
$ LookupTree LookupAcc -> LookupAcc
foldLookupTree (LookupTree LookupAcc -> LookupAcc)
-> LookupTree LookupAcc -> LookupAcc
forall a b. (a -> b) -> a -> b
$
if Buffer -> Bool
forall a. Map Key a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Buffer
wb Bool -> Bool -> Bool
&& [Buffer] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Buffer]
runs
then LookupTree LookupAcc
treeResults
else TreeMergeType -> [LookupTree LookupAcc] -> LookupTree LookupAcc
forall a. TreeMergeType -> [LookupTree a] -> LookupTree a
LookupNode TreeMergeType
MergeLevel [LookupAcc -> LookupTree LookupAcc
forall a. a -> LookupTree a
LookupBatch LookupAcc
acc0, LookupTree LookupAcc
treeResults ]
where
convertAcc :: LookupAcc -> LookupResult Value Blob
convertAcc :: LookupAcc -> LookupResult Value Blob
convertAcc = \case
LookupAcc
Nothing -> LookupResult Value Blob
forall v b. LookupResult v b
NotFound
Just (Insert Value
v Maybe Blob
b) -> Value -> Maybe Blob -> LookupResult Value Blob
forall v b. v -> Maybe b -> LookupResult v b
Found Value
v Maybe Blob
b
Just (Mupsert Value
v) -> Value -> Maybe Blob -> LookupResult Value Blob
forall v b. v -> Maybe b -> LookupResult v b
Found Value
v Maybe Blob
forall a. Maybe a
Nothing
Just Op
Delete -> LookupResult Value Blob
forall v b. LookupResult v b
NotFound
lookupBatch :: LookupAcc -> Key -> [Run] -> LookupAcc
lookupBatch :: LookupAcc -> Key -> [Buffer] -> LookupAcc
lookupBatch LookupAcc
acc Key
k [Buffer]
rs =
let ops :: [Op]
ops = [Op
op | Buffer
r <- [Buffer]
rs, Just Op
op <- [Key -> Buffer -> LookupAcc
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Key
k Buffer
r]]
in (LookupAcc -> Op -> LookupAcc) -> LookupAcc -> [Op] -> LookupAcc
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ((Op -> Op -> Op) -> LookupAcc -> Op -> LookupAcc
updateAcc Op -> Op -> Op
combine) LookupAcc
acc [Op]
ops
data LookupTree a = LookupBatch a
| LookupNode TreeMergeType [LookupTree a]
deriving stock (forall a b. (a -> b) -> LookupTree a -> LookupTree b)
-> (forall a b. a -> LookupTree b -> LookupTree a)
-> Functor LookupTree
forall a b. a -> LookupTree b -> LookupTree a
forall a b. (a -> b) -> LookupTree a -> LookupTree b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> LookupTree a -> LookupTree b
fmap :: forall a b. (a -> b) -> LookupTree a -> LookupTree b
$c<$ :: forall a b. a -> LookupTree b -> LookupTree a
<$ :: forall a b. a -> LookupTree b -> LookupTree a
Functor
buildLookupTree :: MergingTree s -> ST s (LookupTree [Run])
buildLookupTree :: forall s. MergingTree s -> ST s (LookupTree [Buffer])
buildLookupTree = MergingTree s -> ST s (LookupTree [Buffer])
forall s. MergingTree s -> ST s (LookupTree [Buffer])
go
where
go :: MergingTree s -> ST s (LookupTree [Run])
go :: forall s. MergingTree s -> ST s (LookupTree [Buffer])
go (MergingTree STRef s (MergingTreeState s)
treeState) = STRef s (MergingTreeState s) -> ST s (MergingTreeState s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (MergingTreeState s)
treeState ST s (MergingTreeState s)
-> (MergingTreeState s -> ST s (LookupTree [Buffer]))
-> ST s (LookupTree [Buffer])
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
CompletedTreeMerge Buffer
r ->
LookupTree [Buffer] -> ST s (LookupTree [Buffer])
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LookupTree [Buffer] -> ST s (LookupTree [Buffer]))
-> LookupTree [Buffer] -> ST s (LookupTree [Buffer])
forall a b. (a -> b) -> a -> b
$ [Buffer] -> LookupTree [Buffer]
forall a. a -> LookupTree a
LookupBatch [Buffer
r]
OngoingTreeMerge (MergingRun TreeMergeType
mt MergeDebt
_ STRef s MergingRunState
mergeState) ->
STRef s MergingRunState -> ST s MergingRunState
forall s a. STRef s a -> ST s a
readSTRef STRef s MergingRunState
mergeState ST s MergingRunState
-> (MergingRunState -> ST s (LookupTree [Buffer]))
-> ST s (LookupTree [Buffer])
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
CompletedMerge Buffer
r ->
LookupTree [Buffer] -> ST s (LookupTree [Buffer])
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LookupTree [Buffer] -> ST s (LookupTree [Buffer]))
-> LookupTree [Buffer] -> ST s (LookupTree [Buffer])
forall a b. (a -> b) -> a -> b
$ [Buffer] -> LookupTree [Buffer]
forall a. a -> LookupTree a
LookupBatch [Buffer
r]
OngoingMerge MergeCredit
_ [Buffer]
rs Buffer
_ -> case TreeMergeType
mt of
TreeMergeType
MergeLevel -> LookupTree [Buffer] -> ST s (LookupTree [Buffer])
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LookupTree [Buffer] -> ST s (LookupTree [Buffer]))
-> LookupTree [Buffer] -> ST s (LookupTree [Buffer])
forall a b. (a -> b) -> a -> b
$ [Buffer] -> LookupTree [Buffer]
forall a. a -> LookupTree a
LookupBatch [Buffer]
rs
TreeMergeType
MergeUnion -> LookupTree [Buffer] -> ST s (LookupTree [Buffer])
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LookupTree [Buffer] -> ST s (LookupTree [Buffer]))
-> LookupTree [Buffer] -> ST s (LookupTree [Buffer])
forall a b. (a -> b) -> a -> b
$ TreeMergeType -> [LookupTree [Buffer]] -> LookupTree [Buffer]
forall a. TreeMergeType -> [LookupTree a] -> LookupTree a
LookupNode TreeMergeType
MergeUnion ([LookupTree [Buffer]] -> LookupTree [Buffer])
-> [LookupTree [Buffer]] -> LookupTree [Buffer]
forall a b. (a -> b) -> a -> b
$ (Buffer -> LookupTree [Buffer])
-> [Buffer] -> [LookupTree [Buffer]]
forall a b. (a -> b) -> [a] -> [b]
map (\Buffer
r -> [Buffer] -> LookupTree [Buffer]
forall a. a -> LookupTree a
LookupBatch [Buffer
r]) [Buffer]
rs
PendingTreeMerge (PendingLevelMerge [PreExistingRun s]
prs Maybe (MergingTree s)
tree) -> do
LookupTree [Buffer]
preExisting <- [Buffer] -> LookupTree [Buffer]
forall a. a -> LookupTree a
LookupBatch ([Buffer] -> LookupTree [Buffer])
-> ([[Buffer]] -> [Buffer]) -> [[Buffer]] -> LookupTree [Buffer]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Buffer]] -> [Buffer]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Buffer]] -> LookupTree [Buffer])
-> ST s [[Buffer]] -> ST s (LookupTree [Buffer])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
(PreExistingRun s -> ST s [Buffer])
-> [PreExistingRun s] -> ST s [[Buffer]]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse PreExistingRun s -> ST s [Buffer]
forall s. PreExistingRun s -> ST s [Buffer]
flattenPreExistingRun [PreExistingRun s]
prs
case Maybe (MergingTree s)
tree of
Maybe (MergingTree s)
Nothing -> LookupTree [Buffer] -> ST s (LookupTree [Buffer])
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure LookupTree [Buffer]
preExisting
Just MergingTree s
t -> do
LookupTree [Buffer]
lTree <- MergingTree s -> ST s (LookupTree [Buffer])
forall s. MergingTree s -> ST s (LookupTree [Buffer])
go MergingTree s
t
LookupTree [Buffer] -> ST s (LookupTree [Buffer])
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TreeMergeType -> [LookupTree [Buffer]] -> LookupTree [Buffer]
forall a. TreeMergeType -> [LookupTree a] -> LookupTree a
LookupNode TreeMergeType
MergeLevel [LookupTree [Buffer]
preExisting, LookupTree [Buffer]
lTree])
PendingTreeMerge (PendingUnionMerge [MergingTree s]
trees) -> do
TreeMergeType -> [LookupTree [Buffer]] -> LookupTree [Buffer]
forall a. TreeMergeType -> [LookupTree a] -> LookupTree a
LookupNode TreeMergeType
MergeUnion ([LookupTree [Buffer]] -> LookupTree [Buffer])
-> ST s [LookupTree [Buffer]] -> ST s (LookupTree [Buffer])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MergingTree s -> ST s (LookupTree [Buffer]))
-> [MergingTree s] -> ST s [LookupTree [Buffer]]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse MergingTree s -> ST s (LookupTree [Buffer])
forall s. MergingTree s -> ST s (LookupTree [Buffer])
go [MergingTree s]
trees
foldLookupTree :: LookupTree LookupAcc -> LookupAcc
foldLookupTree :: LookupTree LookupAcc -> LookupAcc
foldLookupTree = \case
LookupBatch LookupAcc
acc -> LookupAcc
acc
LookupNode TreeMergeType
mt [LookupTree LookupAcc]
children -> TreeMergeType -> [LookupAcc] -> LookupAcc
mergeAcc TreeMergeType
mt ((LookupTree LookupAcc -> LookupAcc)
-> [LookupTree LookupAcc] -> [LookupAcc]
forall a b. (a -> b) -> [a] -> [b]
map LookupTree LookupAcc -> LookupAcc
foldLookupTree [LookupTree LookupAcc]
children)
newtype NominalCredit = NominalCredit Credit
deriving stock Credit -> NominalCredit -> ShowS
[NominalCredit] -> ShowS
NominalCredit -> String
(Credit -> NominalCredit -> ShowS)
-> (NominalCredit -> String)
-> ([NominalCredit] -> ShowS)
-> Show NominalCredit
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> NominalCredit -> ShowS
showsPrec :: Credit -> NominalCredit -> ShowS
$cshow :: NominalCredit -> String
show :: NominalCredit -> String
$cshowList :: [NominalCredit] -> ShowS
showList :: [NominalCredit] -> ShowS
Show
newtype NominalDebt = NominalDebt Credit
deriving stock Credit -> NominalDebt -> ShowS
[NominalDebt] -> ShowS
NominalDebt -> String
(Credit -> NominalDebt -> ShowS)
-> (NominalDebt -> String)
-> ([NominalDebt] -> ShowS)
-> Show NominalDebt
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> NominalDebt -> ShowS
showsPrec :: Credit -> NominalDebt -> ShowS
$cshow :: NominalDebt -> String
show :: NominalDebt -> String
$cshowList :: [NominalDebt] -> ShowS
showList :: [NominalDebt] -> ShowS
Show
supplyCreditsLevels :: NominalCredit -> Levels s -> ST s ()
supplyCreditsLevels :: forall s. NominalCredit -> Levels s -> ST s ()
supplyCreditsLevels NominalCredit
nominalDeposit =
(Level s -> ST s ()) -> [Level s] -> ST s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ ((Level s -> ST s ()) -> [Level s] -> ST s ())
-> (Level s -> ST s ()) -> [Level s] -> ST s ()
forall a b. (a -> b) -> a -> b
$ \(Level IncomingRun s
ir [Buffer]
_rs) -> do
case IncomingRun s
ir of
Single{} -> () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Merging MergePolicy
_mp NominalDebt
nominalDebt STRef s NominalCredit
nominalCreditVar
mr :: MergingRun LevelMergeType s
mr@(MergingRun LevelMergeType
_ MergeDebt
physicalDebt STRef s MergingRunState
_) -> do
NominalCredit
nominalCredit <- NominalDebt
-> STRef s NominalCredit -> NominalCredit -> ST s NominalCredit
forall s.
NominalDebt
-> STRef s NominalCredit -> NominalCredit -> ST s NominalCredit
depositNominalCredit
NominalDebt
nominalDebt STRef s NominalCredit
nominalCreditVar NominalCredit
nominalDeposit
Credit
physicalCredit <- MergingRun LevelMergeType s -> ST s Credit
forall t s. MergingRun t s -> ST s Credit
suppliedCreditMergingRun MergingRun LevelMergeType s
mr
let !physicalCredit' :: Credit
physicalCredit' = NominalDebt -> MergeDebt -> NominalCredit -> Credit
scaleNominalToPhysicalCredit
NominalDebt
nominalDebt MergeDebt
physicalDebt NominalCredit
nominalCredit
!physicalDeposit :: Credit
physicalDeposit = Credit
physicalCredit' Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- Credit
physicalCredit
Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Credit
physicalDeposit Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
0) (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ do
Credit
leftoverCredits <- Credit -> MergingRun LevelMergeType s -> ST s Credit
forall t s. Credit -> MergingRun t s -> ST s Credit
supplyCreditsMergingRun Credit
physicalDeposit MergingRun LevelMergeType s
mr
Credit
physicalCredit'' <- MergingRun LevelMergeType s -> ST s Credit
forall t s. MergingRun t s -> ST s Credit
suppliedCreditMergingRun MergingRun LevelMergeType s
mr
Bool -> ST s () -> ST s ()
forall a. HasCallStack => Bool -> a -> a
assert (Credit
leftoverCredits Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
0 Bool -> Bool -> Bool
|| Credit
physicalCredit' Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
/= Credit
physicalCredit'')
(() -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
scaleNominalToPhysicalCredit ::
NominalDebt
-> MergeDebt
-> NominalCredit
-> Credit
scaleNominalToPhysicalCredit :: NominalDebt -> MergeDebt -> NominalCredit -> Credit
scaleNominalToPhysicalCredit (NominalDebt Credit
nominalDebt)
MergeDebt { totalDebt :: MergeDebt -> Credit
totalDebt = Credit
physicalDebt }
(NominalCredit Credit
nominalCredit) =
Rational -> Credit
forall b. Integral b => Rational -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Rational -> Credit) -> Rational -> Credit
forall a b. (a -> b) -> a -> b
$ Credit -> Rational
forall a. Real a => a -> Rational
toRational Credit
nominalCredit Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Credit -> Rational
forall a. Real a => a -> Rational
toRational Credit
physicalDebt
Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Credit -> Rational
forall a. Real a => a -> Rational
toRational Credit
nominalDebt
depositNominalCredit ::
NominalDebt
-> STRef s NominalCredit
-> NominalCredit
-> ST s NominalCredit
depositNominalCredit :: forall s.
NominalDebt
-> STRef s NominalCredit -> NominalCredit -> ST s NominalCredit
depositNominalCredit (NominalDebt Credit
nominalDebt)
STRef s NominalCredit
nominalCreditVar
(NominalCredit Credit
deposit) = do
NominalCredit Credit
before <- STRef s NominalCredit -> ST s NominalCredit
forall s a. STRef s a -> ST s a
readSTRef STRef s NominalCredit
nominalCreditVar
let !after :: NominalCredit
after = Credit -> NominalCredit
NominalCredit (Credit -> Credit -> Credit
forall a. Ord a => a -> a -> a
min (Credit
before Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
deposit) Credit
nominalDebt)
STRef s NominalCredit -> NominalCredit -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s NominalCredit
nominalCreditVar NominalCredit
after
NominalCredit -> ST s NominalCredit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure NominalCredit
after
increment :: forall s. Tracer (ST s) Event
-> Counter
-> LSMConfig
-> Run -> Levels s -> UnionLevel s -> ST s (Levels s)
increment :: forall s.
Tracer (ST s) Event
-> Credit
-> LSMConfig
-> Buffer
-> Levels s
-> UnionLevel s
-> ST s (Levels s)
increment Tracer (ST s) Event
tr Credit
sc LSMConfig
conf Buffer
run0 Levels s
ls0 UnionLevel s
ul = do
Credit -> [Buffer] -> Levels s -> ST s (Levels s)
go Credit
1 [Buffer
run0] Levels s
ls0
where
mergeTypeFor :: Levels s -> LevelMergeType
mergeTypeFor :: Levels s -> LevelMergeType
mergeTypeFor Levels s
ls = Levels s -> UnionLevel s -> LevelMergeType
forall s. [Level s] -> UnionLevel s -> LevelMergeType
mergeTypeForLevel Levels s
ls UnionLevel s
ul
go :: Int -> [Run] -> Levels s -> ST s (Levels s)
go :: Credit -> [Buffer] -> Levels s -> ST s (Levels s)
go !Credit
ln [Buffer]
incoming [] = do
let mergePolicy :: MergePolicy
mergePolicy = Credit -> Levels s -> UnionLevel s -> MergePolicy
forall s. Credit -> [Level s] -> UnionLevel s -> MergePolicy
mergePolicyForLevel Credit
ln [] UnionLevel s
ul
Tracer (ST s) EventDetail -> EventDetail -> ST s ()
forall (m :: * -> *) a. Monad m => Tracer m a -> a -> m ()
traceWith Tracer (ST s) EventDetail
tr' EventDetail
AddLevelEvent
IncomingRun s
ir <- Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
forall s.
Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
newLevelMerge Tracer (ST s) EventDetail
tr' LSMConfig
conf Credit
ln MergePolicy
mergePolicy (Levels s -> LevelMergeType
mergeTypeFor []) [Buffer]
incoming
Levels s -> ST s (Levels s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (IncomingRun s -> [Buffer] -> Level s
forall s. IncomingRun s -> [Buffer] -> Level s
Level IncomingRun s
ir [] Level s -> Levels s -> Levels s
forall a. a -> [a] -> [a]
: [])
where
tr' :: Tracer (ST s) EventDetail
tr' = (EventDetail -> Event)
-> Tracer (ST s) Event -> Tracer (ST s) EventDetail
forall a' a. (a' -> a) -> Tracer (ST s) a -> Tracer (ST s) a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap (Credit -> Credit -> EventDetail -> Event
forall e. Credit -> Credit -> e -> EventAt e
EventAt Credit
sc Credit
ln) Tracer (ST s) Event
tr
go !Credit
ln [Buffer]
incoming (Level IncomingRun s
ir [Buffer]
rs : Levels s
ls) = do
Buffer
r <- case IncomingRun s
ir of
Single Buffer
r -> Buffer -> ST s Buffer
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Buffer
r
Merging MergePolicy
mergePolicy NominalDebt
_ STRef s NominalCredit
_ MergingRun LevelMergeType s
mr -> do
Buffer
r <- MergingRun LevelMergeType s -> ST s Buffer
forall t s. HasCallStack => MergingRun t s -> ST s Buffer
expectCompletedMergingRun MergingRun LevelMergeType s
mr
Tracer (ST s) EventDetail -> EventDetail -> ST s ()
forall (m :: * -> *) a. Monad m => Tracer m a -> a -> m ()
traceWith Tracer (ST s) EventDetail
tr' MergeCompletedEvent {
MergePolicy
mergePolicy :: MergePolicy
mergePolicy :: MergePolicy
mergePolicy,
mergeType :: LevelMergeType
mergeType = let MergingRun LevelMergeType
mt MergeDebt
_ STRef s MergingRunState
_ = MergingRun LevelMergeType s
mr in LevelMergeType
mt,
mergeSize :: Credit
mergeSize = Buffer -> Credit
runSize Buffer
r
}
Buffer -> ST s Buffer
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Buffer
r
let resident :: [Buffer]
resident = Buffer
rBuffer -> [Buffer] -> [Buffer]
forall a. a -> [a] -> [a]
:[Buffer]
rs
case Credit -> Levels s -> UnionLevel s -> MergePolicy
forall s. Credit -> [Level s] -> UnionLevel s -> MergePolicy
mergePolicyForLevel Credit
ln Levels s
ls UnionLevel s
ul of
MergePolicy
MergePolicyTiering | HasCallStack =>
MergePolicy -> LSMConfig -> Credit -> Buffer -> Bool
MergePolicy -> LSMConfig -> Credit -> Buffer -> Bool
runTooSmallForLevel MergePolicy
MergePolicyTiering LSMConfig
conf Credit
ln Buffer
r -> do
IncomingRun s
ir' <- Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
forall s.
Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
newLevelMerge Tracer (ST s) EventDetail
tr' LSMConfig
conf Credit
ln MergePolicy
MergePolicyTiering (Levels s -> LevelMergeType
mergeTypeFor Levels s
ls) ([Buffer]
incoming [Buffer] -> [Buffer] -> [Buffer]
forall a. [a] -> [a] -> [a]
++ [Buffer
r])
Levels s -> ST s (Levels s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (IncomingRun s -> [Buffer] -> Level s
forall s. IncomingRun s -> [Buffer] -> Level s
Level IncomingRun s
ir' [Buffer]
rs Level s -> Levels s -> Levels s
forall a. a -> [a] -> [a]
: Levels s
ls)
MergePolicy
MergePolicyTiering | LSMConfig -> Credit -> [Buffer] -> [Buffer] -> Bool
levelIsFullTiering LSMConfig
conf Credit
ln [Buffer]
incoming [Buffer]
resident -> do
IncomingRun s
ir' <- Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
forall s.
Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
newLevelMerge Tracer (ST s) EventDetail
tr' LSMConfig
conf Credit
ln MergePolicy
MergePolicyTiering LevelMergeType
MergeMidLevel [Buffer]
incoming
Levels s
ls' <- Credit -> [Buffer] -> Levels s -> ST s (Levels s)
go (Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1) [Buffer]
resident Levels s
ls
Levels s -> ST s (Levels s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (IncomingRun s -> [Buffer] -> Level s
forall s. IncomingRun s -> [Buffer] -> Level s
Level IncomingRun s
ir' [] Level s -> Levels s -> Levels s
forall a. a -> [a] -> [a]
: Levels s
ls')
MergePolicy
MergePolicyTiering -> do
IncomingRun s
ir' <- Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
forall s.
Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
newLevelMerge Tracer (ST s) EventDetail
tr' LSMConfig
conf Credit
ln MergePolicy
MergePolicyTiering (Levels s -> LevelMergeType
mergeTypeFor Levels s
ls) [Buffer]
incoming
Tracer (ST s) EventDetail -> EventDetail -> ST s ()
forall (m :: * -> *) a. Monad m => Tracer m a -> a -> m ()
traceWith Tracer (ST s) EventDetail
tr' (Credit -> EventDetail
AddRunEvent ([Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
resident))
Levels s -> ST s (Levels s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (IncomingRun s -> [Buffer] -> Level s
forall s. IncomingRun s -> [Buffer] -> Level s
Level IncomingRun s
ir' [Buffer]
resident Level s -> Levels s -> Levels s
forall a. a -> [a] -> [a]
: Levels s
ls)
MergePolicy
MergePolicyLevelling | LSMConfig -> Credit -> [Buffer] -> Buffer -> Bool
levelIsFullLevelling LSMConfig
conf Credit
ln [Buffer]
incoming Buffer
r -> do
Bool -> ST s () -> ST s ()
forall a. HasCallStack => Bool -> a -> a
assert ([Buffer] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Buffer]
rs Bool -> Bool -> Bool
&& Levels s -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Levels s
ls) (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
IncomingRun s
ir' <- Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
forall s.
Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
newLevelMerge Tracer (ST s) EventDetail
tr' LSMConfig
conf Credit
ln MergePolicy
MergePolicyTiering LevelMergeType
MergeMidLevel [Buffer]
incoming
Levels s
ls' <- Credit -> [Buffer] -> Levels s -> ST s (Levels s)
go (Credit
lnCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
+Credit
1) [Buffer
r] []
Levels s -> ST s (Levels s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (IncomingRun s -> [Buffer] -> Level s
forall s. IncomingRun s -> [Buffer] -> Level s
Level IncomingRun s
ir' [] Level s -> Levels s -> Levels s
forall a. a -> [a] -> [a]
: Levels s
ls')
MergePolicy
MergePolicyLevelling -> do
Bool -> ST s () -> ST s ()
forall a. HasCallStack => Bool -> a -> a
assert ([Buffer] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Buffer]
rs Bool -> Bool -> Bool
&& Levels s -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Levels s
ls) (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
IncomingRun s
ir' <- Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
forall s.
Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
newLevelMerge Tracer (ST s) EventDetail
tr' LSMConfig
conf Credit
ln MergePolicy
MergePolicyLevelling (Levels s -> LevelMergeType
mergeTypeFor Levels s
ls)
([Buffer]
incoming [Buffer] -> [Buffer] -> [Buffer]
forall a. [a] -> [a] -> [a]
++ [Buffer
r])
Levels s -> ST s (Levels s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (IncomingRun s -> [Buffer] -> Level s
forall s. IncomingRun s -> [Buffer] -> Level s
Level IncomingRun s
ir' [] Level s -> Levels s -> Levels s
forall a. a -> [a] -> [a]
: [])
where
tr' :: Tracer (ST s) EventDetail
tr' = (EventDetail -> Event)
-> Tracer (ST s) Event -> Tracer (ST s) EventDetail
forall a' a. (a' -> a) -> Tracer (ST s) a -> Tracer (ST s) a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap (Credit -> Credit -> EventDetail -> Event
forall e. Credit -> Credit -> e -> EventAt e
EventAt Credit
sc Credit
ln) Tracer (ST s) Event
tr
newLevelMerge :: Tracer (ST s) EventDetail
-> LSMConfig
-> Int -> MergePolicy -> LevelMergeType
-> [Run] -> ST s (IncomingRun s)
newLevelMerge :: forall s.
Tracer (ST s) EventDetail
-> LSMConfig
-> Credit
-> MergePolicy
-> LevelMergeType
-> [Buffer]
-> ST s (IncomingRun s)
newLevelMerge Tracer (ST s) EventDetail
_ LSMConfig
_ Credit
_ MergePolicy
_ LevelMergeType
_ [Buffer
r] = IncomingRun s -> ST s (IncomingRun s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Buffer -> IncomingRun s
forall s. Buffer -> IncomingRun s
Single Buffer
r)
newLevelMerge Tracer (ST s) EventDetail
tr conf :: LSMConfig
conf@LSMConfig{Credit
configMaxWriteBufferSize :: LSMConfig -> Credit
configSizeRatio :: LSMConfig -> Credit
configMaxWriteBufferSize :: Credit
configSizeRatio :: Credit
..} Credit
level MergePolicy
mergePolicy LevelMergeType
mergeType [Buffer]
rs = do
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST ([Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
rs Credit -> [Credit] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Credit
configSizeRatio, Credit
configSizeRatio Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
1])
mergingRun :: MergingRun LevelMergeType s
mergingRun@(MergingRun LevelMergeType
_ MergeDebt
physicalDebt STRef s MergingRunState
_) <- LevelMergeType -> [Buffer] -> ST s (MergingRun LevelMergeType s)
forall t s. IsMergeType t => t -> [Buffer] -> ST s (MergingRun t s)
newMergingRun LevelMergeType
mergeType [Buffer]
rs
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (MergeDebt -> Credit
totalDebt MergeDebt
physicalDebt Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
maxPhysicalDebt)
Tracer (ST s) EventDetail -> EventDetail -> ST s ()
forall (m :: * -> *) a. Monad m => Tracer m a -> a -> m ()
traceWith Tracer (ST s) EventDetail
tr MergeStartedEvent {
MergePolicy
mergePolicy :: MergePolicy
mergePolicy :: MergePolicy
mergePolicy,
LevelMergeType
mergeType :: LevelMergeType
mergeType :: LevelMergeType
mergeType,
mergeDebt :: Credit
mergeDebt = MergeDebt -> Credit
totalDebt MergeDebt
physicalDebt,
mergeRunsSize :: [Credit]
mergeRunsSize = (Buffer -> Credit) -> [Buffer] -> [Credit]
forall a b. (a -> b) -> [a] -> [b]
map Buffer -> Credit
runSize [Buffer]
rs
}
STRef s NominalCredit
nominalCreditVar <- NominalCredit -> ST s (STRef s NominalCredit)
forall a s. a -> ST s (STRef s a)
newSTRef (Credit -> NominalCredit
NominalCredit Credit
0)
IncomingRun s -> ST s (IncomingRun s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (MergePolicy
-> NominalDebt
-> STRef s NominalCredit
-> MergingRun LevelMergeType s
-> IncomingRun s
forall s.
MergePolicy
-> NominalDebt
-> STRef s NominalCredit
-> MergingRun LevelMergeType s
-> IncomingRun s
Merging MergePolicy
mergePolicy NominalDebt
nominalDebt STRef s NominalCredit
nominalCreditVar MergingRun LevelMergeType s
mergingRun)
where
nominalDebt :: NominalDebt
nominalDebt = Credit -> NominalDebt
NominalDebt (HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize MergePolicy
MergePolicyTiering LSMConfig
conf Credit
level)
maxPhysicalDebt :: Credit
maxPhysicalDebt =
case MergePolicy
mergePolicy of
MergePolicy
MergePolicyLevelling ->
Credit
configSizeRatio Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
* HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize MergePolicy
MergePolicyTiering LSMConfig
conf (Credit
levelCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
-Credit
1)
Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize MergePolicy
MergePolicyLevelling LSMConfig
conf Credit
level
MergePolicy
MergePolicyTiering ->
[Buffer] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [Buffer]
rs Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
* HasCallStack => MergePolicy -> LSMConfig -> Credit -> Credit
MergePolicy -> LSMConfig -> Credit -> Credit
levelNumberToMaxRunSize MergePolicy
MergePolicyTiering LSMConfig
conf (Credit
levelCredit -> Credit -> Credit
forall a. Num a => a -> a -> a
-Credit
1)
newPendingLevelMerge :: [IncomingRun s]
-> Maybe (MergingTree s)
-> ST s (Maybe (MergingTree s))
newPendingLevelMerge :: forall s.
[IncomingRun s]
-> Maybe (MergingTree s) -> ST s (Maybe (MergingTree s))
newPendingLevelMerge [] Maybe (MergingTree s)
t = Maybe (MergingTree s) -> ST s (Maybe (MergingTree s))
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (MergingTree s)
t
newPendingLevelMerge [Single Buffer
r] Maybe (MergingTree s)
Nothing =
MergingTree s -> Maybe (MergingTree s)
forall a. a -> Maybe a
Just (MergingTree s -> Maybe (MergingTree s))
-> (STRef s (MergingTreeState s) -> MergingTree s)
-> STRef s (MergingTreeState s)
-> Maybe (MergingTree s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STRef s (MergingTreeState s) -> MergingTree s
forall s. STRef s (MergingTreeState s) -> MergingTree s
MergingTree (STRef s (MergingTreeState s) -> Maybe (MergingTree s))
-> ST s (STRef s (MergingTreeState s))
-> ST s (Maybe (MergingTree s))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MergingTreeState s -> ST s (STRef s (MergingTreeState s))
forall a s. a -> ST s (STRef s a)
newSTRef (Buffer -> MergingTreeState s
forall s. Buffer -> MergingTreeState s
CompletedTreeMerge Buffer
r)
newPendingLevelMerge [Merging{}] Maybe (MergingTree s)
Nothing =
String -> ST s (Maybe (MergingTree s))
forall a. HasCallStack => String -> a
error String
"newPendingLevelMerge: singleton Merging run"
newPendingLevelMerge [IncomingRun s]
irs Maybe (MergingTree s)
tree = do
let prs :: [PreExistingRun s]
prs = (IncomingRun s -> PreExistingRun s)
-> [IncomingRun s] -> [PreExistingRun s]
forall a b. (a -> b) -> [a] -> [b]
map IncomingRun s -> PreExistingRun s
forall {s}. IncomingRun s -> PreExistingRun s
incomingToPreExistingRun [IncomingRun s]
irs
st :: MergingTreeState s
st = PendingMerge s -> MergingTreeState s
forall s. PendingMerge s -> MergingTreeState s
PendingTreeMerge ([PreExistingRun s] -> Maybe (MergingTree s) -> PendingMerge s
forall s.
[PreExistingRun s] -> Maybe (MergingTree s) -> PendingMerge s
PendingLevelMerge [PreExistingRun s]
prs Maybe (MergingTree s)
tree)
MergingTree s -> Maybe (MergingTree s)
forall a. a -> Maybe a
Just (MergingTree s -> Maybe (MergingTree s))
-> (STRef s (MergingTreeState s) -> MergingTree s)
-> STRef s (MergingTreeState s)
-> Maybe (MergingTree s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STRef s (MergingTreeState s) -> MergingTree s
forall s. STRef s (MergingTreeState s) -> MergingTree s
MergingTree (STRef s (MergingTreeState s) -> Maybe (MergingTree s))
-> ST s (STRef s (MergingTreeState s))
-> ST s (Maybe (MergingTree s))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MergingTreeState s -> ST s (STRef s (MergingTreeState s))
forall a s. a -> ST s (STRef s a)
newSTRef MergingTreeState s
st
where
incomingToPreExistingRun :: IncomingRun s -> PreExistingRun s
incomingToPreExistingRun (Single Buffer
r) = Buffer -> PreExistingRun s
forall s. Buffer -> PreExistingRun s
PreExistingRun Buffer
r
incomingToPreExistingRun (Merging MergePolicy
_ NominalDebt
_ STRef s NominalCredit
_ MergingRun LevelMergeType s
mr) = MergingRun LevelMergeType s -> PreExistingRun s
forall s. MergingRun LevelMergeType s -> PreExistingRun s
PreExistingMergingRun MergingRun LevelMergeType s
mr
newPendingUnionMerge :: [MergingTree s] -> ST s (Maybe (MergingTree s))
newPendingUnionMerge :: forall s. [MergingTree s] -> ST s (Maybe (MergingTree s))
newPendingUnionMerge [] = Maybe (MergingTree s) -> ST s (Maybe (MergingTree s))
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (MergingTree s)
forall a. Maybe a
Nothing
newPendingUnionMerge [MergingTree s
t] = Maybe (MergingTree s) -> ST s (Maybe (MergingTree s))
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (MergingTree s -> Maybe (MergingTree s)
forall a. a -> Maybe a
Just MergingTree s
t)
newPendingUnionMerge [MergingTree s]
trees = do
let st :: MergingTreeState s
st = PendingMerge s -> MergingTreeState s
forall s. PendingMerge s -> MergingTreeState s
PendingTreeMerge ([MergingTree s] -> PendingMerge s
forall s. [MergingTree s] -> PendingMerge s
PendingUnionMerge [MergingTree s]
trees)
MergingTree s -> Maybe (MergingTree s)
forall a. a -> Maybe a
Just (MergingTree s -> Maybe (MergingTree s))
-> (STRef s (MergingTreeState s) -> MergingTree s)
-> STRef s (MergingTreeState s)
-> Maybe (MergingTree s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STRef s (MergingTreeState s) -> MergingTree s
forall s. STRef s (MergingTreeState s) -> MergingTree s
MergingTree (STRef s (MergingTreeState s) -> Maybe (MergingTree s))
-> ST s (STRef s (MergingTreeState s))
-> ST s (Maybe (MergingTree s))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MergingTreeState s -> ST s (STRef s (MergingTreeState s))
forall a s. a -> ST s (STRef s a)
newSTRef MergingTreeState s
st
contentToMergingTree :: LSMContent s -> ST s (Maybe (MergingTree s))
contentToMergingTree :: forall s. LSMContent s -> ST s (Maybe (MergingTree s))
contentToMergingTree (LSMContent Buffer
wb Levels s
ls UnionLevel s
ul) =
[IncomingRun s]
-> Maybe (MergingTree s) -> ST s (Maybe (MergingTree s))
forall s.
[IncomingRun s]
-> Maybe (MergingTree s) -> ST s (Maybe (MergingTree s))
newPendingLevelMerge ([IncomingRun s]
buffers [IncomingRun s] -> [IncomingRun s] -> [IncomingRun s]
forall a. [a] -> [a] -> [a]
++ [IncomingRun s]
levels) Maybe (MergingTree s)
trees
where
buffers :: [IncomingRun s]
buffers
| Buffer -> Credit
bufferSize Buffer
wb Credit -> Credit -> Bool
forall a. Eq a => a -> a -> Bool
== Credit
0 = []
| Bool
otherwise = [Buffer -> IncomingRun s
forall s. Buffer -> IncomingRun s
Single (Buffer -> Buffer
bufferToRun Buffer
wb)]
levels :: [IncomingRun s]
levels = ((Level s -> [IncomingRun s]) -> Levels s -> [IncomingRun s])
-> Levels s -> (Level s -> [IncomingRun s]) -> [IncomingRun s]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Level s -> [IncomingRun s]) -> Levels s -> [IncomingRun s]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Levels s
ls ((Level s -> [IncomingRun s]) -> [IncomingRun s])
-> (Level s -> [IncomingRun s]) -> [IncomingRun s]
forall a b. (a -> b) -> a -> b
$ \(Level IncomingRun s
ir [Buffer]
rs) -> IncomingRun s
ir IncomingRun s -> [IncomingRun s] -> [IncomingRun s]
forall a. a -> [a] -> [a]
: (Buffer -> IncomingRun s) -> [Buffer] -> [IncomingRun s]
forall a b. (a -> b) -> [a] -> [b]
map Buffer -> IncomingRun s
forall s. Buffer -> IncomingRun s
Single [Buffer]
rs
trees :: Maybe (MergingTree s)
trees = case UnionLevel s
ul of
UnionLevel s
NoUnion -> Maybe (MergingTree s)
forall a. Maybe a
Nothing
Union MergingTree s
t STRef s Credit
_ -> MergingTree s -> Maybe (MergingTree s)
forall a. a -> Maybe a
Just MergingTree s
t
type Size = Int
remainingDebtMergingTree :: MergingTree s -> ST s (Debt, Size)
remainingDebtMergingTree :: forall s. MergingTree s -> ST s (Credit, Credit)
remainingDebtMergingTree (MergingTree STRef s (MergingTreeState s)
ref) =
STRef s (MergingTreeState s) -> ST s (MergingTreeState s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (MergingTreeState s)
ref ST s (MergingTreeState s)
-> (MergingTreeState s -> ST s (Credit, Credit))
-> ST s (Credit, Credit)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
CompletedTreeMerge Buffer
r -> (Credit, Credit) -> ST s (Credit, Credit)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
0, Buffer -> Credit
runSize Buffer
r)
OngoingTreeMerge MergingRun TreeMergeType s
mr -> (Credit, Credit) -> (Credit, Credit)
forall {a} {b}. Num a => (a, b) -> (a, b)
addDebtOne ((Credit, Credit) -> (Credit, Credit))
-> ST s (Credit, Credit) -> ST s (Credit, Credit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MergingRun TreeMergeType s -> ST s (Credit, Credit)
forall t s. MergingRun t s -> ST s (Credit, Credit)
remainingDebtMergingRun MergingRun TreeMergeType s
mr
PendingTreeMerge PendingMerge s
pm -> (Credit, Credit) -> (Credit, Credit)
forall {a} {b}. Num a => (a, b) -> (a, b)
addDebtOne ((Credit, Credit) -> (Credit, Credit))
-> ST s (Credit, Credit) -> ST s (Credit, Credit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PendingMerge s -> ST s (Credit, Credit)
forall s. PendingMerge s -> ST s (Credit, Credit)
remainingDebtPendingMerge PendingMerge s
pm
where
addDebtOne :: (a, b) -> (a, b)
addDebtOne (a
debt, b
size) = (a
debt a -> a -> a
forall a. Num a => a -> a -> a
+ a
1, b
size)
remainingDebtPendingMerge :: PendingMerge s -> ST s (Debt, Size)
remainingDebtPendingMerge :: forall s. PendingMerge s -> ST s (Credit, Credit)
remainingDebtPendingMerge (PendingMerge TreeMergeType
_ [PreExistingRun s]
prs [MergingTree s]
trees) = do
([Credit]
debts, [Credit]
sizes) <- [(Credit, Credit)] -> ([Credit], [Credit])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(Credit, Credit)] -> ([Credit], [Credit]))
-> ([[(Credit, Credit)]] -> [(Credit, Credit)])
-> [[(Credit, Credit)]]
-> ([Credit], [Credit])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[(Credit, Credit)]] -> [(Credit, Credit)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[(Credit, Credit)]] -> ([Credit], [Credit]))
-> ST s [[(Credit, Credit)]] -> ST s ([Credit], [Credit])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ST s [(Credit, Credit)]] -> ST s [[(Credit, Credit)]]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence
[ (PreExistingRun s -> ST s (Credit, Credit))
-> [PreExistingRun s] -> ST s [(Credit, Credit)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse PreExistingRun s -> ST s (Credit, Credit)
forall {s}. PreExistingRun s -> ST s (Credit, Credit)
remainingDebtPreExistingRun [PreExistingRun s]
prs
, (MergingTree s -> ST s (Credit, Credit))
-> [MergingTree s] -> ST s [(Credit, Credit)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse MergingTree s -> ST s (Credit, Credit)
forall s. MergingTree s -> ST s (Credit, Credit)
remainingDebtMergingTree [MergingTree s]
trees
]
let totalSize :: Credit
totalSize = [Credit] -> Credit
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Credit]
sizes
let totalDebt :: Credit
totalDebt = [Credit] -> Credit
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Credit]
debts Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
totalSize
(Credit, Credit) -> ST s (Credit, Credit)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
totalDebt, Credit
totalSize)
where
remainingDebtPreExistingRun :: PreExistingRun s -> ST s (Credit, Credit)
remainingDebtPreExistingRun = \case
PreExistingRun Buffer
r -> (Credit, Credit) -> ST s (Credit, Credit)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
0, Buffer -> Credit
runSize Buffer
r)
PreExistingMergingRun MergingRun LevelMergeType s
mr -> MergingRun LevelMergeType s -> ST s (Credit, Credit)
forall t s. MergingRun t s -> ST s (Credit, Credit)
remainingDebtMergingRun MergingRun LevelMergeType s
mr
remainingDebtMergingRun :: MergingRun t s -> ST s (Debt, Size)
remainingDebtMergingRun :: forall t s. MergingRun t s -> ST s (Credit, Credit)
remainingDebtMergingRun (MergingRun t
_ MergeDebt
d STRef s MergingRunState
ref) =
STRef s MergingRunState -> ST s MergingRunState
forall s a. STRef s a -> ST s a
readSTRef STRef s MergingRunState
ref ST s MergingRunState
-> (MergingRunState -> ST s (Credit, Credit))
-> ST s (Credit, Credit)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
CompletedMerge Buffer
r ->
(Credit, Credit) -> ST s (Credit, Credit)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
0, Buffer -> Credit
runSize Buffer
r)
OngoingMerge MergeCredit
c [Buffer]
inputRuns Buffer
_ ->
(Credit, Credit) -> ST s (Credit, Credit)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HasCallStack => MergeDebt -> MergeCredit -> Credit
MergeDebt -> MergeCredit -> Credit
mergeDebtLeft MergeDebt
d MergeCredit
c, [Credit] -> Credit
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((Buffer -> Credit) -> [Buffer] -> [Credit]
forall a b. (a -> b) -> [a] -> [b]
map Buffer -> Credit
runSize [Buffer]
inputRuns))
checked :: HasCallStack
=> (a -> ST s (Debt, Size))
-> (Credit -> a -> ST s Credit)
-> Credit -> a -> ST s Credit
checked :: forall a s.
HasCallStack =>
(a -> ST s (Credit, Credit))
-> (Credit -> a -> ST s Credit) -> Credit -> a -> ST s Credit
checked a -> ST s (Credit, Credit)
query Credit -> a -> ST s Credit
supply Credit
credits a
x = do
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ Credit
credits Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
> Credit
0
Credit
debt <- (Credit, Credit) -> Credit
forall a b. (a, b) -> a
fst ((Credit, Credit) -> Credit)
-> ST s (Credit, Credit) -> ST s Credit
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> ST s (Credit, Credit)
query a
x
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ Credit
debt Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0
Credit
c' <- Credit -> a -> ST s Credit
supply Credit
credits a
x
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ Credit
c' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
credits
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ Credit
c' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0
Credit
debt' <- (Credit, Credit) -> Credit
forall a b. (a, b) -> a
fst ((Credit, Credit) -> Credit)
-> ST s (Credit, Credit) -> ST s Credit
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> ST s (Credit, Credit)
query a
x
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ Credit
debt' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Bool -> ST s ()) -> Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ Credit
debt' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
debt Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- (Credit
credits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- Credit
c')
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
c'
supplyCreditsMergingTree :: Credit -> MergingTree s -> ST s Credit
supplyCreditsMergingTree :: forall s. Credit -> MergingTree s -> ST s Credit
supplyCreditsMergingTree = (MergingTree s -> ST s (Credit, Credit))
-> (Credit -> MergingTree s -> ST s Credit)
-> Credit
-> MergingTree s
-> ST s Credit
forall a s.
HasCallStack =>
(a -> ST s (Credit, Credit))
-> (Credit -> a -> ST s Credit) -> Credit -> a -> ST s Credit
checked MergingTree s -> ST s (Credit, Credit)
forall s. MergingTree s -> ST s (Credit, Credit)
remainingDebtMergingTree ((Credit -> MergingTree s -> ST s Credit)
-> Credit -> MergingTree s -> ST s Credit)
-> (Credit -> MergingTree s -> ST s Credit)
-> Credit
-> MergingTree s
-> ST s Credit
forall a b. (a -> b) -> a -> b
$ \Credit
credits (MergingTree STRef s (MergingTreeState s)
ref) -> do
MergingTreeState s
treeState <- STRef s (MergingTreeState s) -> ST s (MergingTreeState s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (MergingTreeState s)
ref
(!Credit
c', !MergingTreeState s
treeState') <- Credit -> MergingTreeState s -> ST s (Credit, MergingTreeState s)
forall s.
Credit -> MergingTreeState s -> ST s (Credit, MergingTreeState s)
supplyCreditsMergingTreeState Credit
credits MergingTreeState s
treeState
STRef s (MergingTreeState s) -> MergingTreeState s -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s (MergingTreeState s)
ref MergingTreeState s
treeState'
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
c'
supplyCreditsMergingTreeState :: Credit -> MergingTreeState s
-> ST s (Credit, MergingTreeState s)
supplyCreditsMergingTreeState :: forall s.
Credit -> MergingTreeState s -> ST s (Credit, MergingTreeState s)
supplyCreditsMergingTreeState Credit
credits !MergingTreeState s
state = do
Bool -> ST s ()
forall s. HasCallStack => Bool -> ST s ()
assertST (Credit
credits Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
>= Credit
0)
case MergingTreeState s
state of
CompletedTreeMerge{} ->
(Credit, MergingTreeState s) -> ST s (Credit, MergingTreeState s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
credits, MergingTreeState s
state)
OngoingTreeMerge MergingRun TreeMergeType s
mr -> do
Credit
c' <- Credit -> MergingRun TreeMergeType s -> ST s Credit
forall t s. Credit -> MergingRun t s -> ST s Credit
supplyCreditsMergingRun Credit
credits MergingRun TreeMergeType s
mr
if Credit
c' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
0
then (Credit, MergingTreeState s) -> ST s (Credit, MergingTreeState s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
0, MergingTreeState s
state)
else do
Buffer
r <- MergingRun TreeMergeType s -> ST s Buffer
forall t s. HasCallStack => MergingRun t s -> ST s Buffer
expectCompletedMergingRun MergingRun TreeMergeType s
mr
(Credit, MergingTreeState s) -> ST s (Credit, MergingTreeState s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
c', Buffer -> MergingTreeState s
forall s. Buffer -> MergingTreeState s
CompletedTreeMerge Buffer
r)
PendingTreeMerge PendingMerge s
pm -> do
Credit
c' <- Credit -> PendingMerge s -> ST s Credit
forall s. Credit -> PendingMerge s -> ST s Credit
supplyCreditsPendingMerge Credit
credits PendingMerge s
pm
if Credit
c' Credit -> Credit -> Bool
forall a. Ord a => a -> a -> Bool
<= Credit
0
then
(Credit, MergingTreeState s) -> ST s (Credit, MergingTreeState s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
c', MergingTreeState s
state)
else do
(TreeMergeType
mergeType, [Buffer]
rs) <- PendingMerge s -> ST s (TreeMergeType, [Buffer])
forall s.
HasCallStack =>
PendingMerge s -> ST s (TreeMergeType, [Buffer])
expectCompletedChildren PendingMerge s
pm
case [Buffer]
rs of
[Buffer
r] -> (Credit, MergingTreeState s) -> ST s (Credit, MergingTreeState s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
c', Buffer -> MergingTreeState s
forall s. Buffer -> MergingTreeState s
CompletedTreeMerge Buffer
r)
[Buffer]
_ -> do
MergingTreeState s
state' <- MergingRun TreeMergeType s -> MergingTreeState s
forall s. MergingRun TreeMergeType s -> MergingTreeState s
OngoingTreeMerge (MergingRun TreeMergeType s -> MergingTreeState s)
-> ST s (MergingRun TreeMergeType s) -> ST s (MergingTreeState s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TreeMergeType -> [Buffer] -> ST s (MergingRun TreeMergeType s)
forall t s. IsMergeType t => t -> [Buffer] -> ST s (MergingRun t s)
newMergingRun TreeMergeType
mergeType [Buffer]
rs
Credit -> MergingTreeState s -> ST s (Credit, MergingTreeState s)
forall s.
Credit -> MergingTreeState s -> ST s (Credit, MergingTreeState s)
supplyCreditsMergingTreeState Credit
c' MergingTreeState s
state'
supplyCreditsPendingMerge :: Credit -> PendingMerge s -> ST s Credit
supplyCreditsPendingMerge :: forall s. Credit -> PendingMerge s -> ST s Credit
supplyCreditsPendingMerge = (PendingMerge s -> ST s (Credit, Credit))
-> (Credit -> PendingMerge s -> ST s Credit)
-> Credit
-> PendingMerge s
-> ST s Credit
forall a s.
HasCallStack =>
(a -> ST s (Credit, Credit))
-> (Credit -> a -> ST s Credit) -> Credit -> a -> ST s Credit
checked PendingMerge s -> ST s (Credit, Credit)
forall s. PendingMerge s -> ST s (Credit, Credit)
remainingDebtPendingMerge ((Credit -> PendingMerge s -> ST s Credit)
-> Credit -> PendingMerge s -> ST s Credit)
-> (Credit -> PendingMerge s -> ST s Credit)
-> Credit
-> PendingMerge s
-> ST s Credit
forall a b. (a -> b) -> a -> b
$ \Credit
credits -> \case
PendingLevelMerge [PreExistingRun s]
prs Maybe (MergingTree s)
tree ->
(Credit -> PreExistingRun s -> ST s Credit)
-> [PreExistingRun s] -> Credit -> ST s Credit
forall a s.
(Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
leftToRight Credit -> PreExistingRun s -> ST s Credit
forall {s}. Credit -> PreExistingRun s -> ST s Credit
supplyPreExistingRun [PreExistingRun s]
prs Credit
credits
ST s Credit -> (Credit -> ST s Credit) -> ST s Credit
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Credit -> MergingTree s -> ST s Credit)
-> [MergingTree s] -> Credit -> ST s Credit
forall a s.
(Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
leftToRight Credit -> MergingTree s -> ST s Credit
forall s. Credit -> MergingTree s -> ST s Credit
supplyCreditsMergingTree (Maybe (MergingTree s) -> [MergingTree s]
forall a. Maybe a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Maybe (MergingTree s)
tree)
PendingUnionMerge [MergingTree s]
trees ->
(Credit -> MergingTree s -> ST s Credit)
-> [MergingTree s] -> Credit -> ST s Credit
forall a s.
(Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
splitEqually Credit -> MergingTree s -> ST s Credit
forall s. Credit -> MergingTree s -> ST s Credit
supplyCreditsMergingTree [MergingTree s]
trees Credit
credits
where
supplyPreExistingRun :: Credit -> PreExistingRun s -> ST s Credit
supplyPreExistingRun Credit
c = \case
PreExistingRun Buffer
_r -> Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
c
PreExistingMergingRun MergingRun LevelMergeType s
mr -> Credit -> MergingRun LevelMergeType s -> ST s Credit
forall t s. Credit -> MergingRun t s -> ST s Credit
supplyCreditsMergingRun Credit
c MergingRun LevelMergeType s
mr
leftToRight :: (Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
leftToRight :: forall a s.
(Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
leftToRight Credit -> a -> ST s Credit
_ [a]
_ Credit
0 = Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
0
leftToRight Credit -> a -> ST s Credit
_ [] Credit
c = Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
c
leftToRight Credit -> a -> ST s Credit
f (a
x:[a]
xs) Credit
c = Credit -> a -> ST s Credit
f Credit
c a
x ST s Credit -> (Credit -> ST s Credit) -> ST s Credit
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
forall a s.
(Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
leftToRight Credit -> a -> ST s Credit
f [a]
xs
splitEqually :: (Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
splitEqually :: forall a s.
(Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
splitEqually Credit -> a -> ST s Credit
f [a]
xs Credit
credits =
(Credit -> a -> ST s Credit) -> Credit -> [a] -> ST s Credit
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Credit -> a -> ST s Credit
supply Credit
credits [a]
xs ST s Credit -> (Credit -> ST s Credit) -> ST s Credit
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
forall a s.
(Credit -> a -> ST s Credit) -> [a] -> Credit -> ST s Credit
leftToRight Credit -> a -> ST s Credit
f [a]
xs
where
!n :: Credit
n = [a] -> Credit
forall a. [a] -> Credit
forall (t :: * -> *) a. Foldable t => t a -> Credit
length [a]
xs
!k :: Credit
k = (Credit
credits Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ (Credit
n Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- Credit
1)) Credit -> Credit -> Credit
forall a. Integral a => a -> a -> a
`div` Credit
n
supply :: Credit -> a -> ST s Credit
supply Credit
0 a
_ = Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Credit
0
supply Credit
c a
t = do
let creditsToSpend :: Credit
creditsToSpend = Credit -> Credit -> Credit
forall a. Ord a => a -> a -> a
min Credit
k Credit
c
Credit
leftovers <- Credit -> a -> ST s Credit
f Credit
creditsToSpend a
t
Credit -> ST s Credit
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Credit
c Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
- Credit
creditsToSpend Credit -> Credit -> Credit
forall a. Num a => a -> a -> a
+ Credit
leftovers)
expectCompletedChildren :: HasCallStack
=> PendingMerge s -> ST s (TreeMergeType, [Run])
expectCompletedChildren :: forall s.
HasCallStack =>
PendingMerge s -> ST s (TreeMergeType, [Buffer])
expectCompletedChildren (PendingMerge TreeMergeType
mt [PreExistingRun s]
prs [MergingTree s]
trees) = do
[Buffer]
rs1 <- (PreExistingRun s -> ST s Buffer)
-> [PreExistingRun s] -> ST s [Buffer]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse PreExistingRun s -> ST s Buffer
forall {s}. PreExistingRun s -> ST s Buffer
expectCompletedPreExistingRun [PreExistingRun s]
prs
[Buffer]
rs2 <- (MergingTree s -> ST s Buffer) -> [MergingTree s] -> ST s [Buffer]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse MergingTree s -> ST s Buffer
forall s. HasCallStack => MergingTree s -> ST s Buffer
expectCompletedMergingTree [MergingTree s]
trees
(TreeMergeType, [Buffer]) -> ST s (TreeMergeType, [Buffer])
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TreeMergeType
mt, [Buffer]
rs1 [Buffer] -> [Buffer] -> [Buffer]
forall a. [a] -> [a] -> [a]
++ [Buffer]
rs2)
where
expectCompletedPreExistingRun :: PreExistingRun s -> ST s Buffer
expectCompletedPreExistingRun = \case
PreExistingRun Buffer
r -> Buffer -> ST s Buffer
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Buffer
r
PreExistingMergingRun MergingRun LevelMergeType s
mr -> MergingRun LevelMergeType s -> ST s Buffer
forall t s. HasCallStack => MergingRun t s -> ST s Buffer
expectCompletedMergingRun MergingRun LevelMergeType s
mr
expectCompletedMergingTree :: HasCallStack => MergingTree s -> ST s Run
expectCompletedMergingTree :: forall s. HasCallStack => MergingTree s -> ST s Buffer
expectCompletedMergingTree = Invariant s Buffer -> ST s Buffer
forall s a. HasCallStack => Invariant s a -> ST s a
expectInvariant (Invariant s Buffer -> ST s Buffer)
-> (MergingTree s -> Invariant s Buffer)
-> MergingTree s
-> ST s Buffer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MergingTree s -> Invariant s Buffer
forall s. MergingTree s -> Invariant s Buffer
isCompletedMergingTree
data MTree r = MLeaf r
| MNode TreeMergeType [MTree r]
deriving stock (MTree r -> MTree r -> Bool
(MTree r -> MTree r -> Bool)
-> (MTree r -> MTree r -> Bool) -> Eq (MTree r)
forall r. Eq r => MTree r -> MTree r -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall r. Eq r => MTree r -> MTree r -> Bool
== :: MTree r -> MTree r -> Bool
$c/= :: forall r. Eq r => MTree r -> MTree r -> Bool
/= :: MTree r -> MTree r -> Bool
Eq, (forall m. Monoid m => MTree m -> m)
-> (forall m a. Monoid m => (a -> m) -> MTree a -> m)
-> (forall m a. Monoid m => (a -> m) -> MTree a -> m)
-> (forall a b. (a -> b -> b) -> b -> MTree a -> b)
-> (forall a b. (a -> b -> b) -> b -> MTree a -> b)
-> (forall b a. (b -> a -> b) -> b -> MTree a -> b)
-> (forall b a. (b -> a -> b) -> b -> MTree a -> b)
-> (forall a. (a -> a -> a) -> MTree a -> a)
-> (forall a. (a -> a -> a) -> MTree a -> a)
-> (forall a. MTree a -> [a])
-> (forall a. MTree a -> Bool)
-> (forall a. MTree a -> Credit)
-> (forall a. Eq a => a -> MTree a -> Bool)
-> (forall a. Ord a => MTree a -> a)
-> (forall a. Ord a => MTree a -> a)
-> (forall a. Num a => MTree a -> a)
-> (forall a. Num a => MTree a -> a)
-> Foldable MTree
forall a. Eq a => a -> MTree a -> Bool
forall a. Num a => MTree a -> a
forall a. Ord a => MTree a -> a
forall m. Monoid m => MTree m -> m
forall a. MTree a -> Bool
forall a. MTree a -> Credit
forall a. MTree a -> [a]
forall a. (a -> a -> a) -> MTree a -> a
forall m a. Monoid m => (a -> m) -> MTree a -> m
forall b a. (b -> a -> b) -> b -> MTree a -> b
forall a b. (a -> b -> b) -> b -> MTree a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Credit)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => MTree m -> m
fold :: forall m. Monoid m => MTree m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> MTree a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> MTree a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> MTree a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> MTree a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> MTree a -> b
foldr :: forall a b. (a -> b -> b) -> b -> MTree a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> MTree a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> MTree a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> MTree a -> b
foldl :: forall b a. (b -> a -> b) -> b -> MTree a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> MTree a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> MTree a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> MTree a -> a
foldr1 :: forall a. (a -> a -> a) -> MTree a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> MTree a -> a
foldl1 :: forall a. (a -> a -> a) -> MTree a -> a
$ctoList :: forall a. MTree a -> [a]
toList :: forall a. MTree a -> [a]
$cnull :: forall a. MTree a -> Bool
null :: forall a. MTree a -> Bool
$clength :: forall a. MTree a -> Credit
length :: forall a. MTree a -> Credit
$celem :: forall a. Eq a => a -> MTree a -> Bool
elem :: forall a. Eq a => a -> MTree a -> Bool
$cmaximum :: forall a. Ord a => MTree a -> a
maximum :: forall a. Ord a => MTree a -> a
$cminimum :: forall a. Ord a => MTree a -> a
minimum :: forall a. Ord a => MTree a -> a
$csum :: forall a. Num a => MTree a -> a
sum :: forall a. Num a => MTree a -> a
$cproduct :: forall a. Num a => MTree a -> a
product :: forall a. Num a => MTree a -> a
Foldable, (forall a b. (a -> b) -> MTree a -> MTree b)
-> (forall a b. a -> MTree b -> MTree a) -> Functor MTree
forall a b. a -> MTree b -> MTree a
forall a b. (a -> b) -> MTree a -> MTree b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> MTree a -> MTree b
fmap :: forall a b. (a -> b) -> MTree a -> MTree b
$c<$ :: forall a b. a -> MTree b -> MTree a
<$ :: forall a b. a -> MTree b -> MTree a
Functor, Credit -> MTree r -> ShowS
[MTree r] -> ShowS
MTree r -> String
(Credit -> MTree r -> ShowS)
-> (MTree r -> String) -> ([MTree r] -> ShowS) -> Show (MTree r)
forall r. Show r => Credit -> MTree r -> ShowS
forall r. Show r => [MTree r] -> ShowS
forall r. Show r => MTree r -> String
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall r. Show r => Credit -> MTree r -> ShowS
showsPrec :: Credit -> MTree r -> ShowS
$cshow :: forall r. Show r => MTree r -> String
show :: MTree r -> String
$cshowList :: forall r. Show r => [MTree r] -> ShowS
showList :: [MTree r] -> ShowS
Show)
allLevels :: LSM s -> ST s (Buffer, [[Run]], Maybe (MTree Run))
allLevels :: forall s. LSM s -> ST s (Buffer, [[Buffer]], Maybe (MTree Buffer))
allLevels (LSMHandle STRef s Credit
_ LSMConfig
_conf STRef s (LSMContent s)
lsmr) = do
LSMContent Buffer
wb Levels s
ls UnionLevel s
ul <- STRef s (LSMContent s) -> ST s (LSMContent s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (LSMContent s)
lsmr
[[Buffer]]
rs <- Levels s -> ST s [[Buffer]]
forall s. Levels s -> ST s [[Buffer]]
flattenLevels Levels s
ls
Maybe (MTree Buffer)
tree <- case UnionLevel s
ul of
UnionLevel s
NoUnion -> Maybe (MTree Buffer) -> ST s (Maybe (MTree Buffer))
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (MTree Buffer)
forall a. Maybe a
Nothing
Union MergingTree s
t STRef s Credit
_ -> MTree Buffer -> Maybe (MTree Buffer)
forall a. a -> Maybe a
Just (MTree Buffer -> Maybe (MTree Buffer))
-> ST s (MTree Buffer) -> ST s (Maybe (MTree Buffer))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MergingTree s -> ST s (MTree Buffer)
forall s. MergingTree s -> ST s (MTree Buffer)
flattenTree MergingTree s
t
(Buffer, [[Buffer]], Maybe (MTree Buffer))
-> ST s (Buffer, [[Buffer]], Maybe (MTree Buffer))
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Buffer
wb, [[Buffer]]
rs, Maybe (MTree Buffer)
tree)
flattenLevels :: Levels s -> ST s [[Run]]
flattenLevels :: forall s. Levels s -> ST s [[Buffer]]
flattenLevels = (Level s -> ST s [Buffer]) -> [Level s] -> ST s [[Buffer]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Level s -> ST s [Buffer]
forall s. Level s -> ST s [Buffer]
flattenLevel
flattenLevel :: Level s -> ST s [Run]
flattenLevel :: forall s. Level s -> ST s [Buffer]
flattenLevel (Level IncomingRun s
ir [Buffer]
rs) = ([Buffer] -> [Buffer] -> [Buffer]
forall a. [a] -> [a] -> [a]
++ [Buffer]
rs) ([Buffer] -> [Buffer]) -> ST s [Buffer] -> ST s [Buffer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IncomingRun s -> ST s [Buffer]
forall s. IncomingRun s -> ST s [Buffer]
flattenIncomingRun IncomingRun s
ir
flattenIncomingRun :: IncomingRun s -> ST s [Run]
flattenIncomingRun :: forall s. IncomingRun s -> ST s [Buffer]
flattenIncomingRun = \case
Single Buffer
r -> [Buffer] -> ST s [Buffer]
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Buffer
r]
Merging MergePolicy
_ NominalDebt
_ STRef s NominalCredit
_ MergingRun LevelMergeType s
mr -> MergingRun LevelMergeType s -> ST s [Buffer]
forall t s. MergingRun t s -> ST s [Buffer]
flattenMergingRun MergingRun LevelMergeType s
mr
flattenMergingRun :: MergingRun t s -> ST s [Run]
flattenMergingRun :: forall t s. MergingRun t s -> ST s [Buffer]
flattenMergingRun (MergingRun t
_ MergeDebt
_ STRef s MergingRunState
ref) = do
MergingRunState
mrs <- STRef s MergingRunState -> ST s MergingRunState
forall s a. STRef s a -> ST s a
readSTRef STRef s MergingRunState
ref
case MergingRunState
mrs of
CompletedMerge Buffer
r -> [Buffer] -> ST s [Buffer]
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Buffer
r]
OngoingMerge MergeCredit
_ [Buffer]
rs Buffer
_ -> [Buffer] -> ST s [Buffer]
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Buffer]
rs
flattenTree :: MergingTree s -> ST s (MTree Run)
flattenTree :: forall s. MergingTree s -> ST s (MTree Buffer)
flattenTree (MergingTree STRef s (MergingTreeState s)
ref) = do
MergingTreeState s
mts <- STRef s (MergingTreeState s) -> ST s (MergingTreeState s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (MergingTreeState s)
ref
case MergingTreeState s
mts of
CompletedTreeMerge Buffer
r ->
MTree Buffer -> ST s (MTree Buffer)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Buffer -> MTree Buffer
forall r. r -> MTree r
MLeaf Buffer
r)
OngoingTreeMerge (MergingRun TreeMergeType
mt MergeDebt
_ STRef s MergingRunState
mrs) ->
STRef s MergingRunState -> ST s MergingRunState
forall s a. STRef s a -> ST s a
readSTRef STRef s MergingRunState
mrs ST s MergingRunState
-> (MergingRunState -> ST s (MTree Buffer)) -> ST s (MTree Buffer)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
CompletedMerge Buffer
r -> MTree Buffer -> ST s (MTree Buffer)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Buffer -> MTree Buffer
forall r. r -> MTree r
MLeaf Buffer
r)
OngoingMerge MergeCredit
_ [Buffer]
rs Buffer
_ -> MTree Buffer -> ST s (MTree Buffer)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TreeMergeType -> [MTree Buffer] -> MTree Buffer
forall r. TreeMergeType -> [MTree r] -> MTree r
MNode TreeMergeType
mt (Buffer -> MTree Buffer
forall r. r -> MTree r
MLeaf (Buffer -> MTree Buffer) -> [Buffer] -> [MTree Buffer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Buffer]
rs))
PendingTreeMerge (PendingMerge TreeMergeType
mt [PreExistingRun s]
irs [MergingTree s]
trees) -> do
[MTree Buffer]
irs' <- (Buffer -> MTree Buffer) -> [Buffer] -> [MTree Buffer]
forall a b. (a -> b) -> [a] -> [b]
map Buffer -> MTree Buffer
forall r. r -> MTree r
MLeaf ([Buffer] -> [MTree Buffer])
-> ([[Buffer]] -> [Buffer]) -> [[Buffer]] -> [MTree Buffer]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Buffer]] -> [Buffer]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Buffer]] -> [MTree Buffer])
-> ST s [[Buffer]] -> ST s [MTree Buffer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (PreExistingRun s -> ST s [Buffer])
-> [PreExistingRun s] -> ST s [[Buffer]]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse PreExistingRun s -> ST s [Buffer]
forall s. PreExistingRun s -> ST s [Buffer]
flattenPreExistingRun [PreExistingRun s]
irs
[MTree Buffer]
trees' <- (MergingTree s -> ST s (MTree Buffer))
-> [MergingTree s] -> ST s [MTree Buffer]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse MergingTree s -> ST s (MTree Buffer)
forall s. MergingTree s -> ST s (MTree Buffer)
flattenTree [MergingTree s]
trees
MTree Buffer -> ST s (MTree Buffer)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TreeMergeType -> [MTree Buffer] -> MTree Buffer
forall r. TreeMergeType -> [MTree r] -> MTree r
MNode TreeMergeType
mt ([MTree Buffer]
irs' [MTree Buffer] -> [MTree Buffer] -> [MTree Buffer]
forall a. [a] -> [a] -> [a]
++ [MTree Buffer]
trees'))
flattenPreExistingRun :: PreExistingRun s -> ST s [Run]
flattenPreExistingRun :: forall s. PreExistingRun s -> ST s [Buffer]
flattenPreExistingRun = \case
PreExistingRun Buffer
r -> [Buffer] -> ST s [Buffer]
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Buffer
r]
PreExistingMergingRun MergingRun LevelMergeType s
mr -> MergingRun LevelMergeType s -> ST s [Buffer]
forall t s. MergingRun t s -> ST s [Buffer]
flattenMergingRun MergingRun LevelMergeType s
mr
logicalValue :: LSM s -> ST s (Map Key (Value, Maybe Blob))
logicalValue :: forall s. LSM s -> ST s (Map Key (Value, Maybe Blob))
logicalValue LSM s
lsm = do
(Buffer
wb, [[Buffer]]
levels, Maybe (MTree Buffer)
tree) <- LSM s -> ST s (Buffer, [[Buffer]], Maybe (MTree Buffer))
forall s. LSM s -> ST s (Buffer, [[Buffer]], Maybe (MTree Buffer))
allLevels LSM s
lsm
let r :: Buffer
r = TreeMergeType -> [Buffer] -> Buffer
forall t. IsMergeType t => t -> [Buffer] -> Buffer
mergek
TreeMergeType
MergeLevel
(Buffer
wb Buffer -> [Buffer] -> [Buffer]
forall a. a -> [a] -> [a]
: [[Buffer]] -> [Buffer]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Buffer]]
levels [Buffer] -> [Buffer] -> [Buffer]
forall a. [a] -> [a] -> [a]
++ Maybe Buffer -> [Buffer]
forall a. Maybe a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (MTree Buffer -> Buffer
mergeTree (MTree Buffer -> Buffer) -> Maybe (MTree Buffer) -> Maybe Buffer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (MTree Buffer)
tree))
Map Key (Value, Maybe Blob) -> ST s (Map Key (Value, Maybe Blob))
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Op -> Maybe (Value, Maybe Blob))
-> Buffer -> Map Key (Value, Maybe Blob)
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
Map.mapMaybe Op -> Maybe (Value, Maybe Blob)
forall {a} {b}. Update a b -> Maybe (a, Maybe b)
justInsert Buffer
r)
where
mergeTree :: MTree Run -> Run
mergeTree :: MTree Buffer -> Buffer
mergeTree (MLeaf Buffer
r) = Buffer
r
mergeTree (MNode TreeMergeType
mt [MTree Buffer]
ts) = TreeMergeType -> [Buffer] -> Buffer
forall t. IsMergeType t => t -> [Buffer] -> Buffer
mergek TreeMergeType
mt ((MTree Buffer -> Buffer) -> [MTree Buffer] -> [Buffer]
forall a b. (a -> b) -> [a] -> [b]
map MTree Buffer -> Buffer
mergeTree [MTree Buffer]
ts)
justInsert :: Update a b -> Maybe (a, Maybe b)
justInsert (Insert a
v Maybe b
b) = (a, Maybe b) -> Maybe (a, Maybe b)
forall a. a -> Maybe a
Just (a
v, Maybe b
b)
justInsert Update a b
Delete = Maybe (a, Maybe b)
forall a. Maybe a
Nothing
justInsert (Mupsert a
v) = (a, Maybe b) -> Maybe (a, Maybe b)
forall a. a -> Maybe a
Just (a
v, Maybe b
forall a. Maybe a
Nothing)
type Representation = (Run, [LevelRepresentation], Maybe (MTree Run))
type LevelRepresentation =
(Maybe (MergePolicy, NominalDebt, NominalCredit,
LevelMergeType, MergingRunState),
[Run])
dumpRepresentation :: LSM s -> ST s Representation
dumpRepresentation :: forall s. LSM s -> ST s Representation
dumpRepresentation (LSMHandle STRef s Credit
_ LSMConfig
_conf STRef s (LSMContent s)
lsmr) = do
LSMContent Buffer
wb Levels s
ls UnionLevel s
ul <- STRef s (LSMContent s) -> ST s (LSMContent s)
forall s a. STRef s a -> ST s a
readSTRef STRef s (LSMContent s)
lsmr
[LevelRepresentation]
levels <- (Level s -> ST s LevelRepresentation)
-> Levels s -> ST s [LevelRepresentation]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Level s -> ST s LevelRepresentation
forall s. Level s -> ST s LevelRepresentation
dumpLevel Levels s
ls
Maybe (MTree Buffer)
tree <- case UnionLevel s
ul of
UnionLevel s
NoUnion -> Maybe (MTree Buffer) -> ST s (Maybe (MTree Buffer))
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (MTree Buffer)
forall a. Maybe a
Nothing
Union MergingTree s
t STRef s Credit
_ -> MTree Buffer -> Maybe (MTree Buffer)
forall a. a -> Maybe a
Just (MTree Buffer -> Maybe (MTree Buffer))
-> ST s (MTree Buffer) -> ST s (Maybe (MTree Buffer))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MergingTree s -> ST s (MTree Buffer)
forall s. MergingTree s -> ST s (MTree Buffer)
flattenTree MergingTree s
t
Representation -> ST s Representation
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Buffer
wb, [LevelRepresentation]
levels, Maybe (MTree Buffer)
tree)
dumpLevel :: Level s -> ST s LevelRepresentation
dumpLevel :: forall s. Level s -> ST s LevelRepresentation
dumpLevel (Level (Single Buffer
r) [Buffer]
rs) =
LevelRepresentation -> ST s LevelRepresentation
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe
(MergePolicy, NominalDebt, NominalCredit, LevelMergeType,
MergingRunState)
forall a. Maybe a
Nothing, (Buffer
rBuffer -> [Buffer] -> [Buffer]
forall a. a -> [a] -> [a]
:[Buffer]
rs))
dumpLevel (Level (Merging MergePolicy
mp NominalDebt
nd STRef s NominalCredit
ncv (MergingRun LevelMergeType
mt MergeDebt
_ STRef s MergingRunState
ref)) [Buffer]
rs) = do
MergingRunState
mrs <- STRef s MergingRunState -> ST s MergingRunState
forall s a. STRef s a -> ST s a
readSTRef STRef s MergingRunState
ref
NominalCredit
nc <- STRef s NominalCredit -> ST s NominalCredit
forall s a. STRef s a -> ST s a
readSTRef STRef s NominalCredit
ncv
LevelRepresentation -> ST s LevelRepresentation
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((MergePolicy, NominalDebt, NominalCredit, LevelMergeType,
MergingRunState)
-> Maybe
(MergePolicy, NominalDebt, NominalCredit, LevelMergeType,
MergingRunState)
forall a. a -> Maybe a
Just (MergePolicy
mp, NominalDebt
nd, NominalCredit
nc, LevelMergeType
mt, MergingRunState
mrs), [Buffer]
rs)
representationShape :: Representation
-> (Int, [([Int], [Int])], Maybe (MTree Int))
representationShape :: Representation
-> (Credit, [([Credit], [Credit])], Maybe (MTree Credit))
representationShape (Buffer
wb, [LevelRepresentation]
levels, Maybe (MTree Buffer)
tree) =
(Buffer -> Credit
summaryRun Buffer
wb, (LevelRepresentation -> ([Credit], [Credit]))
-> [LevelRepresentation] -> [([Credit], [Credit])]
forall a b. (a -> b) -> [a] -> [b]
map LevelRepresentation -> ([Credit], [Credit])
forall {a} {b} {c} {d}.
(Maybe (a, b, c, d, MergingRunState), [Buffer])
-> ([Credit], [Credit])
summaryLevel [LevelRepresentation]
levels, (MTree Buffer -> MTree Credit)
-> Maybe (MTree Buffer) -> Maybe (MTree Credit)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Buffer -> Credit) -> MTree Buffer -> MTree Credit
forall a b. (a -> b) -> MTree a -> MTree b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Buffer -> Credit
summaryRun) Maybe (MTree Buffer)
tree)
where
summaryLevel :: (Maybe (a, b, c, d, MergingRunState), [Buffer])
-> ([Credit], [Credit])
summaryLevel (Maybe (a, b, c, d, MergingRunState)
mmr, [Buffer]
rs) =
let ([Credit]
ongoing, [Credit]
complete) = Maybe (a, b, c, d, MergingRunState) -> ([Credit], [Credit])
forall {a} {b} {c} {d}.
Maybe (a, b, c, d, MergingRunState) -> ([Credit], [Credit])
summaryMR Maybe (a, b, c, d, MergingRunState)
mmr
in ([Credit]
ongoing, [Credit]
complete [Credit] -> [Credit] -> [Credit]
forall a. Semigroup a => a -> a -> a
<> (Buffer -> Credit) -> [Buffer] -> [Credit]
forall a b. (a -> b) -> [a] -> [b]
map Buffer -> Credit
summaryRun [Buffer]
rs)
summaryRun :: Buffer -> Credit
summaryRun = Buffer -> Credit
runSize
summaryMR :: Maybe (a, b, c, d, MergingRunState) -> ([Credit], [Credit])
summaryMR = \case
Maybe (a, b, c, d, MergingRunState)
Nothing -> ([], [])
Just (a
_, b
_, c
_, d
_, CompletedMerge Buffer
r) -> ([], [Buffer -> Credit
summaryRun Buffer
r])
Just (a
_, b
_, c
_, d
_, OngoingMerge MergeCredit
_ [Buffer]
rs Buffer
_) -> ((Buffer -> Credit) -> [Buffer] -> [Credit]
forall a b. (a -> b) -> [a] -> [b]
map Buffer -> Credit
summaryRun [Buffer]
rs, [])
type Event = EventAt EventDetail
data EventAt e = EventAt {
forall e. EventAt e -> Credit
eventAtStep :: Counter,
forall e. EventAt e -> Credit
eventAtLevel :: Int,
forall e. EventAt e -> e
eventDetail :: e
}
deriving stock Credit -> EventAt e -> ShowS
[EventAt e] -> ShowS
EventAt e -> String
(Credit -> EventAt e -> ShowS)
-> (EventAt e -> String)
-> ([EventAt e] -> ShowS)
-> Show (EventAt e)
forall e. Show e => Credit -> EventAt e -> ShowS
forall e. Show e => [EventAt e] -> ShowS
forall e. Show e => EventAt e -> String
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall e. Show e => Credit -> EventAt e -> ShowS
showsPrec :: Credit -> EventAt e -> ShowS
$cshow :: forall e. Show e => EventAt e -> String
show :: EventAt e -> String
$cshowList :: forall e. Show e => [EventAt e] -> ShowS
showList :: [EventAt e] -> ShowS
Show
data EventDetail =
AddLevelEvent
| AddRunEvent {
EventDetail -> Credit
runsAtLevel :: Int
}
| MergeStartedEvent {
EventDetail -> MergePolicy
mergePolicy :: MergePolicy,
EventDetail -> LevelMergeType
mergeType :: LevelMergeType,
EventDetail -> Credit
mergeDebt :: Debt,
EventDetail -> [Credit]
mergeRunsSize :: [Int]
}
| MergeCompletedEvent {
mergePolicy :: MergePolicy,
mergeType :: LevelMergeType,
EventDetail -> Credit
mergeSize :: Int
}
deriving stock Credit -> EventDetail -> ShowS
[EventDetail] -> ShowS
EventDetail -> String
(Credit -> EventDetail -> ShowS)
-> (EventDetail -> String)
-> ([EventDetail] -> ShowS)
-> Show EventDetail
forall a.
(Credit -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Credit -> EventDetail -> ShowS
showsPrec :: Credit -> EventDetail -> ShowS
$cshow :: EventDetail -> String
show :: EventDetail -> String
$cshowList :: [EventDetail] -> ShowS
showList :: [EventDetail] -> ShowS
Show
instance QC.Arbitrary Key where
arbitrary :: Gen Key
arbitrary = Credit -> Key
K (Credit -> Key) -> Gen Credit -> Gen Key
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Credit
forall a. Integral a => Gen a
QC.arbitrarySizedNatural
shrink :: Key -> [Key]
shrink (K Credit
v) = Credit -> Key
K (Credit -> Key) -> [Credit] -> [Key]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Credit -> [Credit]
forall a. Arbitrary a => a -> [a]
QC.shrink Credit
v
instance QC.Arbitrary Value where
arbitrary :: Gen Value
arbitrary = Credit -> Value
V (Credit -> Value) -> Gen Credit -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Credit
forall a. Integral a => Gen a
QC.arbitrarySizedNatural
shrink :: Value -> [Value]
shrink (V Credit
v) = Credit -> Value
V (Credit -> Value) -> [Credit] -> [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Credit -> [Credit]
forall a. Arbitrary a => a -> [a]
QC.shrink Credit
v
instance QC.Arbitrary Blob where
arbitrary :: Gen Blob
arbitrary = Credit -> Blob
B (Credit -> Blob) -> Gen Credit -> Gen Blob
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Credit
forall a. Integral a => Gen a
QC.arbitrarySizedNatural
shrink :: Blob -> [Blob]
shrink (B Credit
v) = Credit -> Blob
B (Credit -> Blob) -> [Credit] -> [Blob]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Credit -> [Credit]
forall a. Arbitrary a => a -> [a]
QC.shrink Credit
v
instance (QC.Arbitrary v, QC.Arbitrary b) => QC.Arbitrary (Update v b) where
arbitrary :: Gen (Update v b)
arbitrary = [(Credit, Gen (Update v b))] -> Gen (Update v b)
forall a. HasCallStack => [(Credit, Gen a)] -> Gen a
QC.frequency
[ (Credit
3, v -> Maybe b -> Update v b
forall v b. v -> Maybe b -> Update v b
Insert (v -> Maybe b -> Update v b)
-> Gen v -> Gen (Maybe b -> Update v b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen v
forall a. Arbitrary a => Gen a
QC.arbitrary Gen (Maybe b -> Update v b) -> Gen (Maybe b) -> Gen (Update v b)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (Maybe b)
forall a. Arbitrary a => Gen a
QC.arbitrary)
, (Credit
1, v -> Update v b
forall v b. v -> Update v b
Mupsert (v -> Update v b) -> Gen v -> Gen (Update v b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen v
forall a. Arbitrary a => Gen a
QC.arbitrary)
, (Credit
1, Update v b -> Gen (Update v b)
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Update v b
forall v b. Update v b
Delete)
]
instance QC.Arbitrary LevelMergeType where
arbitrary :: Gen LevelMergeType
arbitrary = [LevelMergeType] -> Gen LevelMergeType
forall a. HasCallStack => [a] -> Gen a
QC.elements [LevelMergeType
MergeMidLevel, LevelMergeType
MergeLastLevel]
instance QC.Arbitrary TreeMergeType where
arbitrary :: Gen TreeMergeType
arbitrary = [TreeMergeType] -> Gen TreeMergeType
forall a. HasCallStack => [a] -> Gen a
QC.elements [TreeMergeType
MergeLevel, TreeMergeType
MergeUnion]