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

    module Network.HPACK.Table.RevIndex (
        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.List.NonEmpty (NonEmpty (..))
    import qualified Data.List.NonEmpty as NE
    import Data.Map.Strict (Map)
    import qualified Data.Map.Strict as M
    import Network.HTTP.Semantics

    import Imports
    import Network.HPACK.Table.Entry
    import Network.HPACK.Table.Static
    import Network.HPACK.Types

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

    data RevIndex = RevIndex DynamicRevIndex OtherRevIdex

    type DynamicRevIndex = Array Int (IORef ValueMap)

    data KeyValue = KeyValue FieldName FieldValue deriving (KeyValue -> KeyValue -> Bool
    (KeyValue -> KeyValue -> Bool)
    -> (KeyValue -> KeyValue -> Bool) -> Eq KeyValue
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: KeyValue -> KeyValue -> Bool
    == :: KeyValue -> KeyValue -> Bool
    $c/= :: KeyValue -> KeyValue -> Bool
    /= :: 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
    $ccompare :: KeyValue -> KeyValue -> Ordering
    compare :: KeyValue -> KeyValue -> Ordering
    $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
    >= :: KeyValue -> KeyValue -> Bool
    $cmax :: KeyValue -> KeyValue -> KeyValue
    max :: KeyValue -> KeyValue -> KeyValue
    $cmin :: KeyValue -> KeyValue -> KeyValue
    min :: KeyValue -> KeyValue -> 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
    $cshowsPrec :: Int -> StaticEntry -> ShowS
    showsPrec :: Int -> StaticEntry -> ShowS
    $cshow :: StaticEntry -> String
    show :: StaticEntry -> String
    $cshowList :: [StaticEntry] -> ShowS
    showList :: [StaticEntry] -> ShowS
    Show)

    type ValueMap = Map FieldValue 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
    maxStaticTokenIx) ([(Int, StaticEntry)] -> StaticRevIndex)
    -> [(Int, StaticEntry)] -> StaticRevIndex
    forall a b. (a -> b) -> a -> b
    $ ((CI FieldValue, NonEmpty (FieldValue, HIndex))
     -> (Int, StaticEntry))
    -> [(CI FieldValue, NonEmpty (FieldValue, HIndex))]
    -> [(Int, StaticEntry)]
    forall a b. (a -> b) -> [a] -> [b]
    map (CI FieldValue, NonEmpty (FieldValue, HIndex))
    -> (Int, StaticEntry)
    toEnt [(CI FieldValue, NonEmpty (FieldValue, HIndex))]
    zs
      where
        toEnt :: (CI FieldValue, NonEmpty (FieldValue, HIndex))
    -> (Int, StaticEntry)
    toEnt (CI FieldValue
    k, NonEmpty (FieldValue, HIndex)
    xs) = (Token -> Int
    tokenIx (Token -> Int) -> Token -> Int
    forall a b. (a -> b) -> a -> b
    $ FieldValue -> Token
    toToken (FieldValue -> Token) -> FieldValue -> Token
    forall a b. (a -> b) -> a -> b
    $ CI FieldValue -> FieldValue
    forall s. CI s -> s
    foldedCase CI FieldValue
    k, StaticEntry
    m)
          where
            m :: StaticEntry
    m = case NonEmpty (FieldValue, HIndex)
    xs of
                (FieldValue
    "", HIndex
    i) :| [] -> HIndex -> Maybe ValueMap -> StaticEntry
    StaticEntry HIndex
    i Maybe ValueMap
    forall a. Maybe a
    Nothing
                (FieldValue
    _, HIndex
    i) :| [(FieldValue, HIndex)]
    _ ->
                    let vs :: ValueMap
    vs = [(FieldValue, HIndex)] -> ValueMap
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([(FieldValue, HIndex)] -> ValueMap)
    -> [(FieldValue, HIndex)] -> ValueMap
    forall a b. (a -> b) -> a -> b
    $ NonEmpty (FieldValue, HIndex) -> [(FieldValue, HIndex)]
    forall a. NonEmpty a -> [a]
    NE.toList NonEmpty (FieldValue, HIndex)
    xs
                     in HIndex -> Maybe ValueMap -> StaticEntry
    StaticEntry HIndex
    i (ValueMap -> Maybe ValueMap
    forall a. a -> Maybe a
    Just ValueMap
    vs)
        zs :: [(CI FieldValue, NonEmpty (FieldValue, HIndex))]
    zs = (NonEmpty (CI FieldValue, (FieldValue, HIndex))
     -> (CI FieldValue, NonEmpty (FieldValue, HIndex)))
    -> [NonEmpty (CI FieldValue, (FieldValue, HIndex))]
    -> [(CI FieldValue, NonEmpty (FieldValue, HIndex))]
    forall a b. (a -> b) -> [a] -> [b]
    map NonEmpty (CI FieldValue, (FieldValue, HIndex))
    -> (CI FieldValue, NonEmpty (FieldValue, HIndex))
    forall {a} {b}. NonEmpty (a, b) -> (a, NonEmpty b)
    extract ([NonEmpty (CI FieldValue, (FieldValue, HIndex))]
     -> [(CI FieldValue, NonEmpty (FieldValue, HIndex))])
    -> [NonEmpty (CI FieldValue, (FieldValue, HIndex))]
    -> [(CI FieldValue, NonEmpty (FieldValue, HIndex))]
    forall a b. (a -> b) -> a -> b
    $ ((CI FieldValue, (FieldValue, HIndex))
     -> (CI FieldValue, (FieldValue, HIndex)) -> Bool)
    -> [(CI FieldValue, (FieldValue, HIndex))]
    -> [NonEmpty (CI FieldValue, (FieldValue, HIndex))]
    forall (f :: * -> *) a.
    Foldable f =>
    (a -> a -> Bool) -> f a -> [NonEmpty a]
    NE.groupBy (CI FieldValue -> CI FieldValue -> Bool
    forall a. Eq a => a -> a -> Bool
    (==) (CI FieldValue -> CI FieldValue -> Bool)
    -> ((CI FieldValue, (FieldValue, HIndex)) -> CI FieldValue)
    -> (CI FieldValue, (FieldValue, HIndex))
    -> (CI FieldValue, (FieldValue, HIndex))
    -> Bool
    forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
    `on` (CI FieldValue, (FieldValue, HIndex)) -> CI FieldValue
    forall a b. (a, b) -> a
    fst) [(CI FieldValue, (FieldValue, HIndex))]
    lst
          where
            lst :: [(CI FieldValue, (FieldValue, HIndex))]
    lst = ((CI FieldValue, FieldValue)
     -> HIndex -> (CI FieldValue, (FieldValue, HIndex)))
    -> [(CI FieldValue, FieldValue)]
    -> [HIndex]
    -> [(CI FieldValue, (FieldValue, HIndex))]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (\(CI FieldValue
    k, FieldValue
    v) HIndex
    i -> (CI FieldValue
    k, (FieldValue
    v, HIndex
    i))) [(CI FieldValue, FieldValue)]
    staticTableList ([HIndex] -> [(CI FieldValue, (FieldValue, HIndex))])
    -> [HIndex] -> [(CI FieldValue, (FieldValue, HIndex))]
    forall a b. (a -> b) -> a -> b
    $ (Int -> HIndex) -> [Int] -> [HIndex]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> HIndex
    SIndex [Int
    1 ..]

            extract :: NonEmpty (a, b) -> (a, NonEmpty b)
    extract NonEmpty (a, b)
    xs = ((a, b) -> a
    forall a b. (a, b) -> a
    fst (NonEmpty (a, b) -> (a, b)
    forall a. NonEmpty a -> a
    NE.head NonEmpty (a, b)
    xs), ((a, b) -> b) -> NonEmpty (a, b) -> NonEmpty b
    forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
    NE.map (a, b) -> b
    forall a b. (a, b) -> b
    snd NonEmpty (a, b)
    xs)

    {-# INLINE lookupStaticRevIndex #-}
    lookupStaticRevIndex
        :: Int -> FieldValue -> (HIndex -> IO ()) -> (HIndex -> IO ()) -> IO ()
    lookupStaticRevIndex :: Int
    -> FieldValue -> (HIndex -> IO ()) -> (HIndex -> IO ()) -> IO ()
    lookupStaticRevIndex Int
    ix FieldValue
    v HIndex -> IO ()
    fa' HIndex -> IO ()
    fbd' = case StaticRevIndex
    staticRevIndex StaticRevIndex -> Int -> StaticEntry
    forall i. Ix i => Array i StaticEntry -> 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 -> IO ()
    fbd' HIndex
    i
        StaticEntry HIndex
    i (Just ValueMap
    m) -> case FieldValue -> ValueMap -> Maybe HIndex
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup FieldValue
    v ValueMap
    m of
            Maybe HIndex
    Nothing -> HIndex -> IO ()
    fbd' HIndex
    i
            Just HIndex
    j -> HIndex -> IO ()
    fa' 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)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [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 i. Ix i => Array i (IORef ValueMap) -> 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
        -> FieldValue
        -> DynamicRevIndex
        -> (HIndex -> IO ())
        -> (HIndex -> IO ())
        -> IO ()
    lookupDynamicStaticRevIndex :: Int
    -> FieldValue
    -> DynamicRevIndex
    -> (HIndex -> IO ())
    -> (HIndex -> IO ())
    -> IO ()
    lookupDynamicStaticRevIndex Int
    ix FieldValue
    v DynamicRevIndex
    drev HIndex -> IO ()
    fa' HIndex -> IO ()
    fbd' = do
        let ref :: IORef ValueMap
    ref = DynamicRevIndex
    drev DynamicRevIndex -> Int -> IORef ValueMap
    forall i. Ix i => Array i (IORef ValueMap) -> Int -> IORef ValueMap
    forall (a :: * -> * -> *) e i.
    (IArray a e, Ix i) =>
    a i e -> Int -> e
    `unsafeAt` Int
    ix
        m <- IORef ValueMap -> IO ValueMap
    forall a. IORef a -> IO a
    readIORef IORef ValueMap
    ref
        case M.lookup v m of
            Just HIndex
    i -> HIndex -> IO ()
    fa' HIndex
    i
            Maybe HIndex
    Nothing -> Int
    -> FieldValue -> (HIndex -> IO ()) -> (HIndex -> IO ()) -> IO ()
    lookupStaticRevIndex Int
    ix FieldValue
    v HIndex -> IO ()
    fa' HIndex -> IO ()
    fbd'

    {-# INLINE insertDynamicRevIndex #-}
    insertDynamicRevIndex
        :: Token -> FieldValue -> HIndex -> DynamicRevIndex -> IO ()
    insertDynamicRevIndex :: Token -> FieldValue -> HIndex -> DynamicRevIndex -> IO ()
    insertDynamicRevIndex Token
    t FieldValue
    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
    $ FieldValue -> HIndex -> ValueMap -> ValueMap
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    M.insert FieldValue
    v HIndex
    i
      where
        ref :: IORef ValueMap
    ref = DynamicRevIndex
    drev DynamicRevIndex -> Int -> IORef ValueMap
    forall i. Ix i => Array i (IORef ValueMap) -> 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 -> FieldValue -> DynamicRevIndex -> IO ()
    deleteDynamicRevIndex :: Token -> FieldValue -> DynamicRevIndex -> IO ()
    deleteDynamicRevIndex Token
    t FieldValue
    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
    $ FieldValue -> ValueMap -> ValueMap
    forall k a. Ord k => k -> Map k a -> Map k a
    M.delete FieldValue
    v
      where
        ref :: IORef ValueMap
    ref = DynamicRevIndex
    drev DynamicRevIndex -> Int -> IORef ValueMap
    forall i. Ix i => Array i (IORef ValueMap) -> 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
        :: (FieldName, FieldValue) -> OtherRevIdex -> (HIndex -> IO ()) -> IO () -> IO ()
    lookupOtherRevIndex :: (FieldValue, FieldValue)
    -> OtherRevIdex -> (HIndex -> IO ()) -> IO () -> IO ()
    lookupOtherRevIndex (FieldValue
    k, FieldValue
    v) OtherRevIdex
    ref HIndex -> IO ()
    fa' IO ()
    fc' = do
        oth <- OtherRevIdex -> IO (Map KeyValue HIndex)
    forall a. IORef a -> IO a
    readIORef OtherRevIdex
    ref
        maybe fc' fa' $ M.lookup (KeyValue k v) oth

    {-# INLINE insertOtherRevIndex #-}
    insertOtherRevIndex :: Token -> FieldValue -> HIndex -> OtherRevIdex -> IO ()
    insertOtherRevIndex :: Token -> FieldValue -> HIndex -> OtherRevIdex -> IO ()
    insertOtherRevIndex Token
    t FieldValue
    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 (FieldValue -> FieldValue -> KeyValue
    KeyValue FieldValue
    k FieldValue
    v) HIndex
    i
      where
        k :: FieldValue
    k = Token -> FieldValue
    tokenFoldedKey Token
    t

    {-# INLINE deleteOtherRevIndex #-}
    deleteOtherRevIndex :: Token -> FieldValue -> OtherRevIdex -> IO ()
    deleteOtherRevIndex :: Token -> FieldValue -> OtherRevIdex -> IO ()
    deleteOtherRevIndex Token
    t FieldValue
    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 (FieldValue -> FieldValue -> KeyValue
    KeyValue FieldValue
    k FieldValue
    v)
      where
        k :: FieldValue
    k = Token -> FieldValue
    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 a b. IO (a -> b) -> IO a -> IO b
    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
        -> FieldValue
        -> (HIndex -> IO ())
        -> (FieldValue -> Entry -> HIndex -> IO ())
        -> (FieldName -> FieldValue -> Entry -> IO ())
        -> (FieldValue -> HIndex -> IO ())
        -> RevIndex
        -> IO ()
    lookupRevIndex :: Token
    -> FieldValue
    -> (HIndex -> IO ())
    -> (FieldValue -> Entry -> HIndex -> IO ())
    -> (FieldValue -> FieldValue -> Entry -> IO ())
    -> (FieldValue -> HIndex -> IO ())
    -> RevIndex
    -> IO ()
    lookupRevIndex t :: Token
    t@Token{Bool
    Int
    CI FieldValue
    tokenIx :: Token -> Int
    tokenIx :: Int
    shouldBeIndexed :: Bool
    isPseudo :: Bool
    tokenKey :: CI FieldValue
    tokenKey :: Token -> CI FieldValue
    isPseudo :: Token -> Bool
    shouldBeIndexed :: Token -> Bool
    ..} FieldValue
    v HIndex -> IO ()
    fa FieldValue -> Entry -> HIndex -> IO ()
    fb FieldValue -> FieldValue -> Entry -> IO ()
    fc FieldValue -> HIndex -> IO ()
    fd (RevIndex DynamicRevIndex
    dyn OtherRevIdex
    oth)
        | Bool -> Bool
    not (Int -> Bool
    isStaticTokenIx Int
    tokenIx) = (FieldValue, FieldValue)
    -> OtherRevIdex -> (HIndex -> IO ()) -> IO () -> IO ()
    lookupOtherRevIndex (FieldValue
    k, FieldValue
    v) OtherRevIdex
    oth HIndex -> IO ()
    fa' IO ()
    fc'
        | Bool
    shouldBeIndexed =
            Int
    -> FieldValue
    -> DynamicRevIndex
    -> (HIndex -> IO ())
    -> (HIndex -> IO ())
    -> IO ()
    lookupDynamicStaticRevIndex Int
    tokenIx FieldValue
    v DynamicRevIndex
    dyn HIndex -> IO ()
    fa' HIndex -> IO ()
    fb'
        -- path: is not indexed but ":path /" should be used, sigh.
        | Bool
    otherwise = Int
    -> FieldValue -> (HIndex -> IO ()) -> (HIndex -> IO ()) -> IO ()
    lookupStaticRevIndex Int
    tokenIx FieldValue
    v HIndex -> IO ()
    fa' HIndex -> IO ()
    fd'
      where
        k :: FieldValue
    k = CI FieldValue -> FieldValue
    forall s. CI s -> s
    foldedCase CI FieldValue
    tokenKey
        ent :: Entry
    ent = Token -> FieldValue -> Entry
    toEntryToken Token
    t FieldValue
    v
        fa' :: HIndex -> IO ()
    fa' = HIndex -> IO ()
    fa
        fb' :: HIndex -> IO ()
    fb' = FieldValue -> Entry -> HIndex -> IO ()
    fb FieldValue
    v Entry
    ent
        fc' :: IO ()
    fc' = FieldValue -> FieldValue -> Entry -> IO ()
    fc FieldValue
    k FieldValue
    v Entry
    ent
        fd' :: HIndex -> IO ()
    fd' = FieldValue -> HIndex -> IO ()
    fd FieldValue
    v

    {-# INLINE lookupRevIndex' #-}
    lookupRevIndex'
        :: Token
        -> FieldValue
        -> (HIndex -> IO ())
        -> (FieldValue -> HIndex -> IO ())
        -> (FieldName -> FieldValue -> IO ())
        -> IO ()
    lookupRevIndex' :: Token
    -> FieldValue
    -> (HIndex -> IO ())
    -> (FieldValue -> HIndex -> IO ())
    -> (FieldValue -> FieldValue -> IO ())
    -> IO ()
    lookupRevIndex' Token{Bool
    Int
    CI FieldValue
    tokenIx :: Token -> Int
    tokenKey :: Token -> CI FieldValue
    isPseudo :: Token -> Bool
    shouldBeIndexed :: Token -> Bool
    tokenIx :: Int
    shouldBeIndexed :: Bool
    isPseudo :: Bool
    tokenKey :: CI FieldValue
    ..} FieldValue
    v HIndex -> IO ()
    fa FieldValue -> HIndex -> IO ()
    fd FieldValue -> FieldValue -> IO ()
    fe
        | Int -> Bool
    isStaticTokenIx Int
    tokenIx = Int
    -> FieldValue -> (HIndex -> IO ()) -> (HIndex -> IO ()) -> IO ()
    lookupStaticRevIndex Int
    tokenIx FieldValue
    v HIndex -> IO ()
    fa' HIndex -> IO ()
    fd'
        | Bool
    otherwise = IO ()
    fe'
      where
        k :: FieldValue
    k = CI FieldValue -> FieldValue
    forall s. CI s -> s
    foldedCase CI FieldValue
    tokenKey
        fa' :: HIndex -> IO ()
    fa' = HIndex -> IO ()
    fa
        fd' :: HIndex -> IO ()
    fd' = FieldValue -> HIndex -> IO ()
    fd FieldValue
    v
        fe' :: IO ()
    fe' = FieldValue -> FieldValue -> IO ()
    fe FieldValue
    k FieldValue
    v

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

    {-# INLINE insertRevIndex #-}
    insertRevIndex :: Entry -> HIndex -> RevIndex -> IO ()
    insertRevIndex :: Entry -> HIndex -> RevIndex -> IO ()
    insertRevIndex (Entry Int
    _ Token
    t FieldValue
    v) HIndex
    i (RevIndex DynamicRevIndex
    dyn OtherRevIdex
    oth)
        | Token -> Bool
    isStaticToken Token
    t = Token -> FieldValue -> HIndex -> DynamicRevIndex -> IO ()
    insertDynamicRevIndex Token
    t FieldValue
    v HIndex
    i DynamicRevIndex
    dyn
        | Bool
    otherwise = Token -> FieldValue -> HIndex -> OtherRevIdex -> IO ()
    insertOtherRevIndex Token
    t FieldValue
    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 FieldValue
    v)
        | Token -> Bool
    isStaticToken Token
    t = Token -> FieldValue -> DynamicRevIndex -> IO ()
    deleteDynamicRevIndex Token
    t FieldValue
    v DynamicRevIndex
    dyn
        | Bool
    otherwise = Token -> FieldValue -> OtherRevIdex -> IO ()
    deleteOtherRevIndex Token
    t FieldValue
    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