module Database.Perdure(
module Database.Perdure.Persistent,
module Database.Perdure.Ref,
module Database.Perdure.Deref,
module Database.Perdure.Rev,
module Database.Perdure.SizeRef,
LocalStoreFile,
withRawDeviceStoreFiles,
withRawDeviceStoreFile,
withFileStoreFile,
ReplicatedFile(..),
newCachedFile,
RootLocation,
defaultRootLocation,
PVar,
openPVar,
createPVar,
updatePVar,
updateInspectPVar
) where
import Prelude()
import Cgm.Prelude
import Database.Perdure.State
import Database.Perdure.Persistent
import Database.Perdure.Ref
import Database.Perdure.Deref
import Database.Perdure.Rev
import Database.Perdure.SizeRef
import qualified Database.Perdure.Cache as Cache
import Cgm.Control.Monad.State as M
import Cgm.Data.Typeable
import Control.Monad.Reader hiding (sequence)
import Cgm.Control.Concurrent.MVar
import Cgm.Data.Super
import Cgm.Data.Len
import Data.Word
import Database.Perdure.ReplicatedFile(ReplicatedFile(..))
import Database.Perdure.LocalStoreFile(withFileStoreFile, withRawDeviceStoreFile, withRawDeviceStoreFiles, LocalStoreFile)
newCachedFile :: Integer -> ReplicatedFile -> IO CachedFile
newCachedFile sz f = CachedFile f <$> newMVar (Cache.empty sz)
defaultRootLocation :: CachedFile -> RootLocation
defaultRootLocation f = RootLocation f [RootAddress 0, RootAddress $ apply super rootAllocSize]
newtype PVar s = PVar (MVar (PState s))
createPVar :: (Typeable s, Persistent s) => s -> Word64 -> RootLocation -> IO (PVar s)
createPVar s sz l = initState l (addSpan (sortedPair roots sz') emptySpace) s >>= fmap PVar . newMVar where
roots = 2 * apply super (getLen rootAllocSize)
sz' =
if sz <= roots
then error $ "createPVar needs a max size of at least " ++ show roots ++ " bytes"
else getLen (coarsenLen (unsafeLen (sz roots) :: Len Word8 Word64) :: Len Word64 Word64)
openPVar :: (Typeable s, Persistent s) => RootLocation -> IO (Maybe (PVar s))
openPVar l = readState l >>= sequence . fmap (fmap PVar . newMVar)
updatePVar :: (Typeable s, Persistent s) => PVar s -> M.StateT s IO a -> IO a
updatePVar (PVar v) t = stateTModifyMVar v $ toStandardState $ updateState t
updateInspectPVar :: (Typeable s, Persistent s) => PVar s -> M.StateT s (ReaderT (PState s) IO) a -> IO a
updateInspectPVar (PVar v) t = stateTModifyMVar v $ toStandardState $ updateStateRead t