-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | General purpose simple caching.
--   
--   A simple general purpose shared state cache map with automatic
--   expiration of values, for caching the results of accessing a resource
--   such as reading a file. With variations for Ord and Hashable keys
--   using <a>Data.Map.Strict</a> and <a>Data.HashMap.Strict</a>,
--   respectively.
@package expiring-cache-map
@version 0.0.6.1


-- | TestSequence monad for testing caching behaviour.
--   
--   <pre>
--   {-# 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) &lt;- TestSeq.runTestSequence test'
--     (putStrLn . show . reverse) events
--     return ()
--     where
--       test' = do
--         filecache &lt;- newECMForM
--               (consistentDuration 100 -- Duration between access and expiry time of each item, no state needed.
--                 (\state _id -&gt; do number &lt;- TestSeq.readNumber
--                                   return (state, number)))
--               (TestSeq.getCurrentTime &gt;&gt;= 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 &lt;- lookupECM filecache ("file1" :: BS.ByteString)
--         TestSeq.haveNumber b
--         b &lt;- lookupECM filecache "file1"
--         b &lt;- lookupECM filecache "file2"
--         TestSeq.haveNumber b
--         return b
--   </pre>
--   
--   Evaluating the <tt>test</tt> function results in a list of events.
--   
--   <pre>
--   &gt;&gt;&gt; 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]
--   </pre>
--   
--   In this example the history shows 2 time accesses (<tt>GetTime 7</tt>
--   and <tt>GetTime 23</tt>) 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
--   <tt>"file2"</tt>.
--   
--   Changing the time frequency to 1 will alter the list of events with
--   more frequent time checks:
--   
--   <pre>
--   &gt;&gt;&gt; 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]
--   </pre>
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 GHC.Classes.Eq Caching.ExpiringCacheMap.Utils.TestSequence.TestSequenceEvents
instance GHC.Show.Show Caching.ExpiringCacheMap.Utils.TestSequence.TestSequenceEvents
instance GHC.Show.Show (Caching.ExpiringCacheMap.Utils.TestSequence.TestSequenceState ct)
instance GHC.Base.Functor (Caching.ExpiringCacheMap.Utils.TestSequence.TestSequence a)
instance GHC.Base.Applicative (Caching.ExpiringCacheMap.Utils.TestSequence.TestSequence a)
instance GHC.Base.Monad (Caching.ExpiringCacheMap.Utils.TestSequence.TestSequence a)


-- | 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 (<a>Word32</a>) 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 <a>Caching.ExpiringCacheMap.OrdECM</a> and
--   <a>Caching.ExpiringCacheMap.HashECM</a>.
module Caching.ExpiringCacheMap.Types
data CacheSettings

-- | A cache that maintains a key access history list to perform removals
--   of <i>least recently used</i> entries. Once the key-value map reaches
--   <a>removalsize</a> keys, then a list of keys to keep in the map is
--   determined which is no larger than <a>mapsize</a> 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 <a>compactlistsize</a> 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 (<a>Word32</a>) 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
detNotExpired :: TimeUnits -> [(k, (TimeUnits, TimeUnits, v))] -> [k]


