This file is indexed.

/usr/share/doc/libghc-expiring-cache-map-doc/html/expiring-cache-map.txt is in libghc-expiring-cache-map-doc 0.0.6.1-3build3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
-- 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


-- | 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


-- | 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)


-- | 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 t1, Monad m) => ECM m t4 t3 t2 t1 t -> m String
detNotExpired :: TimeUnits -> [(k, (TimeUnits, TimeUnits, v))] -> [k]


-- | 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


-- | 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