From 76b0a522daa8ed65b7de196fb6f46b58846f3b41 Mon Sep 17 00:00:00 2001 From: Andrew Gibiansky Date: Sat, 25 Jul 2015 21:47:36 -0700 Subject: [PATCH 1/3] Adding unsafeCreate to allow for deserialization of Bloom filters. --- Data/BloomFilter.hs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Data/BloomFilter.hs b/Data/BloomFilter.hs index 2210cef..99ff62d 100644 --- a/Data/BloomFilter.hs +++ b/Data/BloomFilter.hs @@ -106,6 +106,17 @@ instance NFData (Bloom a) where logBitsInHash :: Int logBitsInHash = 5 -- logPower2 bitsInHash +-- | Create an immutable Bloom filter from the underlying bit array. +-- This creates a valid Bloom filter if and only if the arguments passed to +-- @unsafeCreate@ are the same as those that were passed to @create@ or @new@ for the original Bloom filter. +unsafeCreate :: (a -> [Hash]) -- ^ family of hash functions to use + -> Int -- ^ number of bits in filter + -> UArray Int Hash -- ^ Underlying bit array. + -> Bloom a +unsafeCreate hash numBits bits = + (create hash numBits (\_ -> return ())) { bitArray = bits } + + -- | Create an immutable Bloom filter, using the given setup function -- which executes in the 'ST' monad. -- From 556d076b94ec6c24c4a591e062ba61de7e9076dc Mon Sep 17 00:00:00 2001 From: Andrew Gibiansky Date: Sat, 25 Jul 2015 22:09:50 -0700 Subject: [PATCH 2/3] Export unsafeCreate --- Data/BloomFilter.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/Data/BloomFilter.hs b/Data/BloomFilter.hs index 99ff62d..2890acd 100644 --- a/Data/BloomFilter.hs +++ b/Data/BloomFilter.hs @@ -70,6 +70,7 @@ module Data.BloomFilter -- | The raw bit array used by the immutable 'Bloom' type. , bitArray + , unsafeCreate ) where import Control.Monad (liftM, forM_) From 77ecea115faa7b937cec6aa93d4164bcf79ad3c6 Mon Sep 17 00:00:00 2001 From: Andrew Gibiansky Date: Sun, 26 Jul 2015 12:10:58 -0700 Subject: [PATCH 3/3] Trying again --- Data/BloomFilter.hs | 32 ++++++++++++++++++++------------ bloomfilter.cabal | 1 + 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Data/BloomFilter.hs b/Data/BloomFilter.hs index 2890acd..d4b324e 100644 --- a/Data/BloomFilter.hs +++ b/Data/BloomFilter.hs @@ -70,7 +70,8 @@ module Data.BloomFilter -- | The raw bit array used by the immutable 'Bloom' type. , bitArray - , unsafeCreate + , serialize + , unsafeDeserialize ) where import Control.Monad (liftM, forM_) @@ -86,6 +87,9 @@ import qualified Data.BloomFilter.Mutable.Internal as MB import Data.BloomFilter.Mutable.Internal (Hash, MBloom) import Data.Word (Word32) +import Data.Serialize +import Data.ByteString (ByteString) + import Prelude hiding (elem, length, notElem, (/), (*), div, divMod, mod, rem) @@ -107,17 +111,6 @@ instance NFData (Bloom a) where logBitsInHash :: Int logBitsInHash = 5 -- logPower2 bitsInHash --- | Create an immutable Bloom filter from the underlying bit array. --- This creates a valid Bloom filter if and only if the arguments passed to --- @unsafeCreate@ are the same as those that were passed to @create@ or @new@ for the original Bloom filter. -unsafeCreate :: (a -> [Hash]) -- ^ family of hash functions to use - -> Int -- ^ number of bits in filter - -> UArray Int Hash -- ^ Underlying bit array. - -> Bloom a -unsafeCreate hash numBits bits = - (create hash numBits (\_ -> return ())) { bitArray = bits } - - -- | Create an immutable Bloom filter, using the given setup function -- which executes in the 'ST' monad. -- @@ -332,6 +325,21 @@ logPower2 k = go 0 k where go j 1 = j go j n = go (j+1) (n `shiftR` 1) +serialize :: Bloom a -> ByteString +serialize bloom = encode (shift bloom, mask bloom, bitArray bloom) + +unsafeDeserialize :: (a -> [Hash]) -> ByteString -> Either String (Bloom a) +unsafeDeserialize hashes bs = + case decode bs of + Left err -> Left err + Right (shift, mask, bitArray) -> Right $ B + { hashes = hashes + , shift = shift + , mask = mask + , bitArray = bitArray + } + + -- $overview -- -- Each of the functions for creating Bloom filters accepts two parameters: diff --git a/bloomfilter.cabal b/bloomfilter.cabal index 821a5d7..6cd6107 100644 --- a/bloomfilter.cabal +++ b/bloomfilter.cabal @@ -20,6 +20,7 @@ library array, base >= 4.4 && < 5, bytestring >= 0.9, + cereal >= 0.4, deepseq exposed-modules: Data.BloomFilter Data.BloomFilter.Easy