module Data.PerfectHash.Hashing where
import Data.Binary (encode)
import Data.Bits (xor, (.&.))
import Data.ByteString.Lazy (unpack)
import Data.Char (ord)
import Data.Text (Text)
import qualified Data.Text as T
primeFNV :: Int
primeFNV = 0x01000193
mask32bits :: Int
mask32bits = 0xffffffff
class ToHashableChunks a where
toHashableChunks :: a -> [Int]
instance ToHashableChunks Int where
toHashableChunks = map fromIntegral . unpack . encode
instance ToHashableChunks Text where
toHashableChunks = map ord . T.unpack
instance ToHashableChunks String where
toHashableChunks = map ord
hashToSlot :: ToHashableChunks a =>
Int
-> a
-> Int
-> Int
hashToSlot nonce key size = hash nonce key `mod` size
hash :: ToHashableChunks a =>
Int
-> a
-> Int
hash nonce =
foldl combine d . toHashableChunks
where
d = if nonce == 0
then primeFNV
else nonce
combine acc = (.&. mask32bits) . (* primeFNV) . xor acc