{-| Module : Data.LRUCache Copyright : Copyright (jp) 2020-present, murakami License : BSD3 Maintainer : murakami Pure API to an LRU cache. -} module Data.LRUCache ( LRUCache(..) , view , push , empty , clear , size ) where import Data.List ( find , findIndex ) data LRUCache k v = LRUCache { capacity :: Int -- ^ the capacity , cache :: [(k, v)] -- ^ the cache content } deriving (Eq, Show, Read) -- | get a value by key from a LRUCache. view :: (Eq k) => k -> LRUCache k v -> (Maybe v, LRUCache k v) view k (LRUCache n cache) = (fmap snd $ find ((== k) . fst) cache, LRUCache n $ k <|- cache) where (<|-) :: (Eq k) => k -> [(k, v)] -> [(k, v)] k' <|- xs = case findIndex ((== k') . fst) xs of Nothing -> xs Just i -> xs !! i : take i xs <> drop (succ i) xs -- | push a cache iitem in a LRUCache. push :: (k, v) -> LRUCache k v -> LRUCache k v push e (LRUCache n cache) = LRUCache n . take n . (e:) $ cache -- | create an empty LRUCache. empty :: Int -> Maybe (LRUCache k v) empty n | n <= 0 = Nothing | otherwise = Just $ LRUCache n [] -- | clear the LRUCache to empty. clear :: LRUCache k v -> LRUCache k v clear (LRUCache n _) = LRUCache n [] -- | get the LRUCache current cache size. size :: LRUCache k v -> Int size = length . cache