{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

module Network.QPACK.Table.RevIndex (
    RevResult(..)
  , RevIndex
  , newRevIndex
  , renewRevIndex
  , lookupRevIndex
  , lookupRevIndex'
  , insertRevIndex
  , deleteRevIndexList
  ) where

import Data.Array (Array)
import qualified Data.Array as A
import Data.Array.Base (unsafeAt)
import Data.Function (on)
import Data.IORef
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M
import Network.HPACK.Internal
import Network.HPACK.Token

import Imports
import Network.QPACK.Table.Static
import Network.QPACK.Token
import Network.QPACK.Types

----------------------------------------------------------------

data RevResult = N | K HIndex | KV HIndex deriving (RevResult -> RevResult -> Bool
(RevResult -> RevResult -> Bool)
-> (RevResult -> RevResult -> Bool) -> Eq RevResult
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RevResult -> RevResult -> Bool
$c/= :: RevResult -> RevResult -> Bool
== :: RevResult -> RevResult -> Bool
$c== :: RevResult -> RevResult -> Bool
Eq, Int -> RevResult -> ShowS
[RevResult] -> ShowS
RevResult -> String
(Int -> RevResult -> ShowS)
-> (RevResult -> String)
-> ([RevResult] -> ShowS)
-> Show RevResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RevResult] -> ShowS
$cshowList :: [RevResult] -> ShowS
show :: RevResult -> String
$cshow :: RevResult -> String
showsPrec :: Int -> RevResult -> ShowS
$cshowsPrec :: Int -> RevResult -> ShowS
Show)

----------------------------------------------------------------

data RevIndex = RevIndex DynamicRevIndex OtherRevIdex

type DynamicRevIndex = Array Int (IORef ValueMap)

data KeyValue = KeyValue HeaderName HeaderValue deriving (KeyValue -> KeyValue -> Bool
(KeyValue -> KeyValue -> Bool)
-> (KeyValue -> KeyValue -> Bool) -> Eq KeyValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KeyValue -> KeyValue -> Bool
$c/= :: KeyValue -> KeyValue -> Bool
== :: KeyValue -> KeyValue -> Bool
$c== :: KeyValue -> KeyValue -> Bool
Eq, Eq KeyValue
Eq KeyValue
-> (KeyValue -> KeyValue -> Ordering)
-> (KeyValue -> KeyValue -> Bool)
-> (KeyValue -> KeyValue -> Bool)
-> (KeyValue -> KeyValue -> Bool)
-> (KeyValue -> KeyValue -> Bool)
-> (KeyValue -> KeyValue -> KeyValue)
-> (KeyValue -> KeyValue -> KeyValue)
-> Ord KeyValue
KeyValue -> KeyValue -> Bool
KeyValue -> KeyValue -> Ordering
KeyValue -> KeyValue -> KeyValue
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: KeyValue -> KeyValue -> KeyValue
$cmin :: KeyValue -> KeyValue -> KeyValue
max :: KeyValue -> KeyValue -> KeyValue
$cmax :: KeyValue -> KeyValue -> KeyValue
>= :: KeyValue -> KeyValue -> Bool
$c>= :: KeyValue -> KeyValue -> Bool
> :: KeyValue -> KeyValue -> Bool
$c> :: KeyValue -> KeyValue -> Bool
<= :: KeyValue -> KeyValue -> Bool
$c<= :: KeyValue -> KeyValue -> Bool
< :: KeyValue -> KeyValue -> Bool
$c< :: KeyValue -> KeyValue -> Bool
compare :: KeyValue -> KeyValue -> Ordering
$ccompare :: KeyValue -> KeyValue -> Ordering
$cp1Ord :: Eq KeyValue
Ord)

-- We always create an index for a pair of an unknown header and its value
-- in Linear{H}.
type OtherRevIdex = IORef (Map KeyValue HIndex)

