warp-3.2.28: Network/Wai/Handler/Warp/HashMap.hs
{-# LANGUAGE BangPatterns #-}
module Network.Wai.Handler.Warp.HashMap where
import Data.Hashable (hash)
import Data.IntMap.Strict (IntMap)
import qualified Data.IntMap.Strict as I
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M
import Prelude hiding (lookup)
----------------------------------------------------------------
-- | 'HashMap' is used for cache of file information.
-- Hash values of file pathes are used as outer keys.
-- Because negative entries are also contained,
-- a bad guy can intentionally cause the hash collison.
-- So, 'Map' is used internally to prevent
-- the hash collision attack.
newtype HashMap v = HashMap (IntMap (Map FilePath v))
----------------------------------------------------------------
empty :: HashMap v
empty = HashMap I.empty
isEmpty :: HashMap v -> Bool
isEmpty (HashMap hm) = I.null hm
----------------------------------------------------------------
insert :: FilePath -> v -> HashMap v -> HashMap v
insert path v (HashMap hm) = HashMap $ I.insertWith f h m hm
where
!h = hash path
!m = M.singleton path v
f = M.union -- fimxe
lookup :: FilePath -> HashMap v -> Maybe v
lookup path (HashMap hm) = I.lookup h hm >>= M.lookup path
where
!h = hash path