-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A transactional, ACID compliant, embeddable key-value store. -- -- Haskey is a transactional, ACID compliant, embeddable, scalable -- key-value store written entirely in Haskell. -- -- For more information on how to use this package, visit -- https://github.com/haskell-haskey/haskey @package haskey @version 0.2.0.1 -- | Module describing the tree structure of the free page database. module Database.Haskey.Alloc.Concurrent.FreePages.Tree -- | The main tree structure of the free page database. -- -- The main free page database tree maps a TxId to a -- FreeSubtree. type FreeTree = Tree TxId FreeSubtree -- | the subtree structure of the free page database. -- -- Just a collection of free PageIds. type FreeSubtree = NonEmptyTree PageId () -- | Replace the subtree of a certain TxId. replaceSubtree :: AllocM m => TxId -> NonEmpty PageId -> FreeTree -> m FreeTree -- | Delete the subtree of a certain TxId. -- -- The TxId will not be present anymore in the free tree after -- this call. deleteSubtree :: AllocM m => TxId -> FreeTree -> m FreeTree -- | Insert a subtree for a certain TxId. insertSubtree :: AllocM m => TxId -> NonEmpty PageId -> FreeTree -> m FreeTree -- | Environments of a read or write transaction. module Database.Haskey.Alloc.Concurrent.Environment data StateType TypeData :: StateType TypeIndex :: StateType -- | Wrapper around a type to indicate it belongs to a file with either -- data/leaf nodes or index nodes. data S (t :: StateType) a [DataState] :: a -> S 'TypeData a [IndexState] :: a -> S 'TypeIndex a getSValue :: S t a -> a newtype ReaderEnv hnds ReaderEnv :: hnds -> ReaderEnv hnds [readerHnds] :: ReaderEnv hnds -> hnds data FileState stateType FileState :: ![NewlyFreed] -> !(S stateType PageId) -> !(S stateType PageId) -> !(Set PageId) -> !(S stateType FreeTree) -> !(S stateType [FreePage]) -> FileState stateType -- | Pages free'd in this transaction, not ready for reuse until the -- transaction is commited. [fileStateNewlyFreedPages] :: FileState stateType -> ![NewlyFreed] -- | The original number of pages in the file, before the transaction -- started. [fileStateOriginalNumPages] :: FileState stateType -> !(S stateType PageId) -- | The new uncommited number of pages in the file. -- -- All pages in the range fileStateOriginalNumPages to -- fileStateNewNumPages (excluding) are freshly allocated in the -- ongoing transaction. [fileStateNewNumPages] :: FileState stateType -> !(S stateType PageId) -- | Pages written to in this transaction. [fileStateDirtyPages] :: FileState stateType -> !(Set PageId) -- | The root of the free tree, might change during a transaction. [fileStateFreeTree] :: FileState stateType -> !(S stateType FreeTree) -- | All pages that are immediately ready for reuse in this and any -- subsequent transactions. [fileStateCachedFreePages] :: FileState stateType -> !(S stateType [FreePage]) data WriterEnv hnds WriterEnv :: !hnds -> !TxId -> Map TxId Integer -> FileState 'TypeIndex -> FileState 'TypeData -> !Bool -> !(Set DirtyOverflow) -> !Word32 -> ![OldOverflow] -> WriterEnv hnds [writerHnds] :: WriterEnv hnds -> !hnds [writerTxId] :: WriterEnv hnds -> !TxId [writerReaders] :: WriterEnv hnds -> Map TxId Integer -- | State of the file with index nodes. [writerIndexFileState] :: WriterEnv hnds -> FileState 'TypeIndex -- | State of the file with data/leaf nodes. [writerDataFileState] :: WriterEnv hnds -> FileState 'TypeData -- | Whether or not querying free pages from the free is enabled. [writerQueryFreeTreeOn] :: WriterEnv hnds -> !Bool -- | Newly allocated overflow pages in this transaction. [writerDirtyOverflows] :: WriterEnv hnds -> !(Set DirtyOverflow) -- | Counts how many overflow pages were already allocated in this -- transaction. [writerOverflowCounter] :: WriterEnv hnds -> !Word32 -- | Old overflow pages that were removed in this transaction and should be -- deleted when no longer in use. [writerRemovedOverflows] :: WriterEnv hnds -> ![OldOverflow] -- | Create a new writer. newWriter :: hnd -> TxId -> Map TxId Integer -> S 'TypeData PageId -> S 'TypeIndex PageId -> S 'TypeData [FreePage] -> S 'TypeIndex [FreePage] -> S 'TypeData FreeTree -> S 'TypeIndex FreeTree -> WriterEnv hnd -- | Wrapper around PageId indicating it is newly free'd and cannot -- be reused in the same transaction. newtype NewlyFreed NewlyFreed :: PageId -> NewlyFreed -- | Wrapper around PageId indicating it is free and can be reused -- in any transaction. newtype FreePage FreePage :: PageId -> FreePage -- | Wrapper around PageId indicating that it is dirty, i.e. written -- to in this transaction. newtype Dirty Dirty :: PageId -> Dirty -- | Try to free a page, given a set of dirty pages. -- -- If the page was dirty, a FreePage page is added to the -- environment, if not a NewlyFreed page is added to the -- environment. -- -- Btw, give me lenses... freePage :: (Functor m, MonadState (WriterEnv hnd) m) => S stateType PageId -> m () updateFileState :: FileState t -> (forall a. a -> S t a) -> Maybe Dirty -> PageId -> FileState t -- | Get a Dirty page, by first proving it is in fact dirty. dirty :: (Functor m, MonadState (WriterEnv hnd) m) => S stateType PageId -> m (Maybe Dirty) -- | Touch a fresh page, make it dirty. -- -- We really need lenses... touchPage :: MonadState (WriterEnv hnd) m => S stateType PageId -> m () -- | Wrapper around OverflowId indicating that it is dirty. newtype DirtyOverflow DirtyOverflow :: OverflowId -> DirtyOverflow -- | Wrapper around OverflowId indicating that it is an overflow -- page from a previous transaction. newtype OldOverflow OldOverflow :: OverflowId -> OldOverflow -- | Touch a fresh overflow page, making it dirty. touchOverflow :: MonadState (WriterEnv hnd) m => OverflowId -> m () -- | Get the type of the overflow page. overflowType :: MonadState (WriterEnv hnd) m => OverflowId -> m (Either DirtyOverflow OldOverflow) -- | Free an old overflow page. removeOldOverflow :: MonadState (WriterEnv hdn) m => OldOverflow -> m () instance GHC.Show.Show Database.Haskey.Alloc.Concurrent.Environment.OldOverflow instance GHC.Classes.Ord Database.Haskey.Alloc.Concurrent.Environment.OldOverflow instance GHC.Classes.Eq Database.Haskey.Alloc.Concurrent.Environment.OldOverflow instance GHC.Show.Show Database.Haskey.Alloc.Concurrent.Environment.DirtyOverflow instance GHC.Classes.Ord Database.Haskey.Alloc.Concurrent.Environment.DirtyOverflow instance GHC.Classes.Eq Database.Haskey.Alloc.Concurrent.Environment.DirtyOverflow instance GHC.Show.Show Database.Haskey.Alloc.Concurrent.Environment.Dirty instance GHC.Classes.Ord Database.Haskey.Alloc.Concurrent.Environment.Dirty instance GHC.Classes.Eq Database.Haskey.Alloc.Concurrent.Environment.Dirty instance GHC.Show.Show Database.Haskey.Alloc.Concurrent.Environment.FreePage instance GHC.Classes.Ord Database.Haskey.Alloc.Concurrent.Environment.FreePage instance GHC.Classes.Eq Database.Haskey.Alloc.Concurrent.Environment.FreePage instance Data.Binary.Class.Binary Database.Haskey.Alloc.Concurrent.Environment.FreePage instance GHC.Show.Show Database.Haskey.Alloc.Concurrent.Environment.NewlyFreed instance GHC.Classes.Ord Database.Haskey.Alloc.Concurrent.Environment.NewlyFreed instance GHC.Classes.Eq Database.Haskey.Alloc.Concurrent.Environment.NewlyFreed instance GHC.Show.Show a => GHC.Show.Show (Database.Haskey.Alloc.Concurrent.Environment.S t a) instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Database.Haskey.Alloc.Concurrent.Environment.S 'Database.Haskey.Alloc.Concurrent.Environment.TypeData a) instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Database.Haskey.Alloc.Concurrent.Environment.S 'Database.Haskey.Alloc.Concurrent.Environment.TypeIndex a) instance GHC.Base.Functor (Database.Haskey.Alloc.Concurrent.Environment.S t) module Database.Haskey.Alloc.Concurrent.FreePages.Save -- | Save the free pages from the dirty page list and the free page cache. saveFreePages :: AllocM m => TxId -> FileState t -> m FreeTree -- | Save the newly free pages of the current transaction, as stored by -- fileStateNewlyFreedPages. saveNewlyFreedPages :: AllocM m => TxId -> FileState t -> FreeTree -> m FreeTree -- | This module implements mechanisms to work with transactions. module Database.Haskey.Alloc.Transaction -- | A committed or aborted transaction, with a return value of type -- a. data Transaction r a Commit :: r -> a -> Transaction r a Abort :: a -> Transaction r a -- | Commit the new tree and return a computed value. commit :: AllocM n => a -> r -> n (Transaction r a) -- | Commit the new tree, without return a computed value. commit_ :: AllocM n => r -> n (Transaction r ()) -- | Abort the transaction and return a computed value. abort :: AllocM n => a -> n (Transaction r a) -- | Abort the transaction, without returning a computed value. abort_ :: AllocM n => n (Transaction r ()) -- | A storage back-end manages physical storage of pages. module Database.Haskey.Store.Class -- | A storage back-end that can store and fetch physical pages. class (Applicative m, Monad m) => StoreM hnd m | m -> hnd -- | Open a database handle for reading and writing. openHandle :: StoreM hnd m => hnd -> m () -- | Obtain a lock on the given handle, so no other process can access it. lockHandle :: StoreM hnd m => hnd -> m () -- | Release the lock on the given handle, so other processes can access -- it. releaseHandle :: StoreM hnd m => hnd -> m () -- | Flush the contents of a handle to disk (or other storage). flushHandle :: StoreM hnd m => hnd -> m () -- | Close a database handle. closeHandle :: StoreM hnd m => hnd -> m () -- | Remove a handle from the storage back-end. removeHandle :: StoreM hnd m => hnd -> m () -- | A function that calculates the hypothetical size of a node, if it were -- to be written to a page (regardless of the maximum page size). nodePageSize :: (StoreM hnd m, Key key, Value val) => m (Height height -> Node height key val -> PageSize) -- | The maximum page size the allocator can handle. maxPageSize :: StoreM hnd m => m PageSize -- | Get the maximum key size -- -- The default implementation will repeatedly call -- calculateMaxKeySize. You might want to cache this value in your -- own implementation. maxKeySize :: StoreM hnd m => m Word64 -- | Get the maximum value size -- -- The default implementation will repeatedly call -- calculateMaxValueSize. You might want to cache this value in -- your own implementation. maxValueSize :: StoreM hnd m => m Word64 -- | Read a page and return the actual node and the transaction id when the -- node was written. getNodePage :: (StoreM hnd m, Key key, Value val) => hnd -> Height height -> Proxy key -> Proxy val -> NodeId height key val -> m (Node height key val) -- | Write a node to a physical page. putNodePage :: (StoreM hnd m, Key key, Value val) => hnd -> Height height -> NodeId height key val -> Node height key val -> m () -- | Read a value from an overflow page getOverflow :: (StoreM hnd m, (Value val)) => hnd -> Proxy val -> m val -- | Write a value to an overflow page putOverflow :: (StoreM hnd m, (Value val)) => hnd -> val -> m () -- | List overflow pages in the specific overflow directory. -- -- The result should include **AT LEAST** the handles in the specified -- directory, but it may contain more handles, even handles that do not -- belong to an overflow page. listOverflows :: StoreM hnd m => hnd -> m [hnd] -- | Search an arbitrary number, less than a limit, greater than a starting -- value. arbitrarySearch :: (Ord v, Integral n) => n -> (n -> v) -> v -> n -- | Calculate the maximum key size. -- -- Return the size for which at least 4 key-value pairs with keys and -- values of that size can fit in a leaf node. calculateMaxKeySize :: PageSize -> (Node 'Z ZeroEncoded ZeroEncoded -> PageSize) -> Word64 -- | Calculate the maximum value size. -- -- Return the size for which at least 4 key-value pairs of the specified -- maximum key size and values of the returned size can fit in a leaf -- node. that size can fit in a leaf node. calculateMaxValueSize :: PageSize -> Word64 -> (Node 'Z ZeroEncoded ZeroEncoded -> PageSize) -> Word64 -- | Data type which encodes the integer using a variable amount of NULL or -- ONE bytes. data ZeroEncoded ZeroEncoded :: Word64 -> Word64 -> ZeroEncoded [getZeroEncoded] :: ZeroEncoded -> Word64 [getZeroEncodedValue] :: ZeroEncoded -> Word64 instance GHC.Show.Show Database.Haskey.Store.Class.ZeroEncoded instance GHC.Classes.Ord Database.Haskey.Store.Class.ZeroEncoded instance GHC.Classes.Eq Database.Haskey.Store.Class.ZeroEncoded instance Data.Binary.Class.Binary Database.Haskey.Store.Class.ZeroEncoded instance Data.BTree.Primitives.Key.Key Database.Haskey.Store.Class.ZeroEncoded instance Data.BTree.Primitives.Value.Value Database.Haskey.Store.Class.ZeroEncoded instance Database.Haskey.Store.Class.StoreM hnd m => Database.Haskey.Store.Class.StoreM hnd (Control.Monad.Trans.State.Lazy.StateT s m) instance Database.Haskey.Store.Class.StoreM hnd m => Database.Haskey.Store.Class.StoreM hnd (Control.Monad.Trans.Reader.ReaderT s m) -- | Storage back-ends that manage physical storage of pages. module Database.Haskey.Store -- | Data structures and functions related to handling overflow pages. module Database.Haskey.Alloc.Concurrent.Overflow getNewOverflowId :: (Functor m, MonadState (WriterEnv hnd) m) => m OverflowId getOverflowHandle :: FilePath -> OverflowId -> FilePath getOverflowDir :: FilePath -> TxId -> FilePath readOverflowId :: FilePath -> Maybe OverflowId showHex' :: (Integral a, Show a) => a -> String readHex' :: (Eq a, Num a) => String -> Maybe (a, String) -- | The main tree structure of the freed overflow page tree type OverflowTree = Tree TxId OverflowSubtree -- | The subtree structure of the freed overflow page tree type OverflowSubtree = NonEmptyTree OverflowId () -- | Save a set of overflow ids that were free'd in the transaction. insertOverflowIds :: AllocM m => TxId -> NonEmpty OverflowId -> OverflowTree -> m OverflowTree -- | Delete the set of overflow ids that were free'd in the transaction. deleteOverflowIds :: AllocM m => TxId -> OverflowTree -> m OverflowTree deleteOutdatedOverflowIds :: (Functor m, AllocM m, MonadIO m, MonadState (WriterEnv hnd) m) => OverflowTree -> m (Maybe OverflowTree) -- | This module implements data structures and function related to the -- metadata of the concurrent page allocator. module Database.Haskey.Alloc.Concurrent.Meta -- | User-defined data root stored inside ConcurrentMeta. -- -- This can be a user-defined collection of Tree roots. class Value root => Root root -- | Data type used to point to the most recent version of the meta data. data CurrentMetaPage Meta1 :: CurrentMetaPage Meta2 :: CurrentMetaPage -- | Meta data of the page allocator. -- -- The root type parameter should be a user-defined collection -- of Tree roots, instantiating the Root type class. -- -- To store store a single tree, use ConcurrentMeta (Tree k v). data ConcurrentMeta root ConcurrentMeta :: TxId -> S 'TypeData PageId -> S 'TypeIndex PageId -> root -> S 'TypeData FreeTree -> S 'TypeIndex FreeTree -> OverflowTree -> S 'TypeData [FreePage] -> S 'TypeIndex [FreePage] -> ConcurrentMeta root [concurrentMetaRevision] :: ConcurrentMeta root -> TxId [concurrentMetaDataNumPages] :: ConcurrentMeta root -> S 'TypeData PageId [concurrentMetaIndexNumPages] :: ConcurrentMeta root -> S 'TypeIndex PageId [concurrentMetaRoot] :: ConcurrentMeta root -> root [concurrentMetaDataFreeTree] :: ConcurrentMeta root -> S 'TypeData FreeTree [concurrentMetaIndexFreeTree] :: ConcurrentMeta root -> S 'TypeIndex FreeTree [concurrentMetaOverflowTree] :: ConcurrentMeta root -> OverflowTree [concurrentMetaDataCachedFreePages] :: ConcurrentMeta root -> S 'TypeData [FreePage] [concurrentMetaIndexCachedFreePages] :: ConcurrentMeta root -> S 'TypeIndex [FreePage] -- | A class representing the storage requirements of the page allocator. -- -- A store supporting the page allocator should be an instance of this -- class. class StoreM FilePath m => ConcurrentMetaStoreM m -- | Write the meta-data structure to a certain page. putConcurrentMeta :: (ConcurrentMetaStoreM m, Root root) => FilePath -> ConcurrentMeta root -> m () -- | Try to read the meta-data structure from a handle, or return -- Nothing if the handle doesn't contain a meta page. readConcurrentMeta :: (ConcurrentMetaStoreM m, Root root) => FilePath -> Proxy root -> m (Maybe (ConcurrentMeta root)) instance GHC.Generics.Generic (Database.Haskey.Alloc.Concurrent.Meta.ConcurrentMeta root) instance GHC.Show.Show root => GHC.Show.Show (Database.Haskey.Alloc.Concurrent.Meta.ConcurrentMeta root) instance Data.Binary.Class.Binary root => Data.Binary.Class.Binary (Database.Haskey.Alloc.Concurrent.Meta.ConcurrentMeta root) instance (Data.BTree.Primitives.Key.Key k, Data.BTree.Primitives.Value.Value v) => Database.Haskey.Alloc.Concurrent.Meta.Root (Data.BTree.Impure.Structures.Tree k v) module Database.Haskey.Alloc.Concurrent.FreePages.Query -- | Get a free page. -- -- First try to get one from the in-memory dirty pages. Then try to get -- one from the in-memory free page cache stored in -- fileStateCachedFreePages. If that one is empty, actually query -- one from the free database. getFreePageId :: (Functor m, AllocM m, MonadIO m, MonadState (WriterEnv hnd) m) => S stateType () -> m (Maybe PageId) -- | Get a cached free page. -- -- Get a free page from the free database cache stored in -- fileStateCachedFreePages. getCachedFreePageId :: (Functor m, MonadState (WriterEnv hnd) m) => S stateType () -> m (Maybe PageId) -- | Try to get a list of free pages from the free page database, return -- the first free one for immediate use, and store the rest in the -- environment. -- -- Immediately remove the queried free pages from the free tree. queryNewFreePageIds :: (AllocM m, MonadIO m, MonadState (WriterEnv hnd) m) => S stateType () -> m (Maybe PageId) -- | Lookup a list of free pages from the free page database, guaranteed to -- be old enough. lookupValidFreePageIds :: (MonadIO m, AllocReaderM m, MonadState (WriterEnv hnd) m) => FreeTree -> m (Maybe (TxId, NonEmpty PageId)) -- | Lookup a list of free pages from the free page database. lookupFreePageIds :: (Functor m, AllocReaderM m, MonadState (WriterEnv hnd) m) => FreeTree -> m (Maybe (Unchecked (TxId, NonEmpty PageId))) -- | Auxiliry type to ensure the transaction ID of free pages are checked. newtype Unchecked a Unchecked :: a -> Unchecked a -- | Check the transaction ID of the free pages, if it's to old, return -- Nothing. checkFreePages :: (Functor m, MonadIO m, MonadState (WriterEnv hnd) m) => Unchecked (TxId, NonEmpty PageId) -> m (Maybe (TxId, NonEmpty PageId)) -- | This module implements the ConcurrentT monad. -- -- The ConcurrentT monad is used to implement a page allocator -- with concurrent readers and serialized writers. module Database.Haskey.Alloc.Concurrent.Monad -- | All necessary database handles. data ConcurrentHandles ConcurrentHandles :: FilePath -> FilePath -> FilePath -> FilePath -> FilePath -> FilePath -> ConcurrentHandles [concurrentHandlesRoot] :: ConcurrentHandles -> FilePath [concurrentHandlesData] :: ConcurrentHandles -> FilePath [concurrentHandlesIndex] :: ConcurrentHandles -> FilePath [concurrentHandlesMetadata1] :: ConcurrentHandles -> FilePath [concurrentHandlesMetadata2] :: ConcurrentHandles -> FilePath [concurrentHandlesOverflowDir] :: ConcurrentHandles -> FilePath -- | Construct a set of ConcurrentHandles from a root directory. concurrentHandles :: FilePath -> ConcurrentHandles -- | Monad in which page allocations can take place. -- -- The monad has access to a ConcurrentMetaStoreM back-end which -- manages can store and retreive the corresponding metadata. newtype ConcurrentT env hnd m a ConcurrentT :: StateT (env hnd) m a -> ConcurrentT env hnd m a [fromConcurrentT] :: ConcurrentT env hnd m a -> StateT (env hnd) m a -- | Run the actions in an ConcurrentT monad, given a reader or -- writer environment. runConcurrentT :: ConcurrentMetaStoreM m => ConcurrentT env ConcurrentHandles m a -> env ConcurrentHandles -> m (a, env ConcurrentHandles) -- | Evaluate the actions in an ConcurrentT monad, given a reader or -- writer environment. evalConcurrentT :: ConcurrentMetaStoreM m => ConcurrentT env ConcurrentHandles m a -> env ConcurrentHandles -> m a readOverflow' :: (ConcurrentMetaStoreM m, Value v) => FilePath -> OverflowId -> ConcurrentT env hnd m v getWriterHnd :: MonadState (WriterEnv ConcurrentHandles) m => Height height -> m FilePath getReaderHnd :: MonadState (ReaderEnv ConcurrentHandles) m => Height height -> m FilePath instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (env hnd) (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT env hnd m) instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT env hnd m) instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT env hnd m) instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT env hnd m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT env hnd m) instance GHC.Base.Monad m => GHC.Base.Monad (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT env hnd m) instance GHC.Base.Monad m => GHC.Base.Applicative (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT env hnd m) instance GHC.Base.Functor m => GHC.Base.Functor (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT env hnd m) instance GHC.Show.Show Database.Haskey.Alloc.Concurrent.Monad.ConcurrentHandles instance Control.Monad.Trans.Class.MonadTrans (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT env hnd) instance (Database.Haskey.Alloc.Concurrent.Meta.ConcurrentMetaStoreM m, Control.Monad.IO.Class.MonadIO m) => Data.BTree.Alloc.Class.AllocM (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT Database.Haskey.Alloc.Concurrent.Environment.WriterEnv Database.Haskey.Alloc.Concurrent.Monad.ConcurrentHandles m) instance Database.Haskey.Alloc.Concurrent.Meta.ConcurrentMetaStoreM m => Data.BTree.Alloc.Class.AllocReaderM (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT Database.Haskey.Alloc.Concurrent.Environment.WriterEnv Database.Haskey.Alloc.Concurrent.Monad.ConcurrentHandles m) instance Database.Haskey.Alloc.Concurrent.Meta.ConcurrentMetaStoreM m => Data.BTree.Alloc.Class.AllocReaderM (Database.Haskey.Alloc.Concurrent.Monad.ConcurrentT Database.Haskey.Alloc.Concurrent.Environment.ReaderEnv Database.Haskey.Alloc.Concurrent.Monad.ConcurrentHandles m) -- | This module implements data structures and functions related to the -- database. module Database.Haskey.Alloc.Concurrent.Database -- | An active concurrent database. -- -- This can be shared amongst threads. data ConcurrentDb root ConcurrentDb :: ConcurrentHandles -> RLock -> TVar CurrentMetaPage -> TVar (ConcurrentMeta root) -> TVar (ConcurrentMeta root) -> Map TxId Integer -> ConcurrentDb root [concurrentDbHandles] :: ConcurrentDb root -> ConcurrentHandles [concurrentDbWriterLock] :: ConcurrentDb root -> RLock [concurrentDbCurrentMeta] :: ConcurrentDb root -> TVar CurrentMetaPage [concurrentDbMeta1] :: ConcurrentDb root -> TVar (ConcurrentMeta root) [concurrentDbMeta2] :: ConcurrentDb root -> TVar (ConcurrentMeta root) [concurrentDbReaders] :: ConcurrentDb root -> Map TxId Integer -- | Lock the database. -- -- This needs to be called manually, if you want exclusive access, before -- calling either createConcurrentDb or openConcurrentDb -- -- Use unlockConcurrentDb using the bracket pattern to -- properly unlock the database. lockConcurrentDb :: ConcurrentMetaStoreM m => ConcurrentHandles -> m () -- | Unlock the database. unlockConcurrentDb :: ConcurrentMetaStoreM m => ConcurrentHandles -> m () -- | Open all concurrent handles. openConcurrentHandles :: ConcurrentMetaStoreM m => ConcurrentHandles -> m () -- | Open a new concurrent database, with the given handles. createConcurrentDb :: (Root root, MonadIO m, MonadMask m, ConcurrentMetaStoreM m) => ConcurrentHandles -> root -> m (ConcurrentDb root) -- | Open the an existing database, with the given handles. openConcurrentDb :: (Root root, MonadIO m, MonadMask m, ConcurrentMetaStoreM m) => ConcurrentHandles -> m (Maybe (ConcurrentDb root)) -- | Close the handles of the database. closeConcurrentHandles :: (MonadIO m, ConcurrentMetaStoreM m) => ConcurrentHandles -> m () -- | Create a new concurrent database with handles and metadata provided. newConcurrentDb :: (Root root, MonadIO m) => ConcurrentHandles -> ConcurrentMeta root -> m (ConcurrentDb root) -- | Get the current meta data. getCurrentMeta :: Root root => ConcurrentDb root -> STM (ConcurrentMeta root) -- | Write the new metadata, and switch the pointer to the current one. setCurrentMeta :: (Root root, MonadIO m, ConcurrentMetaStoreM m) => ConcurrentMeta root -> ConcurrentDb root -> m () -- | Execute a write transaction, with a result. transact :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m, Root root) => (forall n. (AllocM n, MonadMask n) => root -> n (Transaction root a)) -> ConcurrentDb root -> m a -- | Execute a write transaction, without cleaning up old overflow pages. transactNow :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m, Root root) => (forall n. (AllocM n, MonadMask n) => root -> n (Transaction root a)) -> ConcurrentDb root -> m a -- | Execute a write transaction, without a result. transact_ :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m, Root root) => (forall n. (AllocM n, MonadMask n) => root -> n (Transaction root ())) -> ConcurrentDb root -> m () -- | Execute a read-only transaction. transactReadOnly :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m, Root root) => (forall n. (AllocReaderM n, MonadMask n) => root -> n a) -> ConcurrentDb root -> m a -- | Run a write action that takes the current meta-data and returns new -- meta-data to be commited, or Nothing if the write transaction -- should be aborted. actAndCommit :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m, Root root) => ConcurrentDb root -> (forall n. (MonadIO n, MonadMask n, ConcurrentMetaStoreM n) => ConcurrentMeta root -> ConcurrentT WriterEnv ConcurrentHandles n (Maybe (ConcurrentMeta root), a)) -> m a -- | Cleanup after an exception occurs, or after a program crash. -- -- The TxId of the aborted transaction should be passed. cleanupAfterException :: (MonadIO m, MonadCatch m, ConcurrentMetaStoreM m) => ConcurrentHandles -> TxId -> m () -- | Remove all overflow pages that were written in the transaction. -- -- If the transaction is aborted, all written pages should be deleted. removeNewlyAllocatedOverflows :: (MonadIO m, ConcurrentMetaStoreM m) => WriterEnv ConcurrentHandles -> m () -- | Update the meta-data from a writer environment updateMeta :: WriterEnv ConcurrentHandles -> ConcurrentMeta root -> ConcurrentMeta root -- | Save the newly free'd overflow pages, for deletion on the next tx. saveOverflowIds :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m) => StateT (ConcurrentMeta root, WriterEnv ConcurrentHandles) m () -- | Save the free'd pages to the free page database saveFreePages' :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m) => Int -> (forall a. a -> S t a) -> (forall hnds. WriterEnv hnds -> FileState t) -> (forall hnds. WriterEnv hnds -> FileState t -> WriterEnv hnds) -> StateT (ConcurrentMeta root, WriterEnv ConcurrentHandles) m () -- | Handle the cached free pages. -- -- Save the cached free pages to the metadata for later use. -- -- Update the database size. handleCachedFreePages :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m) => StateT (ConcurrentMeta root, WriterEnv ConcurrentHandles) m () -- | The module implements an page allocator with page reuse and support -- for multiple readers and serialized writers. module Database.Haskey.Alloc.Concurrent -- | An active concurrent database. -- -- This can be shared amongst threads. data ConcurrentDb root ConcurrentDb :: ConcurrentHandles -> RLock -> TVar CurrentMetaPage -> TVar (ConcurrentMeta root) -> TVar (ConcurrentMeta root) -> Map TxId Integer -> ConcurrentDb root [concurrentDbHandles] :: ConcurrentDb root -> ConcurrentHandles [concurrentDbWriterLock] :: ConcurrentDb root -> RLock [concurrentDbCurrentMeta] :: ConcurrentDb root -> TVar CurrentMetaPage [concurrentDbMeta1] :: ConcurrentDb root -> TVar (ConcurrentMeta root) [concurrentDbMeta2] :: ConcurrentDb root -> TVar (ConcurrentMeta root) [concurrentDbReaders] :: ConcurrentDb root -> Map TxId Integer -- | All necessary database handles. data ConcurrentHandles ConcurrentHandles :: FilePath -> FilePath -> FilePath -> FilePath -> FilePath -> FilePath -> ConcurrentHandles [concurrentHandlesRoot] :: ConcurrentHandles -> FilePath [concurrentHandlesData] :: ConcurrentHandles -> FilePath [concurrentHandlesIndex] :: ConcurrentHandles -> FilePath [concurrentHandlesMetadata1] :: ConcurrentHandles -> FilePath [concurrentHandlesMetadata2] :: ConcurrentHandles -> FilePath [concurrentHandlesOverflowDir] :: ConcurrentHandles -> FilePath -- | Construct a set of ConcurrentHandles from a root directory. concurrentHandles :: FilePath -> ConcurrentHandles -- | Lock the database. -- -- This needs to be called manually, if you want exclusive access, before -- calling either createConcurrentDb or openConcurrentDb -- -- Use unlockConcurrentDb using the bracket pattern to -- properly unlock the database. lockConcurrentDb :: ConcurrentMetaStoreM m => ConcurrentHandles -> m () -- | Unlock the database. unlockConcurrentDb :: ConcurrentMetaStoreM m => ConcurrentHandles -> m () -- | Open a new concurrent database, with the given handles. createConcurrentDb :: (Root root, MonadIO m, MonadMask m, ConcurrentMetaStoreM m) => ConcurrentHandles -> root -> m (ConcurrentDb root) -- | Open the an existing database, with the given handles. openConcurrentDb :: (Root root, MonadIO m, MonadMask m, ConcurrentMetaStoreM m) => ConcurrentHandles -> m (Maybe (ConcurrentDb root)) -- | Close the handles of the database. closeConcurrentHandles :: (MonadIO m, ConcurrentMetaStoreM m) => ConcurrentHandles -> m () -- | Execute a write transaction, with a result. transact :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m, Root root) => (forall n. (AllocM n, MonadMask n) => root -> n (Transaction root a)) -> ConcurrentDb root -> m a -- | Execute a write transaction, without a result. transact_ :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m, Root root) => (forall n. (AllocM n, MonadMask n) => root -> n (Transaction root ())) -> ConcurrentDb root -> m () -- | Execute a read-only transaction. transactReadOnly :: (MonadIO m, MonadMask m, ConcurrentMetaStoreM m, Root root) => (forall n. (AllocReaderM n, MonadMask n) => root -> n a) -> ConcurrentDb root -> m a -- | User-defined data root stored inside ConcurrentMeta. -- -- This can be a user-defined collection of Tree roots. class Value root => Root root -- | Meta data of the page allocator. -- -- The root type parameter should be a user-defined collection -- of Tree roots, instantiating the Root type class. -- -- To store store a single tree, use ConcurrentMeta (Tree k v). data ConcurrentMeta root ConcurrentMeta :: TxId -> S 'TypeData PageId -> S 'TypeIndex PageId -> root -> S 'TypeData FreeTree -> S 'TypeIndex FreeTree -> OverflowTree -> S 'TypeData [FreePage] -> S 'TypeIndex [FreePage] -> ConcurrentMeta root [concurrentMetaRevision] :: ConcurrentMeta root -> TxId [concurrentMetaDataNumPages] :: ConcurrentMeta root -> S 'TypeData PageId [concurrentMetaIndexNumPages] :: ConcurrentMeta root -> S 'TypeIndex PageId [concurrentMetaRoot] :: ConcurrentMeta root -> root [concurrentMetaDataFreeTree] :: ConcurrentMeta root -> S 'TypeData FreeTree [concurrentMetaIndexFreeTree] :: ConcurrentMeta root -> S 'TypeIndex FreeTree [concurrentMetaOverflowTree] :: ConcurrentMeta root -> OverflowTree [concurrentMetaDataCachedFreePages] :: ConcurrentMeta root -> S 'TypeData [FreePage] [concurrentMetaIndexCachedFreePages] :: ConcurrentMeta root -> S 'TypeIndex [FreePage] -- | A class representing the storage requirements of the page allocator. -- -- A store supporting the page allocator should be an instance of this -- class. class StoreM FilePath m => ConcurrentMetaStoreM m -- | Write the meta-data structure to a certain page. putConcurrentMeta :: (ConcurrentMetaStoreM m, Root root) => FilePath -> ConcurrentMeta root -> m () -- | Try to read the meta-data structure from a handle, or return -- Nothing if the handle doesn't contain a meta page. readConcurrentMeta :: (ConcurrentMetaStoreM m, Root root) => FilePath -> Proxy root -> m (Maybe (ConcurrentMeta root)) -- | This module contains structures and functions to decode and encode -- pages. module Database.Haskey.Store.Page -- | The type of a page. data PageType TypeEmpty :: PageType TypeConcurrentMeta :: PageType TypeOverflow :: PageType TypeLeafNode :: PageType TypeIndexNode :: PageType data SPageType t [STypeEmpty] :: SPageType 'TypeEmpty [STypeConcurrentMeta] :: SPageType 'TypeConcurrentMeta [STypeOverflow] :: SPageType 'TypeOverflow [STypeLeafNode] :: SPageType 'TypeLeafNode [STypeIndexNode] :: SPageType 'TypeIndexNode -- | A decoded page, of a certain type t of kind PageType. data Page (t :: PageType) [EmptyPage] :: Page 'TypeEmpty [ConcurrentMetaPage] :: Root root => ConcurrentMeta root -> Page 'TypeConcurrentMeta [OverflowPage] :: (Value v) => v -> Page 'TypeOverflow [LeafNodePage] :: (Key k, Value v) => Height 'Z -> Node 'Z k v -> Page 'TypeLeafNode [IndexNodePage] :: (Key k, Value v) => Height ( 'S h) -> Node ( 'S h) k v -> Page 'TypeIndexNode -- | A decoder with its type. data SGet t SGet :: (SPageType t) -> (Get (Page t)) -> SGet t -- | Get the type of a Page. pageType :: SPageType t -> PageType -- | Encode a page to a lazy byte string, but with the checksum set to -- zero. encodeZeroChecksum :: Page t -> ByteString -- | Encode a page to a lazy byte string, and prepend the calculated -- checksum. encode :: Page t -> ByteString -- | Prepend the xxHash 64-bit checksum of a bytestring to itself. prependChecksum :: ByteString -> ByteString -- | Encode a page to a lazy byte string, without prepending the checksum. encodeNoChecksum :: Page t -> ByteString -- | Size of a node, if it were to be encoded. encodedPageSize :: (Key k, Value v) => Height h -> Node h k v -> PageSize -- | Decode a page, and verify the checksum. decode :: SGet t -> ByteString -> Either String (Page t) -- | Decode a page with a specific decoder, or return the error. decodeNoChecksum :: SGet t -> ByteString -> Either String (Page t) -- | Monadic wrapper around decode decodeM :: MonadThrow m => SGet t -> ByteString -> m (Page t) -- | The encoder of a Page. putPage :: Page t -> Put -- | Decoder for an empty page. emptyPage :: SGet 'TypeEmpty -- | Decoder for a leaf node page. leafNodePage :: (Key k, Value v) => Height 'Z -> Proxy k -> Proxy v -> SGet 'TypeLeafNode -- | Decoder for a leaf node page. indexNodePage :: (Key k, Value v) => Height ( 'S n) -> Proxy k -> Proxy v -> SGet 'TypeIndexNode -- | Decoder for an overflow page. overflowPage :: (Value v) => Proxy v -> SGet 'TypeOverflow concurrentMetaPage :: Root root => Proxy root -> SGet 'TypeConcurrentMeta -- | Exception thrown when decoding of a page fails. newtype DecodeError DecodeError :: String -> DecodeError checksumSeed :: Word64 instance GHC.Show.Show Database.Haskey.Store.Page.DecodeError instance GHC.Show.Show Database.Haskey.Store.Page.PageType instance GHC.Classes.Eq Database.Haskey.Store.Page.PageType instance GHC.Exception.Exception Database.Haskey.Store.Page.DecodeError instance Data.Binary.Class.Binary Database.Haskey.Store.Page.PageType -- | Binary in-memory storage back-end. Can be used as a storage back-end -- for the append-only page allocator (see Data.BTree.Alloc). module Database.Haskey.Store.InMemory -- | A decoded page, of a certain type t of kind PageType. data Page (t :: PageType) [EmptyPage] :: Page 'TypeEmpty [ConcurrentMetaPage] :: Root root => ConcurrentMeta root -> Page 'TypeConcurrentMeta [OverflowPage] :: (Value v) => v -> Page 'TypeOverflow [LeafNodePage] :: (Key k, Value v) => Height 'Z -> Node 'Z k v -> Page 'TypeLeafNode [IndexNodePage] :: (Key k, Value v) => Height ( 'S h) -> Node ( 'S h) k v -> Page 'TypeIndexNode -- | A file containing a collection of pages. type MemoryFile = Map PageId ByteString -- | A collection of Files, each associated with a certain -- fp handle. -- -- This is shareable amongst multiple threads. type MemoryFiles fp = MVar (Map fp MemoryFile) -- | Memory store configuration. -- -- The default configuration can be obtained by using -- defMemoryStoreConfig. -- -- A configuration with a specific page size can be obtained by using -- memoryStoreConfigWithPageSize. data MemoryStoreConfig MemoryStoreConfig :: !PageSize -> !Word64 -> !Word64 -> MemoryStoreConfig [memoryStoreConfigPageSize] :: MemoryStoreConfig -> !PageSize [memoryStoreConfigMaxKeySize] :: MemoryStoreConfig -> !Word64 [memoryStoreConfigMaxValueSize] :: MemoryStoreConfig -> !Word64 -- | The default configuration. -- -- This is an unwrapped memoryStoreConfigWithPageSize with a page -- size of 4096. defMemoryStoreConfig :: MemoryStoreConfig -- | Create a configuration with a specific page size. -- -- The maximum key and value sizes are calculated using -- calculateMaxKeySize and calculateMaxValueSize. -- -- If the page size is too small, Nothing is returned. memoryStoreConfigWithPageSize :: PageSize -> Maybe MemoryStoreConfig -- | Monad in which binary storage operations can take place. -- -- Two important instances are StoreM making it a storage -- back-end, and ConcurrentMetaStoreM making it a storage back-end -- compatible with the concurrent page allocator. data MemoryStoreT fp m a -- | Run the storage operations in the MemoryStoreT monad, given a -- collection of Files. runMemoryStoreT :: MemoryStoreT fp m a -> MemoryStoreConfig -> MemoryFiles fp -> m a -- | Construct a store with an empty database with name of type -- hnd. newEmptyMemoryStore :: IO (MemoryFiles hnd) -- | Exception thrown when a file is accessed that doesn't exist. newtype FileNotFoundError hnd FileNotFoundError :: hnd -> FileNotFoundError hnd -- | Exception thrown when a page that is accessed doesn't exist. data PageNotFoundError hnd PageNotFoundError :: hnd -> PageId -> PageNotFoundError hnd -- | Exception thrown when a node cannot be cast to the right type. -- -- As used in getNodePage. data WrongNodeTypeError WrongNodeTypeError :: WrongNodeTypeError -- | Exception thrown when a value from an overflow page cannot be cast. -- -- As used in getOverflow. data WrongOverflowValueError WrongOverflowValueError :: WrongOverflowValueError instance GHC.Show.Show Database.Haskey.Store.InMemory.WrongOverflowValueError instance GHC.Show.Show Database.Haskey.Store.InMemory.WrongNodeTypeError instance GHC.Show.Show hnd => GHC.Show.Show (Database.Haskey.Store.InMemory.PageNotFoundError hnd) instance GHC.Show.Show hnd => GHC.Show.Show (Database.Haskey.Store.InMemory.FileNotFoundError hnd) instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader Database.Haskey.Store.InMemory.MemoryStoreConfig (Database.Haskey.Store.InMemory.MemoryStoreT fp m) instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Database.Haskey.Store.InMemory.MemoryStoreT fp m) instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Database.Haskey.Store.InMemory.MemoryStoreT fp m) instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Database.Haskey.Store.InMemory.MemoryStoreT fp m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Database.Haskey.Store.InMemory.MemoryStoreT fp m) instance GHC.Base.Monad m => GHC.Base.Monad (Database.Haskey.Store.InMemory.MemoryStoreT fp m) instance GHC.Base.Functor m => GHC.Base.Functor (Database.Haskey.Store.InMemory.MemoryStoreT fp m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Haskey.Store.InMemory.MemoryStoreT fp m) instance GHC.Show.Show Database.Haskey.Store.InMemory.MemoryStoreConfig instance (GHC.Base.Applicative m, GHC.Base.Monad m, Control.Monad.IO.Class.MonadIO m, Control.Monad.Catch.MonadThrow m, GHC.Classes.Ord fp, GHC.Show.Show fp, Data.Typeable.Internal.Typeable fp) => Database.Haskey.Store.Class.StoreM fp (Database.Haskey.Store.InMemory.MemoryStoreT fp m) instance GHC.Exception.Exception Database.Haskey.Store.InMemory.WrongOverflowValueError instance GHC.Exception.Exception Database.Haskey.Store.InMemory.WrongNodeTypeError instance (Data.Typeable.Internal.Typeable hnd, GHC.Show.Show hnd) => GHC.Exception.Exception (Database.Haskey.Store.InMemory.PageNotFoundError hnd) instance (Data.Typeable.Internal.Typeable hnd, GHC.Show.Show hnd) => GHC.Exception.Exception (Database.Haskey.Store.InMemory.FileNotFoundError hnd) instance (GHC.Base.Applicative m, GHC.Base.Monad m, Control.Monad.IO.Class.MonadIO m, Control.Monad.Catch.MonadCatch m) => Database.Haskey.Alloc.Concurrent.Meta.ConcurrentMetaStoreM (Database.Haskey.Store.InMemory.MemoryStoreT GHC.IO.FilePath m) -- | On-disk storage back-end. Can be used as a storage back-end for the -- append-only page allocator (see Data.BTree.Alloc). module Database.Haskey.Store.File -- | A decoded page, of a certain type t of kind PageType. data Page (t :: PageType) [EmptyPage] :: Page 'TypeEmpty [ConcurrentMetaPage] :: Root root => ConcurrentMeta root -> Page 'TypeConcurrentMeta [OverflowPage] :: (Value v) => v -> Page 'TypeOverflow [LeafNodePage] :: (Key k, Value v) => Height 'Z -> Node 'Z k v -> Page 'TypeLeafNode [IndexNodePage] :: (Key k, Value v) => Height ( 'S h) -> Node ( 'S h) k v -> Page 'TypeIndexNode -- | File store configuration. -- -- The default configuration can be obtained by using -- defFileStoreConfig -- -- A configuration with a specific page size can be obtained by using -- fileStoreConfigWithPageSize. data FileStoreConfig FileStoreConfig :: !PageSize -> !Word64 -> !Word64 -> FileStoreConfig [fileStoreConfigPageSize] :: FileStoreConfig -> !PageSize [fileStoreConfigMaxKeySize] :: FileStoreConfig -> !Word64 [fileStoreConfigMaxValueSize] :: FileStoreConfig -> !Word64 -- | The default configuration -- -- This is an unwrapped fileStoreConfigWithPageSize with a page -- size of 4096 bytes. defFileStoreConfig :: FileStoreConfig -- | Create a configuration with a specific page size. -- -- The maximum key and value sizes are calculated using -- calculateMaxKeySize and calculateMaxValueSize. -- -- If the page size is too small, Nothing is returned. fileStoreConfigWithPageSize :: PageSize -> Maybe FileStoreConfig -- | Monad in which on-disk storage operations can take place. -- -- Two important instances are StoreM making it a storage -- back-end, and ConcurrentMetaStoreM making it a storage back-end -- compatible with the concurrent page allocator. data FileStoreT fp m a -- | Run the storage operations in the FileStoreT monad, given a -- collection of open files. runFileStoreT :: Monad m => FileStoreT FilePath m a -> FileStoreConfig -> m a -- | Encode a page padding it to the maxim page size. -- -- Return Nothing of the page is too large to fit into one page -- size. encodeAndPad :: PageSize -> Page t -> Maybe ByteString -- | Exception thrown when a file is accessed that doesn't exist. newtype FileNotFoundError hnd FileNotFoundError :: hnd -> FileNotFoundError hnd -- | Exception thrown when a page that is too large is written. -- -- As used in putNodePage. data PageOverflowError PageOverflowError :: PageOverflowError -- | Exception thrown when a node cannot be cast to the right type. -- -- As used in getNodePage. data WrongNodeTypeError WrongNodeTypeError :: WrongNodeTypeError -- | Exception thrown when a value from an overflow page cannot be cast. -- -- As used in getOverflow. data WrongOverflowValueError WrongOverflowValueError :: WrongOverflowValueError instance GHC.Show.Show Database.Haskey.Store.File.WrongOverflowValueError instance GHC.Show.Show Database.Haskey.Store.File.WrongNodeTypeError instance GHC.Show.Show Database.Haskey.Store.File.PageOverflowError instance GHC.Show.Show hnd => GHC.Show.Show (Database.Haskey.Store.File.FileNotFoundError hnd) instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (Database.Haskey.Store.File.Files fp) (Database.Haskey.Store.File.FileStoreT fp m) instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader Database.Haskey.Store.File.FileStoreConfig (Database.Haskey.Store.File.FileStoreT fp m) instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Database.Haskey.Store.File.FileStoreT fp m) instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Database.Haskey.Store.File.FileStoreT fp m) instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Database.Haskey.Store.File.FileStoreT fp m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Database.Haskey.Store.File.FileStoreT fp m) instance GHC.Base.Monad m => GHC.Base.Monad (Database.Haskey.Store.File.FileStoreT fp m) instance GHC.Base.Functor m => GHC.Base.Functor (Database.Haskey.Store.File.FileStoreT fp m) instance GHC.Base.Monad m => GHC.Base.Applicative (Database.Haskey.Store.File.FileStoreT fp m) instance GHC.Show.Show Database.Haskey.Store.File.FileStoreConfig instance (GHC.Base.Applicative m, GHC.Base.Monad m, Control.Monad.IO.Class.MonadIO m, Control.Monad.Catch.MonadThrow m) => Database.Haskey.Store.Class.StoreM GHC.IO.FilePath (Database.Haskey.Store.File.FileStoreT GHC.IO.FilePath m) instance GHC.Exception.Exception Database.Haskey.Store.File.WrongOverflowValueError instance GHC.Exception.Exception Database.Haskey.Store.File.WrongNodeTypeError instance GHC.Exception.Exception Database.Haskey.Store.File.PageOverflowError instance (Data.Typeable.Internal.Typeable hnd, GHC.Show.Show hnd) => GHC.Exception.Exception (Database.Haskey.Store.File.FileNotFoundError hnd) instance (GHC.Base.Applicative m, GHC.Base.Monad m, Control.Monad.IO.Class.MonadIO m, Control.Monad.Catch.MonadCatch m) => Database.Haskey.Alloc.Concurrent.Meta.ConcurrentMetaStoreM (Database.Haskey.Store.File.FileStoreT GHC.IO.FilePath m)