-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | General purpose simple caching. -- @package expiring-cache-map @version 0.0.5.4 -- | TestSequence monad for testing caching behaviour. -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Caching.ExpiringCacheMap.HashECM (newECMForM, lookupECM, CacheSettings(..), consistentDuration)
--   import qualified Caching.ExpiringCacheMap.Utils.TestSequence as TestSeq
--   
--   import qualified Data.ByteString.Char8 as BS
--   
--   test = do
--     (TestSeq.TestSequenceState (_, events, _), return_value) <- TestSeq.runTestSequence test'
--     (putStrLn . show . reverse) events
--     return ()
--     where
--       test' = do
--         filecache <- newECMForM
--               (consistentDuration 100 -- Duration between access and expiry time of each item, no state needed.
--                 (\state _id -> do number <- TestSeq.readNumber
--                                   return (state, number)))
--               (TestSeq.getCurrentTime >>= return)
--               12000 -- Time check frequency: (accumulator `mod` this_number) == 0.
--               (CacheWithLRUList 
--                 6   -- Expected size of key-value map when removing elements.
--                 6   -- Size of map when to remove items from key-value map.
--                 12  -- Size of list when to compact
--                 )
--               TestSeq.newTestSVar TestSeq.enterTestSVar TestSeq.readTestSVar
--         
--         -- Use lookupECM whenever the contents of "file1" is needed.
--         b <- lookupECM filecache ("file1" :: BS.ByteString)
--         TestSeq.haveNumber b
--         b <- lookupECM filecache "file1"
--         b <- lookupECM filecache "file2"
--         TestSeq.haveNumber b
--         return b
--   
-- -- Evaluating the test function results in a list of events. -- --
--   >>> test
--   [GetVar 3,ReadNumber 4,GetTime 7,PutVar 11,HaveNumber 4,GetVar 14,PutVar 17,
--    GetVar 19,ReadNumber 20,GetTime 23,PutVar 27,HaveNumber 20]
--   
-- -- In this example the history shows 2 time accesses (GetTime 7 -- and GetTime 23) since the time check frequency number is a -- high value (12000), but regardless the high value a time check is -- still requested again because of the new key request for -- "file2". -- -- Changing the time frequency to 1 will alter the list of events with -- more frequent time checks: -- --
--   >>> test
--   [GetVar 3,ReadNumber 4,GetTime 7,PutVar 11,HaveNumber 4,GetVar 14,GetTime 15,
--    GetTime 18,PutVar 22,GetVar 24,ReadNumber 25,GetTime 28,PutVar 32,
--    HaveNumber 25]
--   
module Caching.ExpiringCacheMap.Utils.TestSequence runTestSequence :: Show a => TestSequence b a -> IO (TestSequenceState b, a) newTestSVar :: a -> TestSequence a (TestSVar a) enterTestSVar :: TestSVar a -> (a -> TestSequence a (a, b)) -> TestSequence a b readTestSVar :: TestSVar a -> TestSequence a a getCurrentTime :: TestSequence a Int readNumber :: TestSequence a Int haveNumber :: Int -> TestSequence a () data TestSequenceEvents GetVar :: Word32 -> TestSequenceEvents PutVar :: Word32 -> TestSequenceEvents GetTime :: Word32 -> TestSequenceEvents ReadNumber :: Int -> TestSequenceEvents HaveNumber :: Int -> TestSequenceEvents newtype TestSequenceState b TestSequenceState :: (Word32, [TestSequenceEvents], Maybe b) -> TestSequenceState b newtype TestSequence b a TestSequence :: (TestSequenceState b -> (TestSequenceState b, a)) -> TestSequence b a newtype TestSVar a TestSVar :: a -> TestSVar a instance Eq TestSequenceEvents instance Monad (TestSequence a) instance Applicative (TestSequence a) instance Functor (TestSequence a) instance Show (TestSequenceState ct) instance Show TestSequenceEvents -- | Simple types. module Caching.ExpiringCacheMap.Utils.Types -- | Integer involved in the time units used to determine when an item -- expires. The time units used can be any arbitrary integer time -- representation, such as seconds or milliseconds for examples. They can -- also be deterministic time steps in a sequencing monad. type TimeUnits = Int -- | Integer involved in the size of a key-value map. type ECMMapSize = Int -- | Integer involved in the length of the usage history list. type ECMULength = Int -- | Unsigned integer (Word32) involved in the cache state -- incrementing accumulator. type ECMIncr = Word32 -- | Types used by internal functions and as the opaque types exported by -- other modules, assume these type definitions to change from version to -- version. module Caching.ExpiringCacheMap.Internal.Types -- | The type that encapsulates a cache map. newtype ECM a b s m k v ECM :: (b (CacheState s m k v), Maybe s -> k -> a (TimeUnits, (Maybe s, v)), a TimeUnits, ECMMapSize, ECMIncr, ECMULength, ECMULength, ECMEnterState a b s m k v, ECMReadState a b s m k v) -> ECM a b s m k v -- | The cache state. newtype CacheState s m k v CacheState :: (Maybe s, m k (TimeUnits, TimeUnits, v), ECMMapSize, ([(k, ECMIncr)], ECMULength), ECMIncr) -> CacheState s m k v type ECMNewState a b s m k v = (CacheState s m k v) -> a (b (CacheState s m k v)) type ECMEnterState a b s m k v = b (CacheState s m k v) -> ((CacheState s m k v) -> a (CacheState s m k v, v)) -> a v type ECMReadState a b s m k v = b (CacheState s m k v) -> a (CacheState s m k v) -- | Types common to Caching.ExpiringCacheMap.OrdECM and -- Caching.ExpiringCacheMap.HashECM. module Caching.ExpiringCacheMap.Types data CacheSettings -- | A cache that maintains a key access history list to perform removals -- of least recently used entries. Once the key-value map reaches -- removalsize keys, then a list of keys to keep in the map is -- determined which is no larger than mapsize size. Entries are -- removed only on insertion of a new entry in the key-value map. -- -- Key access history entries are prepended to the head of the LRU list, -- if an existing entry for the key appears close to the head of the list -- it is moved to the head of the list, instead of growing the list. When -- the LRU list reaches compactlistsize items, it is compacted by -- removing duplicate keys, by keeping only the most recent accumulator -- value for that key. CacheWithLRUList :: ECMMapSize -> ECMMapSize -> ECMULength -> CacheSettings mapsize :: CacheSettings -> ECMMapSize removalsize :: CacheSettings -> ECMMapSize compactlistsize :: CacheSettings -> ECMULength -- | The type that encapsulates a cache map. data ECM a b s m k v -- | The cache state. data CacheState s m k v -- | Integer involved in the time units used to determine when an item -- expires. The time units used can be any arbitrary integer time -- representation, such as seconds or milliseconds for examples. They can -- also be deterministic time steps in a sequencing monad. type TimeUnits = Int -- | Integer involved in the size of a key-value map. type ECMMapSize = Int -- | Integer involved in the length of the usage history list. type ECMULength = Int -- | Unsigned integer (Word32) involved in the cache state -- incrementing accumulator. type ECMIncr = Word32 type ECMNewState a b s m k v = (CacheState s m k v) -> a (b (CacheState s m k v)) type ECMEnterState a b s m k v = b (CacheState s m k v) -> ((CacheState s m k v) -> a (CacheState s m k v, v)) -> a v type ECMReadState a b s m k v = b (CacheState s m k v) -> a (CacheState s m k v) -- | A module with internal functions used in common by HashECM and OrdECM. -- Assume these functions to change from version to version. module Caching.ExpiringCacheMap.Internal.Internal updateUses :: Eq k => ([(k, ECMIncr)], ECMULength) -> k -> ECMIncr -> ECMULength -> ([(k, ECMIncr)] -> [(k, ECMIncr)]) -> ([(k, ECMIncr)], ECMULength) detECM :: (Monad m, Eq k) => Maybe (TimeUnits, TimeUnits, v) -> Maybe s -> m (TimeUnits, (Maybe s, v)) -> ((TimeUnits, TimeUnits, v) -> mp k (TimeUnits, TimeUnits, v), (TimeUnits, TimeUnits, v) -> [(k, ECMIncr)] -> mp k (TimeUnits, TimeUnits, v), [(k, ECMIncr)] -> [(k, ECMIncr)], ECMMapSize, ECMULength) -> m TimeUnits -> (((TimeUnits, TimeUnits, v) -> Bool) -> mp k (TimeUnits, TimeUnits, v) -> mp k (TimeUnits, TimeUnits, v)) -> ECMMapSize -> (mp k (TimeUnits, TimeUnits, v) -> ECMMapSize) -> ([(k, ECMIncr)], ECMULength) -> ECMIncr -> ECMIncr -> mp k (TimeUnits, TimeUnits, v) -> m ((CacheState s mp k v, v), Bool) -- | Debugging function getStatsString :: (Show t3, Monad m) => ECM m t t1 t2 t3 t4 -> m String -- | A cache that holds values for a length of time that uses -- Hashable keys with Data.HashMap.Strict. -- -- An example of creating a cache for accessing files: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Caching.ExpiringCacheMap.HashECM (newECMIO, lookupECM, CacheSettings(..), consistentDuration)
--   
--   import qualified Data.Time.Clock.POSIX as POSIX (POSIXTime, getPOSIXTime)
--   import qualified Data.ByteString.Char8 as BS
--   import System.IO (withFile, IOMode(ReadMode))
--   
--   example = do
--     filecache <- newECMIO
--           (consistentDuration 100 -- Duration between access and expiry time of each item
--             (\state id -> do BS.putStrLn "Reading a file again..."
--                              withFile (case id :: BS.ByteString of
--                                          "file1" -> "file1.txt"
--                                          "file2" -> "file2.txt")
--                                 ReadMode $
--                                 \fh -> do content <- BS.hGetContents fh
--                                           return $! (state, content)))
--           (do time <- POSIX.getPOSIXTime
--               return (round (time * 100)))
--           1 -- Time check frequency: (accumulator `mod` this_number) == 0.
--           (CacheWithLRUList
--             6     -- Expected size of key-value map when removing elements.
--             6     -- Size of map when to remove items from key-value map.
--             12    -- Size of list when to compact
--             )
--     
--     -- Use lookupECM whenever the contents of "file1" is needed.
--     b <- lookupECM filecache "file1"
--     BS.putStrLn b
--     return ()
--   
--   
module Caching.ExpiringCacheMap.HashECM -- | Create a new expiring cache for retrieving uncached values via -- IO interaction (such as in the case of reading a file from -- disk), with a shared state lock via an MVar to manage cache -- state. -- -- Value request and time check request functions are provided as -- arguments. -- -- The time check frequency value has to be 1 or higher, with higher -- values postponing time checks for longer periods of time. -- -- A cache setting specifies how the cache should remove entries when the -- cache becomes a certain size. The only constructor for this is -- CacheWithLRUList. newECMIO :: (Eq k, Hashable k) => (Maybe s -> k -> IO (TimeUnits, (Maybe s, v))) -> (IO TimeUnits) -> ECMIncr -> CacheSettings -> IO (ECM IO MVar s HashMap k v) -- | Create a new expiring cache along arbitrary monads with provided -- functions to create cache state in Monad m2, and modify and -- read cache state in Monad m1. -- -- newECMIO is just a wrapper to this function with MVar -- functions: -- --
--   newECMIO retr gettime timecheckmodulo cachesettings =
--     newECMForM retr gettime timecheckmodulo cachesettings
--       newMVar modifyMVar readMVar
--   
-- -- Value request and time check request functions are provided as -- arguments. -- -- The time check frequency value has to be 1 or higher, with higher -- values postponing time checks for longer periods of time. -- -- A cache setting specifies how the cache should remove entries when the -- cache becomes a certain size. The only constructor for this is -- CacheWithLRUList. newECMForM :: (Monad m1, Monad m2) => (Eq k, Hashable k) => (Maybe s -> k -> m1 (TimeUnits, (Maybe s, v))) -> (m1 TimeUnits) -> ECMIncr -> CacheSettings -> ECMNewState m2 mv s HashMap k v -> ECMEnterState m1 mv s HashMap k v -> ECMReadState m1 mv s HashMap k v -> m2 (ECM m1 mv s HashMap k v) -- | Used with newECMIO or newECMForM to provide a consistent -- duration for requested values. consistentDuration :: (Monad m, Eq k, Hashable k) => TimeUnits -> (Maybe s -> k -> m (Maybe s, v)) -> (Maybe s -> k -> m (TimeUnits, (Maybe s, v))) -- | Request a value associated with a key from the cache. -- -- -- -- Every lookupECM computation increments an accumulator in the -- cache state which is used to keep track of the succession of key -- accesses. Based on the parameters provided with the -- CacheWithLRUList constructor, this history of key accesses is -- then used to remove entries from the cache back down to a minimum -- size. Also, when the modulo of the accumulator and the modulo value -- computes to 0, the time request function is invoked. In some cases the -- accumulator may get incremented more than once in a lookupECM -- computation. -- -- As the accumulator is a bound unsigned integer, when the accumulator -- increments back to 0, the cache state is completely cleared. -- -- The time request function is invoked in one of two different -- conditions -- -- -- -- When the current time is determined during a lookup, access times of -- the entries in the key-value cache are compared with the new time to -- filter out expired entries from the key-value map. lookupECM :: (Monad m, Eq k, Hashable k) => ECM m mv s HashMap k v -> k -> m v getValReqState :: (Monad m, Eq k, Hashable k) => ECM m mv s HashMap k v -> k -> m (Maybe s) -- | The type that encapsulates a cache map. data ECM a b s m k v data CacheSettings -- | A cache that maintains a key access history list to perform removals -- of least recently used entries. Once the key-value map reaches -- removalsize keys, then a list of keys to keep in the map is -- determined which is no larger than mapsize size. Entries are -- removed only on insertion of a new entry in the key-value map. -- -- Key access history entries are prepended to the head of the LRU list, -- if an existing entry for the key appears close to the head of the list -- it is moved to the head of the list, instead of growing the list. When -- the LRU list reaches compactlistsize items, it is compacted by -- removing duplicate keys, by keeping only the most recent accumulator -- value for that key. CacheWithLRUList :: ECMMapSize -> ECMMapSize -> ECMULength -> CacheSettings mapsize :: CacheSettings -> ECMMapSize removalsize :: CacheSettings -> ECMMapSize compactlistsize :: CacheSettings -> ECMULength -- | A cache that holds values for a length of time that uses Ord -- keys with Data.Map.Strict. -- -- An example of creating a cache for accessing files: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Caching.ExpiringCacheMap.OrdECM (newECMIO, lookupECM, CacheSettings(..), consistentDuration)
--   
--   import qualified Data.Time.Clock.POSIX as POSIX (POSIXTime, getPOSIXTime)
--   import qualified Data.ByteString.Char8 as BS
--   import System.IO (withFile, IOMode(ReadMode))
--   
--   example = do
--     filecache <- newECMIO
--           (consistentDuration 100 -- Duration between access and expiry time of each item
--             (\state id -> do BS.putStrLn "Reading a file again..."
--                              withFile (case id :: BS.ByteString of
--                                          "file1" -> "file1.txt"
--                                          "file2" -> "file2.txt")
--                                 ReadMode $
--                                 \fh -> do content <- BS.hGetContents fh
--                                           return $! (state, content)))
--           (do time <- POSIX.getPOSIXTime
--               return (round (time * 100)))
--           1 -- Time check frequency: (accumulator `mod` this_number) == 0.
--           (CacheWithLRUList
--             6     -- Expected size of key-value map when removing elements.
--             6     -- Size of map when to remove items from key-value map.
--             12    -- Size of list when to compact
--             )
--     
--     -- Use lookupECM whenever the contents of "file1" is needed.
--     b <- lookupECM filecache "file1"
--     BS.putStrLn b
--     return ()
--   
--   
module Caching.ExpiringCacheMap.OrdECM -- | Create a new expiring cache for retrieving uncached values via -- IO interaction (such as in the case of reading a file from -- disk), with a shared state lock via an MVar to manage cache -- state. -- -- Value request and time check request functions are provided as -- arguments. -- -- The time check frequency value has to be 1 or higher, with higher -- values postponing time checks for longer periods of time. -- -- A cache setting specifies how the cache should remove entries when the -- cache becomes a certain size. The only constructor for this is -- CacheWithLRUList. newECMIO :: Ord k => (Maybe s -> k -> IO (TimeUnits, (Maybe s, v))) -> (IO TimeUnits) -> ECMIncr -> CacheSettings -> IO (ECM IO MVar s Map k v) -- | Create a new expiring cache along arbitrary monads with provided -- functions to create cache state in Monad m2, and modify and -- read cache state in Monad m1. -- -- newECMIO is just a wrapper to this function with MVar -- functions: -- --
--   newECMIO retr gettime timecheckmodulo cachesettings =
--     newECMForM retr gettime timecheckmodulo cachesettings
--       newMVar modifyMVar readMVar
--   
-- -- Value request and time check request functions are provided as -- arguments. -- -- The time check frequency value has to be 1 or higher, with higher -- values postponing time checks for longer periods of time. -- -- A cache setting specifies how the cache should remove entries when the -- cache becomes a certain size. The only constructor for this is -- CacheWithLRUList. newECMForM :: (Monad m1, Monad m2) => Ord k => (Maybe s -> k -> m1 (TimeUnits, (Maybe s, v))) -> (m1 TimeUnits) -> ECMIncr -> CacheSettings -> ECMNewState m2 mv s Map k v -> ECMEnterState m1 mv s Map k v -> ECMReadState m1 mv s Map k v -> m2 (ECM m1 mv s Map k v) -- | Used with newECMIO or newECMForM to provide a consistent -- duration for requested values. consistentDuration :: (Monad m, Ord k) => TimeUnits -> (Maybe s -> k -> m (Maybe s, v)) -> (Maybe s -> k -> m (TimeUnits, (Maybe s, v))) -- | Request a value associated with a key from the cache. -- -- -- -- Every lookupECM computation increments an accumulator in the -- cache state which is used to keep track of the succession of key -- accesses. Based on the parameters provided with the -- CacheWithLRUList constructor, this history of key accesses is -- then used to remove entries from the cache back down to a minimum -- size. Also, when the modulo of the accumulator and the modulo value -- computes to 0, the time request function is invoked. In some cases the -- accumulator may get incremented more than once in a lookupECM -- computation. -- -- As the accumulator is a bound unsigned integer, when the accumulator -- increments back to 0, the cache state is completely cleared. -- -- The time request function is invoked in one of two different -- conditions -- -- -- -- When the current time is determined during a lookup, access times of -- the entries in the key-value cache are compared with the new time to -- filter out expired entries from the key-value map. lookupECM :: (Monad m, Ord k) => ECM m mv s Map k v -> k -> m v getValReqState :: (Monad m, Ord k) => ECM m mv s Map k v -> k -> m (Maybe s) -- | The type that encapsulates a cache map. data ECM a b s m k v data CacheSettings -- | A cache that maintains a key access history list to perform removals -- of least recently used entries. Once the key-value map reaches -- removalsize keys, then a list of keys to keep in the map is -- determined which is no larger than mapsize size. Entries are -- removed only on insertion of a new entry in the key-value map. -- -- Key access history entries are prepended to the head of the LRU list, -- if an existing entry for the key appears close to the head of the list -- it is moved to the head of the list, instead of growing the list. When -- the LRU list reaches compactlistsize items, it is compacted by -- removing duplicate keys, by keeping only the most recent accumulator -- value for that key. CacheWithLRUList :: ECMMapSize -> ECMMapSize -> ECMULength -> CacheSettings mapsize :: CacheSettings -> ECMMapSize removalsize :: CacheSettings -> ECMMapSize compactlistsize :: CacheSettings -> ECMULength