{-# LANGUAGE RecordWildCards #-}

module Network.HTTP2.Arch.Cache where

import Data.OrdPSQ (OrdPSQ)
import qualified Data.OrdPSQ as PSQ

type Priority = Int

data Cache k v = Cache {
    forall k v. Cache k v -> Int
cLimit :: Int
  , forall k v. Cache k v -> Int
cSize  :: Int
  , forall k v. Cache k v -> Int
cTick  :: Priority
  , forall k v. Cache k v -> OrdPSQ k Int v
cQueue :: OrdPSQ k Priority v
  }

emptyCache :: Int -> Cache k v
emptyCache :: forall k v. Int -> Cache k v
emptyCache Int
lim = forall k v. Int -> Int -> Int -> OrdPSQ k Int v -> Cache k v
Cache Int
lim Int
0 Int
0 forall k p v. OrdPSQ k p v
PSQ.empty

insert :: Ord k => k -> v -> Cache k v -> Cache k v
insert :: forall k v. Ord k => k -> v -> Cache k v -> Cache k v
insert k
k v
v c :: Cache k v
c@Cache{Int
OrdPSQ k Int v
cQueue :: OrdPSQ k Int v
cTick :: Int
cSize :: Int
cLimit :: Int
cQueue :: forall k v. Cache k v -> OrdPSQ k Int v
cTick :: forall k v. Cache k v -> Int
cSize :: forall k v. Cache k v -> Int
cLimit :: forall k v. Cache k v -> Int
..}
  | Int
cSize forall a. Eq a => a -> a -> Bool
== Int
cLimit = let q :: OrdPSQ k Int v
q = forall k p v.
(Ord k, Ord p) =>
k -> p -> v -> OrdPSQ k p v -> OrdPSQ k p v
PSQ.insert k
k Int
cTick v
v forall a b. (a -> b) -> a -> b
$ forall k p v. (Ord k, Ord p) => OrdPSQ k p v -> OrdPSQ k p v
PSQ.deleteMin OrdPSQ k Int v
cQueue
                      in Cache k v
c { cTick :: Int
cTick = Int
cTick forall a. Num a => a -> a -> a
+ Int
1, cQueue :: OrdPSQ k Int v
cQueue = OrdPSQ k Int v
q }
  | Bool
otherwise       = let q :: OrdPSQ k Int v
q = forall k p v.
(Ord k, Ord p) =>
k -> p -> v -> OrdPSQ k p v -> OrdPSQ k p v
PSQ.insert k
k Int
cTick v
v OrdPSQ k Int v
cQueue
                      in Cache k v
c { cTick :: Int
cTick = Int
cTick forall a. Num a => a -> a -> a
+ Int
1, cQueue :: OrdPSQ k Int v
cQueue = OrdPSQ k Int v
q, cSize :: Int
cSize = Int
cSize forall a. Num a => a -> a -> a
+ Int
1 }

lookup :: Ord k => k -> Cache k v -> Maybe v
lookup :: forall k v. Ord k => k -> Cache k v -> Maybe v
lookup k
k Cache{Int
OrdPSQ k Int v
cQueue :: OrdPSQ k Int v
cTick :: Int
cSize :: Int
cLimit :: Int
cQueue :: forall k v. Cache k v -> OrdPSQ k Int v
cTick :: forall k v. Cache k v -> Int
cSize :: forall k v. Cache k v -> Int
cLimit :: forall k v. Cache k v -> Int
..} = forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall k p v. Ord k => k -> OrdPSQ k p v -> Maybe (p, v)
PSQ.lookup k
k OrdPSQ k Int v
cQueue