-- | A cache that holds values for a length of time that uses
--   <a>Hashable</a> keys with <a>Data.HashMap.Strict</a>.
--   
--   An example of creating a cache for accessing files:
--   
--   <pre>
--   {-# 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 &lt;- newECMIO
--           (consistentDuration 100 -- Duration between access and expiry time of each item
--             (\state id -&gt; do BS.putStrLn "Reading a file again..."
--                              withFile (case id :: BS.ByteString of
--                                          "file1" -&gt; "file1.txt"
--                                          "file2" -&gt; "file2.txt")
--                                 ReadMode $
--                                 \fh -&gt; do content &lt;- BS.hGetContents fh
--                                           return $! (state, content)))
--           (do time &lt;- 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 &lt;- lookupECM filecache "file1"
--     BS.putStrLn b
--     return ()
--   </pre>
module Caching.ExpiringCacheMap.HashECM

-- | Create a new expiring cache for retrieving uncached values via
--   <a>IO</a> interaction (such as in the case of reading a file from
--   disk), with a shared state lock via an <a>MVar</a> 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
--   <a>CacheWithLRUList</a>.
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 <a>Monad</a> m2, and modify and
--   read cache state in <a>Monad</a> m1.
--   
--   <a>newECMIO</a> is just a wrapper to this function with <a>MVar</a>
--   functions:
--   
--   <pre>
--   newECMIO retr gettime timecheckmodulo cachesettings =
--     newECMForM retr gettime timecheckmodulo cachesettings
--       <a>newMVar</a> <a>modifyMVar</a> <a>readMVar</a>
--   </pre>
--   
--   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
--   <a>CacheWithLRUList</a>.
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 <a>newECMIO</a> or <a>newECMForM</a> 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.
--   
--   <ul>
--   <li>If the value is not in the cache, the value will be requested
--   through the function defined when the <a>ECM</a> value was created,
--   its computation returned and the value stored in the cache state
--   map.</li>
--   <li>If the value is in the cache and has not expired, it will be
--   returned.</li>
--   <li>If the value is in the cache and a new time is computed in the
--   same lookup, and the value has been determined to have since expired,
--   it will be discarded and a new value will be requested for this
--   computation.</li>
--   </ul>
--   
--   Every <a>lookupECM</a> 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
--   <a>CacheWithLRUList</a> 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 <a>lookupECM</a>
--   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
--   
--   <ul>
--   <li>When a new key-value entry is requested, the current time is also
--   requested during the same lookup, as a recent time determination is
--   needed for a new entry in the key-value cache.</li>
--   <li>When the modulo of the accumulator and a specified value equals to
--   0.</li>
--   </ul>
--   
--   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)

-- | Invalidates a key from the cache and returns its value if any. Note
--   that this is a sequential composition of a read and modify of the
--   mutable cache container (e.g. <a>readMVar</a> followed by
--   <a>modifyMVar</a> with <a>newECMIO</a> instances).
invalidate :: (Monad m, Eq k, Hashable k) => ECM m mv s HashMap k v -> k -> m (Maybe v)

-- | Invalidates the entire cache and returns the last key and value if
--   any. Note that this is a sequential composition of a read and modify
--   of the mutable cache container (e.g. <a>readMVar</a> followed by
--   <a>modifyMVar</a> with <a>newECMIO</a> instances).
invalidateCache :: (Monad m, Eq k, Hashable k) => ECM m mv s HashMap k v -> m (Maybe (k, v))

-- | List of keys in the cache map without performing a time check,
--   returning both stored keys that are expired and keys that are not
--   expired. keys are in an unspecified order.
keysCached :: (Monad m, Eq k, Hashable k) => ECM m mv s HashMap k v -> m [k]

-- | List of keys in the cache map that are not expired values. A time
--   check is always performed to compare with the elapsed time left with
--   each key. The cache state is not modified and the time check is not
--   performed from within a modifying state context, e.g. not within
--   <a>modifyMVar</a> with a <a>newECMIO</a> instance. Keys are in an
--   unspecified order.
keysNotExpired :: (Monad m, Eq k, Hashable k) => ECM m mv s HashMap k v -> m [k]

-- | 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 <i>least recently used</i> entries. Once the key-value map reaches
--   <a>removalsize</a> keys, then a list of keys to keep in the map is
--   determined which is no larger than <a>mapsize</a> 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 <a>compactlistsize</a> 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 <a>Ord</a>
--   keys with <a>Data.Map.Strict</a>.
--   
--   An example of creating a cache for accessing files:
--   
--   <pre>
--   {-# 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 &lt;- newECMIO
--           (consistentDuration 100 -- Duration between access and expiry time of each item
--             (\state id -&gt; do BS.putStrLn "Reading a file again..."
--                              withFile (case id :: BS.ByteString of
--                                          "file1" -&gt; "file1.txt"
--                                          "file2" -&gt; "file2.txt")
--                                 ReadMode $
--                                 \fh -&gt; do content &lt;- BS.hGetContents fh
--                                           return $! (state, content)))
--           (do time &lt;- 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 &lt;- lookupECM filecache "file1"
--     BS.putStrLn b
--     return ()
--   </pre>
module Caching.ExpiringCacheMap.OrdECM

-- | Create a new expiring cache for retrieving uncached values via
--   <a>IO</a> interaction (such as in the case of reading a file from
--   disk), with a shared state lock via an <a>MVar</a> 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
--   <a>CacheWithLRUList</a>.
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 <a>Monad</a> m2, and modify and
--   read cache state in <a>Monad</a> m1.
--   
--   <a>newECMIO</a> is just a wrapper to this function with <a>MVar</a>
--   functions:
--   
--   <pre>
--   newECMIO retr gettime timecheckmodulo cachesettings =
--     newECMForM retr gettime timecheckmodulo cachesettings
--       <a>newMVar</a> <a>modifyMVar</a> <a>readMVar</a>
--   </pre>
--   
--   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
--   <a>CacheWithLRUList</a>.
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 <a>newECMIO</a> or <a>newECMForM</a> 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.
--   
--   <ul>
--   <li>If the value is not in the cache, it will be requested through the
--   function defined through <tt>newECM</tt>, its computation returned and
--   the value stored in the cache state map.</li>
--   <li>If the value is in the cache and has not expired, it will be
--   returned.</li>
--   <li>If the value is in the cache and a new time is computed in the
--   same lookup, and the value has been determined to have since expired,
--   it will be discarded and a new value will be requested for this
--   computation.</li>
--   </ul>
--   
--   Every <a>lookupECM</a> 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
--   <a>CacheWithLRUList</a> 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 <a>lookupECM</a>
--   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
--   
--   <ul>
--   <li>When a new key-value entry is requested, the current time is also
--   requested during the same lookup, as a recent time determination is
--   needed for a new entry in the key-value cache.</li>
--   <li>When the modulo of the accumulator and a specified value equals to
--   0.</li>
--   </ul>
--   
--   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)

-- | Invalidates a key from the cache and returns its value if any. Note
--   that this is a sequential composition of a read and modify of the
--   mutable cache container (e.g. <a>readMVar</a> followed by
--   <a>modifyMVar</a> with <a>newECMIO</a> instances).
invalidate :: (Monad m, Ord k) => ECM m mv s Map k v -> k -> m (Maybe v)

-- | Invalidates the entire cache and returns the last key and value if
--   any. Note that this is a sequential composition of a read and modify
--   of the mutable cache container (e.g. <a>readMVar</a> followed by
--   <a>modifyMVar</a> with <a>newECMIO</a> instances).
invalidateCache :: (Monad m, Ord k) => ECM m mv s Map k v -> m (Maybe (k, v))

-- | List of keys in the cache map without performing a time check,
--   returning both stored keys that are expired and keys that are not
--   expired. keys are in an unspecified order.
keysCached :: (Monad m, Ord k) => ECM m mv s Map k v -> m [k]

-- | List of keys in the cache map that are not expired values. A time
--   check is always performed to compare with the elapsed time left with
--   each key. The cache state is not modified and the time check is not
--   performed from within a modifying state context, e.g. not within
--   <a>modifyMVar</a> with a <a>newECMIO</a> instance. Keys are in an
--   unspecified order.
keysNotExpired :: (Monad m, Ord k) => ECM m mv s Map k v -> m [k]

-- | 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 <i>least recently used</i> entries. Once the key-value map reaches
--   <a>removalsize</a> keys, then a list of keys to keep in the map is
--   determined which is no larger than <a>mapsize</a> 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 <a>compactlistsize</a> 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
