module Data.Vector.Bloom.Mutable
(
MBloom(MBloom)
, mbloom
, hashes
, width
, insert
) where
import Control.Monad.Primitive
import Control.Monad.ST
import Data.Bits
import Data.Typeable
import Data.Foldable (forM_)
import Data.Hashable
import Data.Vector.Bloom.Util
import qualified Data.Vector.Unboxed.Mutable as UM
import Data.Word
data MBloom s = MBloom
{ hashes :: !Int
, _mask :: !Int
, _bits :: !(UM.MVector s Word64)
} deriving Typeable
mbloom :: Int -> Int -> ST s (MBloom s)
mbloom k m0 = do
let m1 = m0 .|. unsafeShiftR m0 1
let m2 = m1 .|. unsafeShiftR m1 2
let m3 = m2 .|. unsafeShiftR m2 4
let m4 = m3 .|. unsafeShiftR m3 8
let m5 = m4 .|. unsafeShiftR m4 16
let m6 = m5 .|. shiftR m5 32
v <- UM.replicate (unsafeShiftR m6 6 + 1) 0
return $ MBloom k m6 v
width :: MBloom s -> Int
width (MBloom _ m _) = m + 1
insert :: (PrimMonad m, Hashable a) => a -> MBloom (PrimState m) -> m ()
insert a (MBloom k m bs)
| m > 32767, h:hs <- rehash k a, p <- unsafeShiftL h 15 = forM_ hs $ \i -> do
let !im = (p + (i.&.32767)) .&. m
let !iw = unsafeShiftR im 6
w <- UM.unsafeRead bs iw
UM.unsafeWrite bs iw $ setBit w (im .&. 63)
| otherwise = forM_ (rehash k a) $ \ i -> do
let !im = i .&. m
let !iw = unsafeShiftR im 6
w <- UM.unsafeRead bs iw
UM.unsafeWrite bs iw $ setBit w (im .&. 63)