module Network.Wai.Handler.Warp.HashMap where

import Data.ByteString (ByteString)
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)

type Hash = Int
newtype HashMap k v = HashMap (IntMap (Map k v))

hashByteString :: ByteString -> Hash
hashByteString = hash

empty :: HashMap k v
empty = HashMap $ I.empty

null :: HashMap k v -> Bool
null (HashMap hm) = I.null hm

insert :: Ord k => Hash -> k -> v -> HashMap k v -> HashMap k v
insert h k v (HashMap hm) = HashMap $ I.insertWith f h m hm
  where
    m = M.singleton k v
    f = M.union -- fimxe
{-# SPECIALIZE insert :: Hash -> String -> v -> HashMap String v -> HashMap String v #-}

lookup :: Ord k => Hash -> k -> HashMap k v -> Maybe v
lookup h k (HashMap hm) = I.lookup h hm >>= M.lookup k
{-# SPECIALIZE lookup :: Hash -> String -> HashMap String v -> Maybe v #-}