{-# SPECIALIZE INLINE M.lookup :: KeyValue -> M.Map KeyValue HIndex -> Maybe HIndex #-}
{-# SPECIALIZE INLINE M.delete :: KeyValue -> M.Map KeyValue HIndex -> M.Map KeyValue HIndex #-}
{-# SPECIALIZE INLINE M.insert :: KeyValue -> HIndex -> M.Map KeyValue HIndex -> M.Map KeyValue HIndex #-}

----------------------------------------------------------------

type StaticRevIndex = Array Int StaticEntry

data StaticEntry = StaticEntry HIndex (Maybe ValueMap) deriving Int -> StaticEntry -> ShowS
[StaticEntry] -> ShowS
StaticEntry -> String
(Int -> StaticEntry -> ShowS)
-> (StaticEntry -> String)
-> ([StaticEntry] -> ShowS)
-> Show StaticEntry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StaticEntry] -> ShowS
$cshowList :: [StaticEntry] -> ShowS
show :: StaticEntry -> String
$cshow :: StaticEntry -> String
showsPrec :: Int -> StaticEntry -> ShowS
$cshowsPrec :: Int -> StaticEntry -> ShowS
Show

type ValueMap = Map HeaderValue HIndex

----------------------------------------------------------------

staticRevIndex :: StaticRevIndex
staticRevIndex :: StaticRevIndex
staticRevIndex = (Int, Int) -> [(Int, StaticEntry)] -> StaticRevIndex
forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
A.array (Int
minTokenIx,Int
51) ([(Int, StaticEntry)] -> StaticRevIndex)
-> [(Int, StaticEntry)] -> StaticRevIndex
forall a b. (a -> b) -> a -> b
$ ((ByteString, [(ByteString, HIndex)]) -> (Int, StaticEntry))
-> [(ByteString, [(ByteString, HIndex)])] -> [(Int, StaticEntry)]
forall a b. (a -> b) -> [a] -> [b]
map (ByteString, [(ByteString, HIndex)]) -> (Int, StaticEntry)
toEnt [(ByteString, [(ByteString, HIndex)])]
zs
  where
    toEnt :: (ByteString, [(ByteString, HIndex)]) -> (Int, StaticEntry)
toEnt (ByteString
k, [(ByteString, HIndex)]
xs) = (Int -> Int
quicIx (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Token -> Int
tokenIx (Token -> Int) -> Token -> Int
forall a b. (a -> b) -> a -> b
$ ByteString -> Token
toToken ByteString
k, StaticEntry
m)
      where
        m :: StaticEntry
m = case [(ByteString, HIndex)]
xs of
            []  -> String -> StaticEntry
forall a. HasCallStack => String -> a
error String
"staticRevIndex"
            [("",i)] -> HIndex -> Maybe ValueMap -> StaticEntry
StaticEntry HIndex
i Maybe ValueMap
forall a. Maybe a
Nothing
            (_,i):_  -> HIndex -> Maybe ValueMap -> StaticEntry
StaticEntry HIndex
i (Maybe ValueMap -> StaticEntry) -> Maybe ValueMap -> StaticEntry
forall a b. (a -> b) -> a -> b
$ ValueMap -> Maybe ValueMap
forall a. a -> Maybe a
Just (ValueMap -> Maybe ValueMap) -> ValueMap -> Maybe ValueMap
forall a b. (a -> b) -> a -> b
$ [(ByteString, HIndex)] -> ValueMap
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(ByteString, HIndex)]
xs
    zs :: [(ByteString, [(ByteString, HIndex)])]
zs = ([(ByteString, (ByteString, HIndex))]
 -> (ByteString, [(ByteString, HIndex)]))
-> [[(ByteString, (ByteString, HIndex))]]
-> [(ByteString, [(ByteString, HIndex)])]
forall a b. (a -> b) -> [a] -> [b]
map [(ByteString, (ByteString, HIndex))]
-> (ByteString, [(ByteString, HIndex)])
forall a b. [(a, b)] -> (a, [b])
extract ([[(ByteString, (ByteString, HIndex))]]
 -> [(ByteString, [(ByteString, HIndex)])])
-> [[(ByteString, (ByteString, HIndex))]]
-> [(ByteString, [(ByteString, HIndex)])]
forall a b. (a -> b) -> a -> b
$ ((ByteString, (ByteString, HIndex))
 -> (ByteString, (ByteString, HIndex)) -> Bool)
-> [(ByteString, (ByteString, HIndex))]
-> [[(ByteString, (ByteString, HIndex))]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
(==) (ByteString -> ByteString -> Bool)
-> ((ByteString, (ByteString, HIndex)) -> ByteString)
-> (ByteString, (ByteString, HIndex))
-> (ByteString, (ByteString, HIndex))
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (ByteString, (ByteString, HIndex)) -> ByteString
forall a b. (a, b) -> a
fst) ([(ByteString, (ByteString, HIndex))]
 -> [[(ByteString, (ByteString, HIndex))]])
-> [(ByteString, (ByteString, HIndex))]
-> [[(ByteString, (ByteString, HIndex))]]
forall a b. (a -> b) -> a -> b
$ [(ByteString, (ByteString, HIndex))]
-> [(ByteString, (ByteString, HIndex))]
forall a. Ord a => [a] -> [a]
sort [(ByteString, (ByteString, HIndex))]
lst
      where
        lst :: [(ByteString, (ByteString, HIndex))]
lst = ((ByteString, ByteString)
 -> HIndex -> (ByteString, (ByteString, HIndex)))
-> [(ByteString, ByteString)]
-> [HIndex]
-> [(ByteString, (ByteString, HIndex))]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\(ByteString
k,ByteString
v) HIndex
i -> (ByteString
k,(ByteString
v,HIndex
i))) [(ByteString, ByteString)]
staticTableList ([HIndex] -> [(ByteString, (ByteString, HIndex))])
-> [HIndex] -> [(ByteString, (ByteString, HIndex))]
forall a b. (a -> b) -> a -> b
$ (Int -> HIndex) -> [Int] -> [HIndex]
forall a b. (a -> b) -> [a] -> [b]
map (AbsoluteIndex -> HIndex
SIndex (AbsoluteIndex -> HIndex)
-> (Int -> AbsoluteIndex) -> Int -> HIndex
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> AbsoluteIndex
AbsoluteIndex) [Int
0..]
        extract :: [(a, b)] -> (a, [b])
extract [(a, b)]
xs = ((a, b) -> a
forall a b. (a, b) -> a
fst ([(a, b)] -> (a, b)
forall a. [a] -> a
head [(a, b)]
xs), ((a, b) -> b) -> [(a, b)] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map (a, b) -> b
forall a b. (a, b) -> b
snd [(a, b)]
xs)

{-# INLINE lookupStaticRevIndex #-}
lookupStaticRevIndex :: Int -> HeaderValue -> RevResult
lookupStaticRevIndex :: Int -> ByteString -> RevResult
lookupStaticRevIndex Int
ix ByteString
v = case StaticRevIndex
staticRevIndex StaticRevIndex -> Int -> StaticEntry
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
`unsafeAt` Int
ix of
    StaticEntry HIndex
i Maybe ValueMap
Nothing  -> HIndex -> RevResult
K HIndex
i
    StaticEntry HIndex
i (Just ValueMap
m) -> case ByteString -> ValueMap -> Maybe HIndex
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup ByteString
v ValueMap
m of
            Maybe HIndex
Nothing -> HIndex -> RevResult
K HIndex
i
            Just HIndex
j  -> HIndex -> RevResult
KV HIndex
j

----------------------------------------------------------------

newDynamicRevIndex :: IO DynamicRevIndex
newDynamicRevIndex :: IO DynamicRevIndex
newDynamicRevIndex = (Int, Int) -> [IORef ValueMap] -> DynamicRevIndex
forall i e. Ix i => (i, i) -> [e] -> Array i e
A.listArray (Int
minTokenIx,Int
maxStaticTokenIx) ([IORef ValueMap] -> DynamicRevIndex)
-> IO [IORef ValueMap] -> IO DynamicRevIndex
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> IO (IORef ValueMap)) -> [Int] -> IO [IORef ValueMap]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Int -> IO (IORef ValueMap)
forall p k a. p -> IO (IORef (Map k a))
mk [Int]
lst
  where
    mk :: p -> IO (IORef (Map k a))
mk p
_ = Map k a -> IO (IORef (Map k a))
forall a. a -> IO (IORef a)
newIORef Map k a
forall k a. Map k a
M.empty
    lst :: [Int]
lst = [Int
minTokenIx..Int
maxStaticTokenIx]

renewDynamicRevIndex :: DynamicRevIndex -> IO ()
renewDynamicRevIndex :: DynamicRevIndex -> IO ()
renewDynamicRevIndex DynamicRevIndex
drev = (Int -> IO ()) -> [Int] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Int -> IO ()
clear [Int
minTokenIx..Int
maxStaticTokenIx]
  where
    clear :: Int -> IO ()
clear Int
t = IORef ValueMap -> ValueMap -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (DynamicRevIndex
drev DynamicRevIndex -> Int -> IORef ValueMap
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
`unsafeAt` Int
t) ValueMap
forall k a. Map k a
M.empty

{-# INLINE lookupDynamicStaticRevIndex #-}
lookupDynamicStaticRevIndex :: Int -> HeaderValue -> DynamicRevIndex -> IO RevResult
lookupDynamicStaticRevIndex :: Int -> ByteString -> DynamicRevIndex -> IO RevResult
lookupDynamicStaticRevIndex Int
ix ByteString
v DynamicRevIndex
drev = do
    let ref :: IORef ValueMap
ref = DynamicRevIndex
drev DynamicRevIndex -> Int -> IORef ValueMap
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
`unsafeAt` Int
ix
    ValueMap
m <- IORef ValueMap -> IO ValueMap
forall a. IORef a -> IO a
readIORef IORef ValueMap
ref
    case ByteString -> ValueMap -> Maybe HIndex
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup ByteString
v ValueMap
m of
        Just HIndex
i  -> RevResult -> IO RevResult
forall (m :: * -> *) a. Monad m => a -> m a
return (RevResult -> IO RevResult) -> RevResult -> IO RevResult
forall a b. (a -> b) -> a -> b
$ HIndex -> RevResult
KV HIndex
i
        Maybe HIndex
Nothing -> RevResult -> IO RevResult
forall (m :: * -> *) a. Monad m => a -> m a
return (RevResult -> IO RevResult) -> RevResult -> IO RevResult
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> RevResult
lookupStaticRevIndex Int
ix ByteString
v

{-# INLINE insertDynamicRevIndex #-}
insertDynamicRevIndex :: Token -> HeaderValue -> HIndex -> DynamicRevIndex -> IO ()
insertDynamicRevIndex :: Token -> ByteString -> HIndex -> DynamicRevIndex -> IO ()
insertDynamicRevIndex Token
t ByteString
v HIndex
i DynamicRevIndex
drev = IORef ValueMap -> (ValueMap -> ValueMap) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef ValueMap
ref ((ValueMap -> ValueMap) -> IO ())
-> (ValueMap -> ValueMap) -> IO ()
forall a b. (a -> b) -> a -> b
$ ByteString -> HIndex -> ValueMap -> ValueMap
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert ByteString
v HIndex
i
  where
    ref :: IORef ValueMap
ref = DynamicRevIndex
drev DynamicRevIndex -> Int -> IORef ValueMap
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
`unsafeAt` Token -> Int
tokenIx Token
t

{-# INLINE deleteDynamicRevIndex #-}
deleteDynamicRevIndex :: Token -> HeaderValue -> DynamicRevIndex -> IO ()
deleteDynamicRevIndex :: Token -> ByteString -> DynamicRevIndex -> IO ()
deleteDynamicRevIndex Token
t ByteString
v DynamicRevIndex
drev = IORef ValueMap -> (ValueMap -> ValueMap) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef ValueMap
ref ((ValueMap -> ValueMap) -> IO ())
-> (ValueMap -> ValueMap) -> IO ()
forall a b. (a -> b) -> a -> b
$ ByteString -> ValueMap -> ValueMap
forall k a. Ord k => k -> Map k a -> Map k a
M.delete ByteString
v
  where
    ref :: IORef ValueMap
ref = DynamicRevIndex
drev DynamicRevIndex -> Int -> IORef ValueMap
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
`unsafeAt` Token -> Int
tokenIx Token
t

----------------------------------------------------------------

newOtherRevIndex :: IO OtherRevIdex
newOtherRevIndex :: IO OtherRevIdex
newOtherRevIndex = Map KeyValue HIndex -> IO OtherRevIdex
forall a. a -> IO (IORef a)
newIORef Map KeyValue HIndex
forall k a. Map k a
M.empty

renewOtherRevIndex :: OtherRevIdex -> IO ()
renewOtherRevIndex :: OtherRevIdex -> IO ()
renewOtherRevIndex OtherRevIdex
ref = OtherRevIdex -> Map KeyValue HIndex -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef OtherRevIdex
ref Map KeyValue HIndex
forall k a. Map k a
M.empty

{-# INLINE lookupOtherRevIndex #-}
lookupOtherRevIndex :: Header -> OtherRevIdex -> IO RevResult
lookupOtherRevIndex :: (ByteString, ByteString) -> OtherRevIdex -> IO RevResult
lookupOtherRevIndex (ByteString
k,ByteString
v) OtherRevIdex
ref = do
      Map KeyValue HIndex
oth <- OtherRevIdex -> IO (Map KeyValue HIndex)
forall a. IORef a -> IO a
readIORef OtherRevIdex
ref
      case KeyValue -> Map KeyValue HIndex -> Maybe HIndex
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup (ByteString -> ByteString -> KeyValue
KeyValue ByteString
k ByteString
v) Map KeyValue HIndex
oth of
        Maybe HIndex
Nothing -> RevResult -> IO RevResult
forall (m :: * -> *) a. Monad m => a -> m a
return RevResult
N
        Just  HIndex
i -> RevResult -> IO RevResult
forall (m :: * -> *) a. Monad m => a -> m a
return (RevResult -> IO RevResult) -> RevResult -> IO RevResult
forall a b. (a -> b) -> a -> b
$ HIndex -> RevResult
KV HIndex
i

{-# INLINE insertOtherRevIndex #-}
insertOtherRevIndex :: Token -> HeaderValue -> HIndex -> OtherRevIdex -> IO ()
insertOtherRevIndex :: Token -> ByteString -> HIndex -> OtherRevIdex -> IO ()
insertOtherRevIndex Token
t ByteString
v HIndex
i OtherRevIdex
ref = OtherRevIdex
-> (Map KeyValue HIndex -> Map KeyValue HIndex) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' OtherRevIdex
ref ((Map KeyValue HIndex -> Map KeyValue HIndex) -> IO ())
-> (Map KeyValue HIndex -> Map KeyValue HIndex) -> IO ()
forall a b. (a -> b) -> a -> b
$ KeyValue -> HIndex -> Map KeyValue HIndex -> Map KeyValue HIndex
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (ByteString -> ByteString -> KeyValue
KeyValue ByteString
k ByteString
v) HIndex
i
  where
    k :: ByteString
k = Token -> ByteString
tokenFoldedKey Token
t

{-# INLINE deleteOtherRevIndex #-}
deleteOtherRevIndex :: Token -> HeaderValue -> OtherRevIdex -> IO ()
deleteOtherRevIndex :: Token -> ByteString -> OtherRevIdex -> IO ()
deleteOtherRevIndex Token
t ByteString
v OtherRevIdex
ref = OtherRevIdex
-> (Map KeyValue HIndex -> Map KeyValue HIndex) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' OtherRevIdex
ref ((Map KeyValue HIndex -> Map KeyValue HIndex) -> IO ())
-> (Map KeyValue HIndex -> Map KeyValue HIndex) -> IO ()
forall a b. (a -> b) -> a -> b
$ KeyValue -> Map KeyValue HIndex -> Map KeyValue HIndex
forall k a. Ord k => k -> Map k a -> Map k a
M.delete (ByteString -> ByteString -> KeyValue
KeyValue ByteString
k ByteString
v)
  where
    k :: ByteString
k = Token -> ByteString
tokenFoldedKey Token
t

----------------------------------------------------------------

newRevIndex :: IO RevIndex
newRevIndex :: IO RevIndex
newRevIndex = DynamicRevIndex -> OtherRevIdex -> RevIndex
RevIndex (DynamicRevIndex -> OtherRevIdex -> RevIndex)
-> IO DynamicRevIndex -> IO (OtherRevIdex -> RevIndex)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO DynamicRevIndex
newDynamicRevIndex IO (OtherRevIdex -> RevIndex) -> IO OtherRevIdex -> IO RevIndex
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IO OtherRevIdex
newOtherRevIndex

renewRevIndex :: RevIndex -> IO ()
renewRevIndex :: RevIndex -> IO ()
renewRevIndex (RevIndex DynamicRevIndex
dyn OtherRevIdex
oth) = do
    DynamicRevIndex -> IO ()
renewDynamicRevIndex DynamicRevIndex
dyn
    OtherRevIdex -> IO ()
renewOtherRevIndex OtherRevIdex
oth

{-# INLINE lookupRevIndex #-}
lookupRevIndex :: Token
               -> HeaderValue
               -> RevIndex
               -> IO RevResult
lookupRevIndex :: Token -> ByteString -> RevIndex -> IO RevResult
lookupRevIndex t :: Token
t@Token{Bool
Int
CI ByteString
shouldBeIndexed :: Token -> Bool
isPseudo :: Token -> Bool
tokenKey :: Token -> CI ByteString
tokenKey :: CI ByteString
isPseudo :: Bool
shouldBeIndexed :: Bool
tokenIx :: Int
tokenIx :: Token -> Int
..} ByteString
v (RevIndex DynamicRevIndex
dyn OtherRevIdex
oth)
  | Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0          = (ByteString, ByteString) -> OtherRevIdex -> IO RevResult
lookupOtherRevIndex (ByteString
k,ByteString
v) OtherRevIdex
oth
  | Bool
shouldBeIndexed = Int -> ByteString -> DynamicRevIndex -> IO RevResult
lookupDynamicStaticRevIndex Int
ix ByteString
v DynamicRevIndex
dyn
  -- path: is not indexed but ":path /" should be used, sigh.
  | Bool
otherwise       = RevResult -> IO RevResult
forall (m :: * -> *) a. Monad m => a -> m a
return (RevResult -> IO RevResult) -> RevResult -> IO RevResult
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> RevResult
lookupStaticRevIndex Int
ix ByteString
v
  where
    ix :: Int
ix = Int -> Int
quicIx Int
tokenIx
    k :: ByteString
k = Token -> ByteString
tokenFoldedKey Token
t
--    ent = toEntryToken t v -- fixme

{-# INLINE lookupRevIndex' #-}
lookupRevIndex' :: Token
                -> HeaderValue
                -> RevResult
lookupRevIndex' :: Token -> ByteString -> RevResult
lookupRevIndex' Token{Bool
Int
CI ByteString
tokenKey :: CI ByteString
isPseudo :: Bool
shouldBeIndexed :: Bool
tokenIx :: Int
shouldBeIndexed :: Token -> Bool
isPseudo :: Token -> Bool
tokenKey :: Token -> CI ByteString
tokenIx :: Token -> Int
..} ByteString
v
  | Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0   = Int -> ByteString -> RevResult
lookupStaticRevIndex Int
ix ByteString
v
  | Bool
otherwise = RevResult
N -- fixme
  where
    ix :: Int
ix = Int -> Int
quicIx Int
tokenIx
--    k = tokenFoldedKey t -- fixme

----------------------------------------------------------------

{-# INLINE insertRevIndex #-}
insertRevIndex :: Entry -> HIndex -> RevIndex -> IO ()
insertRevIndex :: Entry -> HIndex -> RevIndex -> IO ()
insertRevIndex (Entry Int
_ Token
t ByteString
v) HIndex
i (RevIndex DynamicRevIndex
dyn OtherRevIdex
oth)
  | Int -> Int
quicIx (Token -> Int
tokenIx Token
t) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 = Token -> ByteString -> HIndex -> DynamicRevIndex -> IO ()
insertDynamicRevIndex Token
t ByteString
v HIndex
i DynamicRevIndex
dyn
  | Bool
otherwise               = Token -> ByteString -> HIndex -> OtherRevIdex -> IO ()
insertOtherRevIndex   Token
t ByteString
v HIndex
i OtherRevIdex
oth

{-# INLINE deleteRevIndex #-}
deleteRevIndex :: RevIndex -> Entry -> IO ()
deleteRevIndex :: RevIndex -> Entry -> IO ()
deleteRevIndex (RevIndex DynamicRevIndex
dyn OtherRevIdex
oth) (Entry Int
_ Token
t ByteString
v)
  | Int -> Int
quicIx (Token -> Int
tokenIx Token
t) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 = Token -> ByteString -> DynamicRevIndex -> IO ()
deleteDynamicRevIndex Token
t ByteString
v DynamicRevIndex
dyn
  | Bool
otherwise               = Token -> ByteString -> OtherRevIdex -> IO ()
deleteOtherRevIndex   Token
t ByteString
v OtherRevIdex
oth

{-# INLINE deleteRevIndexList #-}
deleteRevIndexList :: [Entry] -> RevIndex -> IO ()
deleteRevIndexList :: [Entry] -> RevIndex -> IO ()
deleteRevIndexList [Entry]
es RevIndex
rev = (Entry -> IO ()) -> [Entry] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (RevIndex -> Entry -> IO ()
deleteRevIndex RevIndex
rev) [Entry]
es

-- isStaticToken