Haskell bounded LRU cache over Data.Map
Haskell
import Data.IORef (IORef, atomicModifyIORef', newIORef)
import Data.List (minimumBy)
import Data.Ord (comparing)
import qualified Data.Map.Strict as M
type LRU k v = (Int, M.Map k (Int, v))
newLRU :: IO (IORef (LRU k v))
newLRU = newIORef (0, M.empty)
lruGet :: Ord k => k -> IORef (LRU k v) -> IO (Maybe v)
lruGet k ref = atomicModifyIORef' ref $ \(tick, m) -> case M.lookup k m of
Nothing -> ((tick, m), Nothing)
Just (_, v) -> ((tick + 1, M.insert k (tick + 1, v) m), Just v)
lruPut :: Ord k => Int -> k -> v -> IORef (LRU k v) -> IO ()
lruPut cap k v ref = atomicModifyIORef' ref $ \(tick, m) ->
let m' = M.insert k (tick + 1, v) m
keep | M.size m' <= cap = m'
| otherwise = M.delete (fst (minimumBy (comparing snd) (M.toList m'))) m'
in ((tick + 1, keep), ())