module Database.Haskey.Alloc.Concurrent.FreePages.Tree where
import Control.Monad ((>=>))
import Data.Foldable (traverse_)
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NE
import Data.BTree.Alloc.Class
import Data.BTree.Impure
import Data.BTree.Impure.NonEmpty
import Data.BTree.Primitives
type FreeTree = Tree TxId FreeSubtree
type FreeSubtree = NonEmptyTree PageId ()
replaceSubtree :: AllocM m
=> TxId
-> NonEmpty PageId
-> FreeTree
-> m FreeTree
replaceSubtree tx pids = deleteSubtree tx >=> insertSubtree tx pids
deleteSubtree :: AllocM m
=> TxId
-> FreeTree
-> m FreeTree
deleteSubtree tx tree = lookupTree tx tree >>= \case
Nothing -> return tree
Just (NonEmptyTree h nid) -> do
freeAllNodes h nid
deleteTree tx tree
where
freeAllNodes :: (AllocM m, Key key, Value val)
=> Height h
-> NodeId h key val
-> m ()
freeAllNodes h nid = readNode h nid >>= \case
Leaf _ -> freeNode h nid
Idx idx -> do
let subHgt = decrHeight h
traverse_ (freeAllNodes subHgt) idx
freeNode h nid
insertSubtree :: AllocM m
=> TxId
-> NonEmpty PageId
-> FreeTree
-> m FreeTree
insertSubtree tx pids tree = do
subtree <- fromNonEmptyList (NE.zip pids (NE.repeat ()))
insertTree tx subtree tree