{-# LANGUAGE BangPatterns #-} module Network.HPACK.Table.RevIndex where import Data.Map.Strict (Map) import qualified Data.Map.Strict as M import Network.HPACK.Types import Network.HPACK.Table.Static -- Physical array index for Dynamic Table. -- Defining here due to dependency, sigh. newtype DIndex = DIndex Int deriving (Eq, Ord, Show) data Inner = Inner [(HeaderValue, SIndex)] [(HeaderValue, DIndex)] deriving Show newtype Outer = Outer (Map HeaderName Inner) deriving Show defaultRevIndex :: Outer defaultRevIndex = Outer $! foldr op M.empty lst where lst = zip staticTableList $ map SIndex [1..] op ((k,v),i) m = M.alter f k m where f Nothing = Just $! Inner [(v,i)] [] f (Just (Inner ss ds)) = let ss' = (v,i):ss in Just $! Inner ss' ds insertDynamic :: Header -> DIndex -> Outer -> Outer insertDynamic (k,v) didx (Outer rev) = Outer $! M.alter f k rev where f Nothing = Just $! Inner [] [(v,didx)] f (Just (Inner ss ds)) = let ds' = (v,didx):ds in Just $! Inner ss ds' deleteDynamic :: Header -> Map HeaderName Inner -> Map HeaderName Inner deleteDynamic (k,v) rev = M.alter f k rev where f Nothing = Nothing f (Just (Inner ss ds)) = case filter (\(a,_) -> a /= v) ds of [] -> case ss of [] -> Nothing _ -> Just $! Inner ss [] ds' -> Just $! Inner ss ds' deleteDynamicList :: [Header] -> Outer -> Outer deleteDynamicList hs (Outer rev) = Outer $! foldr deleteDynamic rev hs