{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# OPTIONS_HADDOCK not-home #-}
module Data.BloomFilter.Classic.Internal (
MBloom (mbHashSalt),
new,
maxSizeBits,
Bloom (hashSalt),
bloomInvariant,
size,
Hashes,
Salt,
hashesWithSalt,
insertHashes,
elemHashes,
readHashes,
freeze,
unsafeFreeze,
thaw,
formatVersion,
serialise,
deserialise,
) where
import Control.DeepSeq (NFData (..))
import Control.Exception (assert)
import Control.Monad.Primitive (PrimMonad, PrimState)
import Control.Monad.ST (ST)
import Data.Bits
import Data.Kind (Type)
import Data.Primitive.ByteArray
import Data.Primitive.PrimArray
import Data.Primitive.Types (Prim (..))
import Data.Word (Word64)
import GHC.Exts (Int (I#), Int#, int2Word#, timesWord2#,
uncheckedIShiftL#, word2Int#, (+#))
import qualified GHC.Exts as Exts
import GHC.Word (Word64 (W64#))
import Data.BloomFilter.Classic.BitArray (BitArray, MBitArray)
import qualified Data.BloomFilter.Classic.BitArray as BitArray
import Data.BloomFilter.Classic.Calc
import Data.BloomFilter.Hash
formatVersion :: Int
formatVersion :: Int
formatVersion = Int
1
type MBloom :: Type -> Type -> Type
data MBloom s a = MBloom {
forall s a. MBloom s a -> Int
mbNumBits :: {-# UNPACK #-} !Int
, forall s a. MBloom s a -> Int
mbNumHashes :: {-# UNPACK #-} !Int
, forall s a. MBloom s a -> Salt
mbHashSalt :: {-# UNPACK #-} !Salt
, forall s a. MBloom s a -> MBitArray s
mbBitArray :: {-# UNPACK #-} !(MBitArray s)
}
type role MBloom nominal nominal
instance Show (MBloom s a) where
show :: MBloom s a -> String
show MBloom s a
mb = String
"MBloom { " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (MBloom s a -> Int
forall s a. MBloom s a -> Int
mbNumBits MBloom s a
mb) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" bits } "
instance NFData (MBloom s a) where
rnf :: MBloom s a -> ()
rnf !MBloom s a
_ = ()
new :: BloomSize -> Salt -> ST s (MBloom s a)
new :: forall s a. BloomSize -> Salt -> ST s (MBloom s a)
new BloomSize { Int
sizeBits :: Int
sizeBits :: BloomSize -> Int
sizeBits, Int
sizeHashes :: Int
sizeHashes :: BloomSize -> Int
sizeHashes } Salt
mbHashSalt = do
let !mbNumBits :: Int
mbNumBits = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
maxSizeBits Int
sizeBits)
MBitArray s
mbBitArray <- Int -> ST s (MBitArray s)
forall s. Int -> ST s (MBitArray s)
BitArray.new Int
mbNumBits
MBloom s a -> ST s (MBloom s a)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure MBloom {
Int
mbNumBits :: Int
mbNumBits :: Int
mbNumBits,
mbNumHashes :: Int
mbNumHashes = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
sizeHashes,
Salt
mbHashSalt :: Salt
mbHashSalt :: Salt
mbHashSalt,
MBitArray s
mbBitArray :: MBitArray s
mbBitArray :: MBitArray s
mbBitArray
}
maxSizeBits :: Int
maxSizeBits :: Int
maxSizeBits = Int
0x1_0000_0000_0000
insertHashes :: MBloom s a -> Hashes a -> ST s ()
insertHashes :: forall s a. MBloom s a -> Hashes a -> ST s ()
insertHashes MBloom { Int
mbNumBits :: forall s a. MBloom s a -> Int
mbNumBits :: Int
mbNumBits, Int
mbNumHashes :: forall s a. MBloom s a -> Int
mbNumHashes :: Int
mbNumHashes, MBitArray s
mbBitArray :: forall s a. MBloom s a -> MBitArray s
mbBitArray :: MBitArray s
mbBitArray } !Hashes a
h =
Int -> ST s ()
go Int
0
where
go :: Int -> ST s ()
go !Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
mbNumHashes = () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
go !Int
i = do
let probe :: Word64
probe :: Salt
probe = Hashes a -> Int -> Salt
forall {k} (a :: k). Hashes a -> Int -> Salt
evalHashes Hashes a
h Int
i
index :: Int
index :: Int
index = Salt -> Int -> Int
reduceRange64 Salt
probe Int
mbNumBits
MBitArray s -> Int -> ST s ()
forall s. MBitArray s -> Int -> ST s ()
BitArray.unsafeSet MBitArray s
mbBitArray Int
index
Int -> ST s ()
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
readHashes :: forall s a. MBloom s a -> Hashes a -> ST s Bool
readHashes :: forall s a. MBloom s a -> Hashes a -> ST s Bool
readHashes MBloom { Int
mbNumBits :: forall s a. MBloom s a -> Int
mbNumBits :: Int
mbNumBits, Int
mbNumHashes :: forall s a. MBloom s a -> Int
mbNumHashes :: Int
mbNumHashes, MBitArray s
mbBitArray :: forall s a. MBloom s a -> MBitArray s
mbBitArray :: MBitArray s
mbBitArray } !Hashes a
h =
Int -> ST s Bool
go Int
0
where
go :: Int -> ST s Bool
go :: Int -> ST s Bool
go !Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
mbNumHashes = Bool -> ST s Bool
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
go !Int
i = do
let probe :: Word64
probe :: Salt
probe = Hashes a -> Int -> Salt
forall {k} (a :: k). Hashes a -> Int -> Salt
evalHashes Hashes a
h Int
i
index :: Int
index :: Int
index = Salt -> Int -> Int
reduceRange64 Salt
probe Int
mbNumBits
Bool
b <- MBitArray s -> Int -> ST s Bool
forall s. MBitArray s -> Int -> ST s Bool
BitArray.unsafeRead MBitArray s
mbBitArray Int
index
if Bool
b then Int -> ST s Bool
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
else Bool -> ST s Bool
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
{-# INLINE deserialise #-}
deserialise :: PrimMonad m
=> MBloom (PrimState m) a
-> (MutableByteArray (PrimState m) -> Int -> Int -> m ())
-> m ()
deserialise :: forall (m :: * -> *) a.
PrimMonad m =>
MBloom (PrimState m) a
-> (MutableByteArray (PrimState m) -> Int -> Int -> m ()) -> m ()
deserialise MBloom {MBitArray (PrimState m)
mbBitArray :: forall s a. MBloom s a -> MBitArray s
mbBitArray :: MBitArray (PrimState m)
mbBitArray} MutableByteArray (PrimState m) -> Int -> Int -> m ()
fill =
MBitArray (PrimState m)
-> (MutableByteArray (PrimState m) -> Int -> Int -> m ()) -> m ()
forall (m :: * -> *).
PrimMonad m =>
MBitArray (PrimState m)
-> (MutableByteArray (PrimState m) -> Int -> Int -> m ()) -> m ()
BitArray.deserialise MBitArray (PrimState m)
mbBitArray MutableByteArray (PrimState m) -> Int -> Int -> m ()
fill
type Bloom :: Type -> Type
data Bloom a = Bloom {
forall a. Bloom a -> Int
numBits :: {-# UNPACK #-} !Int
, forall a. Bloom a -> Int
numHashes :: {-# UNPACK #-} !Int
, forall a. Bloom a -> Salt
hashSalt :: {-# UNPACK #-} !Salt
, forall a. Bloom a -> BitArray
bitArray :: {-# UNPACK #-} !BitArray
}
deriving stock Bloom a -> Bloom a -> Bool
(Bloom a -> Bloom a -> Bool)
-> (Bloom a -> Bloom a -> Bool) -> Eq (Bloom a)
forall a. Bloom a -> Bloom a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Bloom a -> Bloom a -> Bool
== :: Bloom a -> Bloom a -> Bool
$c/= :: forall a. Bloom a -> Bloom a -> Bool
/= :: Bloom a -> Bloom a -> Bool
Eq
type role Bloom nominal
bloomInvariant :: Bloom a -> Bool
bloomInvariant :: forall a. Bloom a -> Bool
bloomInvariant Bloom { Int
numBits :: forall a. Bloom a -> Int
numBits :: Int
numBits, Int
numHashes :: forall a. Bloom a -> Int
numHashes :: Int
numHashes, bitArray :: forall a. Bloom a -> BitArray
bitArray = BitArray.BitArray PrimArray Salt
pa } =
Int
numBits Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
Bool -> Bool -> Bool
&& Int
numBits Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
2Int -> Int -> Int
forall a b. (Num a, Integral b) => a -> b -> a
^(Int
48 :: Int)
Bool -> Bool -> Bool
&& Int -> Int
forall {a}. (Bits a, Num a) => a -> a
ceilDiv64 Int
numBits Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== PrimArray Salt -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray Salt
pa
Bool -> Bool -> Bool
&& Int
numHashes Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
where
ceilDiv64 :: a -> a
ceilDiv64 a
x = a -> Int -> a
forall a. Bits a => a -> Int -> a
unsafeShiftR (a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
63) Int
6
instance Show (Bloom a) where
show :: Bloom a -> String
show Bloom a
mb = String
"Bloom { " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Bloom a -> Int
forall a. Bloom a -> Int
numBits Bloom a
mb) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" bits } "
instance NFData (Bloom a) where
rnf :: Bloom a -> ()
rnf !Bloom a
_ = ()
size :: Bloom a -> BloomSize
size :: forall a. Bloom a -> BloomSize
size Bloom { Int
numBits :: forall a. Bloom a -> Int
numBits :: Int
numBits, Int
numHashes :: forall a. Bloom a -> Int
numHashes :: Int
numHashes } =
BloomSize {
sizeBits :: Int
sizeBits = Int
numBits,
sizeHashes :: Int
sizeHashes = Int
numHashes
}
elemHashes :: Bloom a -> Hashes a -> Bool
elemHashes :: forall a. Bloom a -> Hashes a -> Bool
elemHashes Bloom { Int
numBits :: forall a. Bloom a -> Int
numBits :: Int
numBits, Int
numHashes :: forall a. Bloom a -> Int
numHashes :: Int
numHashes, BitArray
bitArray :: forall a. Bloom a -> BitArray
bitArray :: BitArray
bitArray } !Hashes a
h =
Int -> Bool
go Int
0
where
go :: Int -> Bool
go :: Int -> Bool
go !Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
numHashes = Bool
True
go !Int
i =
let probe :: Word64
probe :: Salt
probe = Hashes a -> Int -> Salt
forall {k} (a :: k). Hashes a -> Int -> Salt
evalHashes Hashes a
h Int
i
index :: Int
index :: Int
index = Salt -> Int -> Int
reduceRange64 Salt
probe Int
numBits
in if BitArray -> Int -> Bool
BitArray.unsafeIndex BitArray
bitArray Int
index
then Int -> Bool
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
else Bool
False
serialise :: Bloom a -> (BloomSize, Salt, ByteArray, Int, Int)
serialise :: forall a. Bloom a -> (BloomSize, Salt, ByteArray, Int, Int)
serialise b :: Bloom a
b@Bloom{BitArray
bitArray :: forall a. Bloom a -> BitArray
bitArray :: BitArray
bitArray} =
(Bloom a -> BloomSize
forall a. Bloom a -> BloomSize
size Bloom a
b, Bloom a -> Salt
forall a. Bloom a -> Salt
hashSalt Bloom a
b, ByteArray
ba, Int
off, Int
len)
where
(ByteArray
ba, Int
off, Int
len) = BitArray -> (ByteArray, Int, Int)
BitArray.serialise BitArray
bitArray
freeze :: MBloom s a -> ST s (Bloom a)
freeze :: forall s a. MBloom s a -> ST s (Bloom a)
freeze MBloom { Int
mbNumBits :: forall s a. MBloom s a -> Int
mbNumBits :: Int
mbNumBits, Int
mbNumHashes :: forall s a. MBloom s a -> Int
mbNumHashes :: Int
mbNumHashes, Salt
mbHashSalt :: forall s a. MBloom s a -> Salt
mbHashSalt :: Salt
mbHashSalt, MBitArray s
mbBitArray :: forall s a. MBloom s a -> MBitArray s
mbBitArray :: MBitArray s
mbBitArray } = do
BitArray
bitArray <- MBitArray s -> ST s BitArray
forall s. MBitArray s -> ST s BitArray
BitArray.freeze MBitArray s
mbBitArray
let !bf :: Bloom a
bf = Bloom {
numBits :: Int
numBits = Int
mbNumBits,
numHashes :: Int
numHashes = Int
mbNumHashes,
hashSalt :: Salt
hashSalt = Salt
mbHashSalt,
BitArray
bitArray :: BitArray
bitArray :: BitArray
bitArray
}
Bool -> ST s (Bloom a) -> ST s (Bloom a)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Bloom a -> Bool
forall a. Bloom a -> Bool
bloomInvariant Bloom a
bf) (ST s (Bloom a) -> ST s (Bloom a))
-> ST s (Bloom a) -> ST s (Bloom a)
forall a b. (a -> b) -> a -> b
$ Bloom a -> ST s (Bloom a)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bloom a
bf
unsafeFreeze :: MBloom s a -> ST s (Bloom a)
unsafeFreeze :: forall s a. MBloom s a -> ST s (Bloom a)
unsafeFreeze MBloom { Int
mbNumBits :: forall s a. MBloom s a -> Int
mbNumBits :: Int
mbNumBits, Int
mbNumHashes :: forall s a. MBloom s a -> Int
mbNumHashes :: Int
mbNumHashes, Salt
mbHashSalt :: forall s a. MBloom s a -> Salt
mbHashSalt :: Salt
mbHashSalt, MBitArray s
mbBitArray :: forall s a. MBloom s a -> MBitArray s
mbBitArray :: MBitArray s
mbBitArray } = do
BitArray
bitArray <- MBitArray s -> ST s BitArray
forall s. MBitArray s -> ST s BitArray
BitArray.unsafeFreeze MBitArray s
mbBitArray
let !bf :: Bloom a
bf = Bloom {
numBits :: Int
numBits = Int
mbNumBits,
numHashes :: Int
numHashes = Int
mbNumHashes,
hashSalt :: Salt
hashSalt = Salt
mbHashSalt,
BitArray
bitArray :: BitArray
bitArray :: BitArray
bitArray
}
Bool -> ST s (Bloom a) -> ST s (Bloom a)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Bloom a -> Bool
forall a. Bloom a -> Bool
bloomInvariant Bloom a
bf) (ST s (Bloom a) -> ST s (Bloom a))
-> ST s (Bloom a) -> ST s (Bloom a)
forall a b. (a -> b) -> a -> b
$ Bloom a -> ST s (Bloom a)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bloom a
bf
thaw :: Bloom a -> ST s (MBloom s a)
thaw :: forall a s. Bloom a -> ST s (MBloom s a)
thaw Bloom { Int
numBits :: forall a. Bloom a -> Int
numBits :: Int
numBits, Int
numHashes :: forall a. Bloom a -> Int
numHashes :: Int
numHashes, Salt
hashSalt :: forall a. Bloom a -> Salt
hashSalt :: Salt
hashSalt, BitArray
bitArray :: forall a. Bloom a -> BitArray
bitArray :: BitArray
bitArray } = do
MBitArray s
mbBitArray <- BitArray -> ST s (MBitArray s)
forall s. BitArray -> ST s (MBitArray s)
BitArray.thaw BitArray
bitArray
MBloom s a -> ST s (MBloom s a)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure MBloom {
mbNumBits :: Int
mbNumBits = Int
numBits,
mbNumHashes :: Int
mbNumHashes = Int
numHashes,
mbHashSalt :: Salt
mbHashSalt = Salt
hashSalt,
MBitArray s
mbBitArray :: MBitArray s
mbBitArray :: MBitArray s
mbBitArray
}
{-# INLINE reduceRange64 #-}
reduceRange64 :: Word64
-> Int
-> Int
reduceRange64 :: Salt -> Int -> Int
reduceRange64 (W64# Word64#
x) (I# Int#
n) =
case Word# -> Word# -> (# Word#, Word# #)
timesWord2# (Word64# -> Word#
word64ToWordShim# Word64#
x) (Int# -> Word#
int2Word# Int#
n) of
(# Word#
high, Word#
_low #) -> Int# -> Int
I# (Word# -> Int#
word2Int# Word#
high)
{-# INLINE word64ToWordShim# #-}
#if MIN_VERSION_base(4,17,0)
word64ToWordShim# :: Exts.Word64# -> Exts.Word#
word64ToWordShim# :: Word64# -> Word#
word64ToWordShim# = Word64# -> Word#
Exts.word64ToWord#
#else
word64ToWordShim# :: Exts.Word# -> Exts.Word#
word64ToWordShim# x# = x#
#endif
data Hashes a = Hashes !Hash !Hash
type role Hashes nominal
instance Prim (Hashes a) where
sizeOfType# :: Proxy (Hashes a) -> Int#
sizeOfType# Proxy (Hashes a)
_ = Int#
16#
alignmentOfType# :: Proxy (Hashes a) -> Int#
alignmentOfType# Proxy (Hashes a)
_ = Int#
8#
indexByteArray# :: ByteArray# -> Int# -> Hashes a
indexByteArray# ByteArray#
ba Int#
i = Salt -> Salt -> Hashes a
forall {k} (a :: k). Salt -> Salt -> Hashes a
Hashes
(ByteArray# -> Int# -> Salt
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba (Int# -> Int#
indexLo Int#
i))
(ByteArray# -> Int# -> Salt
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
ba (Int# -> Int#
indexHi Int#
i))
readByteArray# :: forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Hashes a #)
readByteArray# MutableByteArray# s
ba Int#
i State# s
s1 =
case MutableByteArray# s -> Int# -> State# s -> (# State# s, Salt #)
forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Salt #)
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# s
ba (Int# -> Int#
indexLo Int#
i) State# s
s1 of { (# State# s
s2, Salt
lo #) ->
case MutableByteArray# s -> Int# -> State# s -> (# State# s, Salt #)
forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Salt #)
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# s
ba (Int# -> Int#
indexHi Int#
i) State# s
s2 of { (# State# s
s3, Salt
hi #) ->
(# State# s
s3, Salt -> Salt -> Hashes a
forall {k} (a :: k). Salt -> Salt -> Hashes a
Hashes Salt
lo Salt
hi #)
}}
writeByteArray# :: forall s.
MutableByteArray# s -> Int# -> Hashes a -> State# s -> State# s
writeByteArray# MutableByteArray# s
ba Int#
i (Hashes Salt
lo Salt
hi) State# s
s =
MutableByteArray# s -> Int# -> Salt -> State# s -> State# s
forall s.
MutableByteArray# s -> Int# -> Salt -> State# s -> State# s
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# s
ba (Int# -> Int#
indexHi Int#
i) Salt
hi (MutableByteArray# s -> Int# -> Salt -> State# s -> State# s
forall s.
MutableByteArray# s -> Int# -> Salt -> State# s -> State# s
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# s
ba (Int# -> Int#
indexLo Int#
i) Salt
lo State# s
s)
indexOffAddr# :: Addr# -> Int# -> Hashes a
indexOffAddr# Addr#
ba Int#
i = Salt -> Salt -> Hashes a
forall {k} (a :: k). Salt -> Salt -> Hashes a
Hashes
(Addr# -> Int# -> Salt
forall a. Prim a => Addr# -> Int# -> a
indexOffAddr# Addr#
ba (Int# -> Int#
indexLo Int#
i))
(Addr# -> Int# -> Salt
forall a. Prim a => Addr# -> Int# -> a
indexOffAddr# Addr#
ba (Int# -> Int#
indexHi Int#
i))
readOffAddr# :: forall s. Addr# -> Int# -> State# s -> (# State# s, Hashes a #)
readOffAddr# Addr#
ba Int#
i State# s
s1 =
case Addr# -> Int# -> State# s -> (# State# s, Salt #)
forall s. Addr# -> Int# -> State# s -> (# State# s, Salt #)
forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
ba (Int# -> Int#
indexLo Int#
i) State# s
s1 of { (# State# s
s2, Salt
lo #) ->
case Addr# -> Int# -> State# s -> (# State# s, Salt #)
forall s. Addr# -> Int# -> State# s -> (# State# s, Salt #)
forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
ba (Int# -> Int#
indexHi Int#
i) State# s
s2 of { (# State# s
s3, Salt
hi #) ->
(# State# s
s3, Salt -> Salt -> Hashes a
forall {k} (a :: k). Salt -> Salt -> Hashes a
Hashes Salt
lo Salt
hi #)
}}
writeOffAddr# :: forall s. Addr# -> Int# -> Hashes a -> State# s -> State# s
writeOffAddr# Addr#
ba Int#
i (Hashes Salt
lo Salt
hi) State# s
s =
Addr# -> Int# -> Salt -> State# s -> State# s
forall s. Addr# -> Int# -> Salt -> State# s -> State# s
forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
ba (Int# -> Int#
indexHi Int#
i) Salt
hi (Addr# -> Int# -> Salt -> State# s -> State# s
forall s. Addr# -> Int# -> Salt -> State# s -> State# s
forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
ba (Int# -> Int#
indexLo Int#
i) Salt
lo State# s
s)
indexLo :: Int# -> Int#
indexLo :: Int# -> Int#
indexLo Int#
i = Int# -> Int# -> Int#
uncheckedIShiftL# Int#
i Int#
1#
indexHi :: Int# -> Int#
indexHi :: Int# -> Int#
indexHi Int#
i = Int# -> Int# -> Int#
uncheckedIShiftL# Int#
i Int#
1# Int# -> Int# -> Int#
+# Int#
1#
evalHashes :: Hashes a -> Int -> Hash
evalHashes :: forall {k} (a :: k). Hashes a -> Int -> Salt
evalHashes (Hashes Salt
h1 Salt
h2) Int
i = Salt
h1 Salt -> Salt -> Salt
forall a. Num a => a -> a -> a
+ (Salt
h2 Salt -> Int -> Salt
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
i)
hashesWithSalt :: Hashable a => Salt -> a -> Hashes a
hashesWithSalt :: forall a. Hashable a => Salt -> a -> Hashes a
hashesWithSalt Salt
salt a
v = Salt -> Salt -> Hashes a
forall {k} (a :: k). Salt -> Salt -> Hashes a
Hashes (Salt -> a -> Salt
forall a. Hashable a => Salt -> a -> Salt
hashSalt64 Salt
salt a
v) (Salt -> a -> Salt
forall a. Hashable a => Salt -> a -> Salt
hashSalt64 (Salt
salt Salt -> Salt -> Salt
forall a. Num a => a -> a -> a
+ Salt
1) a
v)
{-# INLINE hashesWithSalt #-}