module Database.Perdure.SpaceTree(
SpaceTree
) where
import Prelude()
import Cgm.Prelude
import Data.Word
import Cgm.Data.Maybe
import Cgm.Control.Monad.State
import Database.Perdure.Space
import Database.Perdure.Data.Map
import Database.Perdure.Persistent
import Data.Typeable
newtype SpaceTree = SpaceTree (Map Word64 Bool) deriving Typeable
instance Space SpaceTree where
emptySpace = SpaceTree Database.Perdure.Data.Map.empty
removeSpan = onSortedPair (\b e -> spaceTreeIncr e . spaceTreeDecr b)
addSpan = onSortedPair (\b e -> spaceTreeIncr b . spaceTreeDecr e)
findSpan sz (SpaceTree m) = filter (onSortedPair $ \start end -> end start > sz) $
let
start = 0
mkSpans [] = []
mkSpans (_ : []) = error "bad SpaceTree"
mkSpans (k0 : k1 : ks) = unsafeSortedPair k0 k1 : mkSpans ks
in mkSpans $
(\(b, ks) -> bool (start : ks) ks b) $
($ (True, [])) $
fromMaybe (const (True, [])) $
scan (\k -> bool (\_ -> id) (\b (_, ks) -> (b, k : ks)) $ k > start)
(\k l r -> bool (l . r) r $ k <= start) m
isFreeSpace a (SpaceTree m) = fromMaybe False $ fromMaybe Nothing $
scan (\k -> bool (const Nothing) Just $ k <= a) (\k -> bool (\l r -> maybe l Just r) const $ k >= a) m
spaceTreeIncr :: Word64 -> SpaceTree -> SpaceTree
spaceTreeIncr a (SpaceTree m) =
SpaceTree $ fromMaybe m $ snd $ runState (updateM a $ get >>= maybe (put (Just True)) (bool (put Nothing) (error $ "spaceTreeIncr " ++ show a))) m
spaceTreeDecr :: Word64 -> SpaceTree -> SpaceTree
spaceTreeDecr a (SpaceTree m) =
SpaceTree $ fromMaybe m $ snd $ runState (updateM a $ get >>= maybe (put (Just False)) (bool (error $ "spaceTreeDecr " ++ show a) (put Nothing))) m
instance Persistent SpaceTree where persister = structureMap persister
deriveStructured ''SpaceTree