uni-util-2.2.0.0: Util/Cache.hs
-- | The Cache module allows us to cache results of expensive stateful
-- computations in memory.
-- Possible improvements -
-- (1) use hashing instead
module Util.Cache(
Cache, -- a cache (a stateful object). Takes parameters key and elt.
-- key must be an instance of Ord.
newCache, -- :: Ord key => (key -> IO elt) -> IO(Cache key elt)
getCached -- :: Ord key => Cache key elt -> key -> IO elt
) where
import qualified Data.Map as Map
import Control.Concurrent
data Ord key =>
Cache key elt = Cache (MVar(Map.Map key (MVar elt))) (key -> IO elt)
newCache :: Ord key => (key -> IO elt) -> IO(Cache key elt)
newCache getAct =
do
cacheMVar <- newMVar Map.empty
return (Cache cacheMVar getAct)
{- We do this in two stages so as not to hold up the whole
cache at once. -}
getCached :: Ord key => Cache key elt -> key -> IO elt
getCached (Cache cacheMVar getAct) key =
do
cacheMap <- takeMVar cacheMVar
case Map.lookup key cacheMap of
Just mVar ->
do
putMVar cacheMVar cacheMap
readMVar mVar
Nothing ->
do
mVar <- newEmptyMVar
putMVar cacheMVar (Map.insert key mVar cacheMap)
value <- getAct key
putMVar mVar value
return value