{-# 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