module Data.BloomFilter.Classic (
Hash,
Salt,
Hashable,
Bloom,
create,
unfold,
fromList,
formatVersion,
serialise,
deserialise,
NumEntries,
BloomSize (..),
FPR,
sizeForFPR,
BitsPerEntry,
sizeForBits,
sizeForPolicy,
BloomPolicy (..),
policyFPR,
policyForFPR,
policyForBits,
size,
elem,
notElem,
(?),
MBloom,
new,
maxSizeBits,
insert,
read,
freeze,
thaw,
unsafeFreeze,
Hashes,
hashesWithSalt,
insertHashes,
elemHashes,
readHashes,
) where
import Control.Monad.Primitive (PrimMonad, PrimState, RealWorld,
stToPrim)
import Control.Monad.ST (ST, runST)
import Data.Primitive.ByteArray (MutableByteArray)
import Data.BloomFilter.Classic.Calc
import Data.BloomFilter.Classic.Internal hiding (deserialise)
import qualified Data.BloomFilter.Classic.Internal as Internal
import Data.BloomFilter.Hash
import Prelude hiding (elem, notElem, read)
create :: BloomSize
-> Salt
-> (forall s. (MBloom s a -> ST s ()))
-> Bloom a
{-# INLINE create #-}
create :: forall a.
BloomSize -> Salt -> (forall s. MBloom s a -> ST s ()) -> Bloom a
create BloomSize
bloomsize Salt
bloomsalt forall s. MBloom s a -> ST s ()
body =
(forall s. ST s (Bloom a)) -> Bloom a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Bloom a)) -> Bloom a)
-> (forall s. ST s (Bloom a)) -> Bloom a
forall a b. (a -> b) -> a -> b
$ do
MBloom s a
mb <- BloomSize -> Salt -> ST s (MBloom s a)
forall s a. BloomSize -> Salt -> ST s (MBloom s a)
new BloomSize
bloomsize Salt
bloomsalt
MBloom s a -> ST s ()
forall s. MBloom s a -> ST s ()
body MBloom s a
mb
MBloom s a -> ST s (Bloom a)
forall s a. MBloom s a -> ST s (Bloom a)
unsafeFreeze MBloom s a
mb
insert :: Hashable a => MBloom s a -> a -> ST s ()
insert :: forall a s. Hashable a => MBloom s a -> a -> ST s ()
insert !MBloom s a
mb !a
x = MBloom s a -> Hashes a -> ST s ()
forall s a. MBloom s a -> Hashes a -> ST s ()
insertHashes MBloom s a
mb (Salt -> a -> Hashes a
forall a. Hashable a => Salt -> a -> Hashes a
hashesWithSalt (MBloom s a -> Salt
forall s a. MBloom s a -> Salt
mbHashSalt MBloom s a
mb) a
x)
elem :: Hashable a => a -> Bloom a -> Bool
elem :: forall a. Hashable a => a -> Bloom a -> Bool
elem = \ !a
x !Bloom a
b -> Bloom a -> Hashes a -> Bool
forall a. Bloom a -> Hashes a -> Bool
elemHashes Bloom a
b (Salt -> a -> Hashes a
forall a. Hashable a => Salt -> a -> Hashes a
hashesWithSalt (Bloom a -> Salt
forall a. Bloom a -> Salt
hashSalt Bloom a
b) a
x)
(?) :: Hashable a => Bloom a -> a -> Bool
? :: forall a. Hashable a => Bloom a -> a -> Bool
(?) = (a -> Bloom a -> Bool) -> Bloom a -> a -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> Bloom a -> Bool
forall a. Hashable a => a -> Bloom a -> Bool
elem
notElem :: Hashable a => a -> Bloom a -> Bool
notElem :: forall a. Hashable a => a -> Bloom a -> Bool
notElem = \ a
x Bloom a
b -> Bool -> Bool
not (a
x a -> Bloom a -> Bool
forall a. Hashable a => a -> Bloom a -> Bool
`elem` Bloom a
b)
read :: Hashable a => MBloom s a -> a -> ST s Bool
read :: forall a s. Hashable a => MBloom s a -> a -> ST s Bool
read !MBloom s a
mb !a
x = MBloom s a -> Hashes a -> ST s Bool
forall s a. MBloom s a -> Hashes a -> ST s Bool
readHashes MBloom s a
mb (Salt -> a -> Hashes a
forall a. Hashable a => Salt -> a -> Hashes a
hashesWithSalt (MBloom s a -> Salt
forall s a. MBloom s a -> Salt
mbHashSalt MBloom s a
mb) a
x)
unfold :: forall a b.
Hashable a
=> BloomSize
-> Salt
-> (b -> Maybe (a, b))
-> b
-> Bloom a
{-# INLINE unfold #-}
unfold :: forall a b.
Hashable a =>
BloomSize -> Salt -> (b -> Maybe (a, b)) -> b -> Bloom a
unfold BloomSize
bloomsize Salt
bloomsalt b -> Maybe (a, b)
f b
k =
BloomSize -> Salt -> (forall s. MBloom s a -> ST s ()) -> Bloom a
forall a.
BloomSize -> Salt -> (forall s. MBloom s a -> ST s ()) -> Bloom a
create BloomSize
bloomsize Salt
bloomsalt MBloom s a -> ST s ()
forall s. MBloom s a -> ST s ()
body
where
body :: forall s. MBloom s a -> ST s ()
body :: forall s. MBloom s a -> ST s ()
body MBloom s a
mb = b -> ST s ()
loop b
k
where
loop :: b -> ST s ()
loop :: b -> ST s ()
loop !b
j = case b -> Maybe (a, b)
f b
j of
Maybe (a, b)
Nothing -> () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just (a
a, b
j') -> MBloom s a -> a -> ST s ()
forall a s. Hashable a => MBloom s a -> a -> ST s ()
insert MBloom s a
mb a
a ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> b -> ST s ()
loop b
j'
{-# INLINEABLE fromList #-}
fromList :: (Foldable t, Hashable a)
=> BloomPolicy
-> Salt
-> t a
-> Bloom a
fromList :: forall (t :: * -> *) a.
(Foldable t, Hashable a) =>
BloomPolicy -> Salt -> t a -> Bloom a
fromList BloomPolicy
policy Salt
bsalt t a
xs =
BloomSize -> Salt -> (forall s. MBloom s a -> ST s ()) -> Bloom a
forall a.
BloomSize -> Salt -> (forall s. MBloom s a -> ST s ()) -> Bloom a
create BloomSize
bsize Salt
bsalt (\MBloom s a
b -> (a -> ST s ()) -> t a -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (MBloom s a -> a -> ST s ()
forall a s. Hashable a => MBloom s a -> a -> ST s ()
insert MBloom s a
b) t a
xs)
where
bsize :: BloomSize
bsize = BloomPolicy -> NumEntries -> BloomSize
sizeForPolicy BloomPolicy
policy (t a -> NumEntries
forall a. t a -> NumEntries
forall (t :: * -> *) a. Foldable t => t a -> NumEntries
length t a
xs)
{-# SPECIALISE deserialise :: BloomSize
-> Salt
-> (MutableByteArray RealWorld -> Int -> Int -> IO ())
-> IO (Bloom a) #-}
deserialise :: PrimMonad m
=> BloomSize
-> Salt
-> (MutableByteArray (PrimState m) -> Int -> Int -> m ())
-> m (Bloom a)
deserialise :: forall (m :: * -> *) a.
PrimMonad m =>
BloomSize
-> Salt
-> (MutableByteArray (PrimState m)
-> NumEntries -> NumEntries -> m ())
-> m (Bloom a)
deserialise BloomSize
bloomsalt Salt
bloomsize MutableByteArray (PrimState m) -> NumEntries -> NumEntries -> m ()
fill = do
MBloom (PrimState m) a
mbloom <- ST (PrimState m) (MBloom (PrimState m) a)
-> m (MBloom (PrimState m) a)
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) (MBloom (PrimState m) a)
-> m (MBloom (PrimState m) a))
-> ST (PrimState m) (MBloom (PrimState m) a)
-> m (MBloom (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ BloomSize -> Salt -> ST (PrimState m) (MBloom (PrimState m) a)
forall s a. BloomSize -> Salt -> ST s (MBloom s a)
new BloomSize
bloomsalt Salt
bloomsize
MBloom (PrimState m) a
-> (MutableByteArray (PrimState m)
-> NumEntries -> NumEntries -> m ())
-> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MBloom (PrimState m) a
-> (MutableByteArray (PrimState m)
-> NumEntries -> NumEntries -> m ())
-> m ()
Internal.deserialise MBloom (PrimState m) a
mbloom MutableByteArray (PrimState m) -> NumEntries -> NumEntries -> m ()
fill
ST (PrimState m) (Bloom a) -> m (Bloom a)
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) (Bloom a) -> m (Bloom a))
-> ST (PrimState m) (Bloom a) -> m (Bloom a)
forall a b. (a -> b) -> a -> b
$ MBloom (PrimState m) a -> ST (PrimState m) (Bloom a)
forall s a. MBloom s a -> ST s (Bloom a)
unsafeFreeze MBloom (PrimState m) a
mbloom