-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A thread-safe interface for finite map types with optional persistency support. -- -- Changes in 0.1.*: -- -- -- -- This library provides a thread-safe (STM) frontend for finite map -- types together with a backend interface for persistent storage. The -- TMap data type is thread-safe, since all access functions run -- inside an STM monad . Any type instantiating -- Data.Edison.Assoc.FiniteMapX (see EdisonAPI) can be used as a -- map type. -- -- When a TMap is modified within an STM transaction, a corresponding -- backend IO-request is added using the onCommit hook (cf. stm-io-hooks -- package). To ensure consistency, the (Adv)STM monad runs these -- requests iff the transaction commits. Additional backends (e.g. HDBC) -- can be added by instantiating the class Backend. -- -- Example: -- -- Thread 1: -- --
--   atomically $ do
--     isMemb <- member 1 tmap
--     when (not isMemb) $
--       insert 1 "john doe" tmap
--   
-- -- Thread 2: -- --
--   atomically $ do
--     v <- lookup 1 tmap
--     -- ... do something with 'v'
--     adjust (\_ -> "jd") 1 tmap
--   
-- -- The function member will first check whether the key value '1' -- is in the map; if not, it sends a lookup-request to the persistent -- backend and then retries the transaction. Note that "sending a -- lookup-request" essentially means adding a call to the corresponding -- IO-function of the backend to the list of retry-IO actions. (This is -- done using the retryWith IO hook of the stm-io-package.) -- -- If the value does not exist yet, function insert adds the -- key-value mapping to the TMap and sends an insert-request to the -- backend using the onCommit hook of the stm-io-package. Note -- that onCommit guarantees that the backend IO action is only -- executed iff the transaction commits. Any changes that were made to -- the TMap are invisible to other threads until the onCommit actions are -- run. Therefore, the threads will always observe a consistent state. -- -- The module Data.TStorage provides a high level interface to -- TMap inspired by the TCache package ((C) Alberto Gomez Corona). It can -- store any type that has a key (i.e. is an instance of type class -- HasKey). See file Sample.hs for an example on how to use it. -- -- Warning: This package is very experimental and the interface -- will probably change. @package persistent-map @version 0.1.1 -- | A type class for implementing different caching policies (e.g. LRU, -- LFU,... ). Should be imported qualified. module Data.CacheStructure -- | A type class for implementing a caching policy (e.g. LRU) class CacheStructure c a hit :: (CacheStructure c a) => a -> c a -> c a last :: (CacheStructure c a) => c a -> a pop :: (CacheStructure c a) => c a -> (c a, a) empty :: (CacheStructure c a) => c a null :: (CacheStructure c a) => c a -> Bool toList :: (CacheStructure c a) => c a -> [a] delete :: (CacheStructure c a) => a -> c a -> c a member :: (CacheStructure c a) => a -> c a -> Bool size :: (CacheStructure c a) => c a -> Int popMany :: (CacheStructure c a) => Int -> c a -> (c a, [a]) data CacheException CacheException :: String -> CacheException instance Typeable CacheException instance Show CacheException instance Eq CacheException instance Exception CacheException -- | Provides a least recently used caching policy. Note: This module is -- simply a wrapper around the LRU-package. module Data.CacheStructure.LRU instance (Ord a) => CacheStructure LRU a -- | Provides a type class for backends. To avoid data inconsistencies, -- these functmns should not be used directly but only by means of the -- TMap interface. module Data.TMap.Backend -- | This class needs to be instantiated when developing a new backend. The -- backend is expected to be able to handle concurrent (non-conflicting) -- requests. class (Ord k) => Backend k a b | a -> k insert :: (Backend k a b) => b k a -> k -> a -> IO () adjust :: (Backend k a b) => b k a -> (a -> a) -> k -> IO () delete :: (Backend k a b) => b k a -> k -> IO () lookup :: (Backend k a b) => b k a -> k -> IO (Maybe a) flush :: (Backend k a b) => b k a -> IO () initialize :: (Backend k a b) => b k a -> IO () -- | Proivides a (simplistic) backend using the binary package. Every entry -- of the map is written to a separate file where the filename is the -- key. -- -- Note: This interface is only thread-safe when being used via TMap! module Data.TMap.Backend.Binary -- | Creates a new backend that stores one file per entry in the given -- working directory. mkBinaryBackend :: FilePath -> IO (BinaryBackend k a) -- | The binary-backend type data BinaryBackend k a instance (Show k, Ord k, Binary a) => Backend k a BinaryBackend -- | A backend instantiation that ignores all requests. module Data.TMap.Backend.NoBackend data NoBackend k a NoBackend :: NoBackend k a instance (Ord k) => Backend k a NoBackend -- | Simply prints out all backend requests to stdout. module Data.TMap.Backend.StdoutBackend data StdoutBackend k a -- | Creates a new StdoutBackend. newStdoutBackend :: StdoutBackend k a instance (Show a, Show k, Ord k) => Backend k a StdoutBackend -- | Provides a thread-safe STM interface for finite map types with -- optional persistent storage. module Data.TMap data TMap map k a b c -- | Creates a new TMap. You will need to use an apropriate backend and -- specify the caching policy, e.g., -- --
--   import Data.TMap.Backend.Binary( BinaryBackend,mkBinaryBackend )
--   import Data.TMap.CacheStructure.LRU
--   
-- -- will use a binary-serialization backend for persistent storage and a -- "least recently used" caching algorithm. -- -- Now, to create an unbounded map that uses the 'FM Int String' (see -- package EdisonCore) as the map type, you can write -- --
--   backend <- mkBinaryBackend "myworkdir" "mytempdir"
--   tmap <- newTMapIO backend Nothing :: IO (TMap (FM Int) Int String BinaryBackend LRU)
--   
newTMapIO :: (FiniteMapX map k, Ord k, Backend k a b, CacheStructure c k) => b k a -> Maybe Int -> IO (TMap map k a b c) -- | Looks for a given key in the map and (if necessary) in the persistent -- storage and updates the map if necessary. lookup :: (FiniteMapX map k, MonadAdvSTM m, Ord k, Backend k a b, CacheStructure c k) => k -> TMap map k a b c -> m (Maybe a) -- | Adds a key-value mapping to the map. Can throw a DuplicateEntry -- exception. insert :: (FiniteMapX map k, MonadAdvSTM m, Ord k, Backend k a b, CacheStructure c k) => k -> a -> TMap map k a b c -> m () -- | Removes a key from the map. Can throw an EntryNotFound -- exception. delete :: (FiniteMapX map k, MonadAdvSTM m, Ord k, Backend k a b, CacheStructure c k) => k -> TMap map k a b c -> m () -- | Checks whether the given key is in the map. member :: (FiniteMapX map k, MonadAdvSTM m, Ord k, Backend k a b, CacheStructure c k) => k -> TMap map k a b c -> m Bool -- | Applies a function to the element identified by the key. Can throw an -- EntryNotFound exception. adjust :: (FiniteMapX map k, MonadAdvSTM m, Ord k, Backend k a b, CacheStructure c k) => (a -> a) -> k -> TMap map k a b c -> m () -- | Reduces the map to the appropriate size if the maximum size was -- exceeded. Calls Data.TMap.Backend.flush if the map is purged. -- Runs in O(1) if the map size is within bounds, otherwise -- O(n). Warning: This function should always be called at -- the end of a transaction to prevent nonterminating retry-loops! purgeTMap :: (FiniteMapX map k, MonadAdvSTM m, Ord k, Backend k a b, CacheStructure c k) => TMap map k a b c -> m () -- | Reduces the map to the appropriate size if the maximum size was -- exceeded. Calls Data.TMap.Backend.flush if the map is purged. -- Runs in O(1) if the map size is within bounds, otherwise -- O(n). purgeTMapIO :: (FiniteMapX map k, MonadIO m, Ord k, Backend k a b, CacheStructure c k) => TMap map k a b c -> m () -- | Gets the maximum size of the map. O(1). getMaximumSize :: (FiniteMapX map k, MonadAdvSTM m, Ord k, Backend k a b, CacheStructure c k) => TMap map k a b c -> m (Maybe Int) -- | Sets the maximum size of the map. O(1). Note that the size of -- the TMap needs to be reduced manually to the maximum size by calling -- purgeTMap. setMaximumSize :: (FiniteMapX map k, MonadAdvSTM m, Ord k, Backend k a b, CacheStructure c k) => TMap map k a b c -> Int -> m () -- | Gets the current size of the map. O(1). getCurrentSize :: (FiniteMapX map k, MonadAdvSTM m, Ord k, Backend k a b, CacheStructure c k) => TMap map k a b c -> m Int -- | Sends a B.flush request to the backend. Useful for asynchronous -- backend implementations. flushBackend :: (FiniteMapX map k, Ord k, Backend k a b, CacheStructure c k) => TMap map k a b c -> IO () data TMapException DuplicateEntry :: TMapException EntryNotFound :: TMapException TMapDefaultExc :: String -> TMapException BackendException :: String -> TMapException instance (Show a) => Show (Entry a) instance (Eq a) => Eq (Entry a) instance Functor Entry -- | Provides a high level interface to Data.TMap. This module was inspired -- by the TCache package, (C) Alberto Gomez Corona. -- -- The essential difference to the low level functions in Data.TMap is -- that this interface assumes that the stored type is an instance of -- HasKey, allowing partially filled (i.e. complete enough for -- deducing the key) values to be passed to the interface functions. module Data.TStorage data TMap map k a b c -- | Instantiated by types where values have a unique key. class HasKey a k | a -> k key :: (HasKey a k) => a -> k -- | Creates a new TMap. You will need to use an apropriate backend and -- specify the caching policy, e.g., -- --
--   import Data.TMap.Backend.Binary( BinaryBackend,mkBinaryBackend )
--   import Data.TMap.CacheStructure.LRU
--   
-- -- will use a binary-serialization backend for persistent storage and a -- "least recently used" caching algorithm. -- -- Now, to create an unbounded map that uses the 'FM Int String' (see -- package EdisonCore) as the map type, you can write -- --
--   backend <- mkBinaryBackend "myworkdir" "mytempdir"
--   tmap <- newTMapIO backend Nothing :: IO (TMap (FM Int) Int String BinaryBackend LRU)
--   
newTMapIO :: (FiniteMapX map k, Ord k, Backend k a b, CacheStructure c k) => b k a -> Maybe Int -> IO (TMap map k a b c) -- | Adds a new element to the map. The key is automatically deduced by the -- HasKey instantiation. add :: (FiniteMapX map k, MonadAdvSTM stm, Ord k, Backend k a b, CacheStructure c k, HasKey a k) => a -> TMap map k a b c -> stm () -- | Tries to fill a partially initialized value with data from the TMap. -- Returns Nothing if the TMap does not contain a corresponding -- entry. tryComplete :: (FiniteMapX map k, MonadAdvSTM stm, Ord k, Backend k a b, CacheStructure c k, HasKey a k) => a -> TMap map k a b c -> stm (Maybe a) -- | Fills a partially initialized value with data from the TMap. Throws an -- EntryNotFound exception if there is no corresponding entry. complete :: (FiniteMapX map k, MonadAdvSTM stm, Ord k, Backend k a b, CacheStructure c k, HasKey a k) => a -> TMap map k a b c -> stm a -- | Removes the element from the map. remove :: (FiniteMapX map k, MonadAdvSTM stm, Ord k, Backend k a b, CacheStructure c k, HasKey a k) => a -> TMap map k a b c -> stm () -- | Removes the entry that has the supplied key. removeByKey :: (FiniteMapX map k, MonadAdvSTM stm, Ord k, Backend k a b, CacheStructure c k, HasKey a k) => k -> TMap map k a b c -> stm () -- | Applies a function to an element that might be only partially -- initialized. apply :: (FiniteMapX map k, MonadAdvSTM stm, Ord k, Backend k a b, CacheStructure c k, HasKey a k) => (a -> a) -> a -> TMap map k a b c -> stm a -- | Reduces the map to the appropriate size if the maximum size was -- exceeded. Calls Data.TMap.Backend.flush if the map is purged. -- Runs in O(1) if the map size is within bounds, otherwise -- O(n). Warning: This function should always be called at -- the end of a transaction to prevent nonterminating retry-loops! purgeTMap :: (FiniteMapX map k, MonadAdvSTM m, Ord k, Backend k a b, CacheStructure c k) => TMap map k a b c -> m () -- | Reduces the map to the appropriate size if the maximum size was -- exceeded. Calls Data.TMap.Backend.flush if the map is purged. -- Runs in O(1) if the map size is within bounds, otherwise -- O(n). purgeTMapIO :: (FiniteMapX map k, MonadIO m, Ord k, Backend k a b, CacheStructure c k) => TMap map k a b c -> m ()