bloomfilter 1.0 → 1.0.1
raw patch · 5 files changed
+27/−8 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.BloomFilter: notElemB :: a -> Bloom a -> Bool
+ Data.BloomFilter.Easy: notElemB :: a -> Bloom a -> Bool
Files
- Data/BloomFilter.hs +8/−0
- Data/BloomFilter/Easy.hs +2/−1
- bloomfilter.cabal +1/−1
- examples/SpellChecker.hs +2/−4
- examples/Words.hs +14/−2
Data/BloomFilter.hs view
@@ -49,6 +49,7 @@ -- ** Accessors , lengthB , elemB+ , notElemB -- * Mutable Bloom filters -- ** Creation@@ -219,6 +220,13 @@ elemB elt ub = all test (hashesU ub elt) where test (off :* bit) = (bitArrayB ub `unsafeAt` off) .&. (1 `shiftL` bit) /= 0 +-- | Query an immutable Bloom filter for non-membership. If the value+-- /is/ present, return @False@. If the value is not present, there+-- is /still/ some possibility that @False@ will be returned.+notElemB :: a -> Bloom a -> Bool+notElemB elt ub = any test (hashesU ub elt)+ where test (off :* bit) = (bitArrayB ub `unsafeAt` off) .&. (1 `shiftL` bit) == 0+ -- | Create an immutable Bloom filter from a mutable one. The mutable -- filter /must not/ be modified afterwards, or a runtime crash may -- occur. For a safer creation interface, use 'createB'.
Data/BloomFilter/Easy.hs view
@@ -17,6 +17,7 @@ Bloom , easyList , elemB+ , notElemB , lengthB -- ** Example: a spell checker@@ -26,7 +27,7 @@ , suggestSizing ) where -import Data.BloomFilter (Bloom, elemB, fromListB, lengthB)+import Data.BloomFilter (Bloom, elemB, fromListB, lengthB, notElemB) import Data.BloomFilter.Hash (Hashable, cheapHashes) import Data.BloomFilter.Util (nextPowerOfTwo) import qualified Data.ByteString as SB
bloomfilter.cabal view
@@ -1,5 +1,5 @@ name: bloomfilter-version: 1.0+version: 1.0.1 license: BSD3 license-file: LICENSE author: Bryan O'Sullivan <bos@serpentine.com>
examples/SpellChecker.hs view
@@ -1,7 +1,5 @@-import Data.BloomFilter.Easy (easyList, elemB)+import Data.BloomFilter.Easy (easyList, notElemB) main = do filt <- (easyList 0.01 . words) `fmap` readFile "/usr/share/dict/words"- let check word | word `elemB` filt = ""- | otherwise = word ++ "\n"- interact (concat . map check . lines)+ interact (unlines . filter (`notElemB` filt) . lines)
examples/Words.hs view
@@ -3,11 +3,23 @@ -- queries it exhaustively. import Control.Monad (forM_, mapM_)-import Data.BloomFilter.Easy (easyList, elemB, lengthB)+import Data.BloomFilter (Bloom, fromListB, elemB, lengthB)+import Data.BloomFilter.Hash (cheapHashes)+import Data.BloomFilter.Easy (easyList, suggestSizing) import qualified Data.ByteString.Char8 as B import Data.Time.Clock (diffUTCTime, getCurrentTime) import System.Environment (getArgs) +conservative, aggressive :: Double -> [B.ByteString] -> Bloom B.ByteString+conservative = easyList++aggressive fpr xs+ = let (size, numHashes) = suggestSizing (length xs) fpr+ k = 3+ in fromListB (cheapHashes (numHashes - k)) (size * k) xs++testFunction = aggressive+ main = do args <- getArgs let files | null args = ["/usr/share/dict/words"]@@ -18,7 +30,7 @@ putStrLn $ {-# SCC "words/length" #-} show (length words) ++ " words" b <- getCurrentTime putStrLn $ show (diffUTCTime b a) ++ "s to count words"- let filt = {-# SCC "construct" #-} easyList 0.01 words+ let filt = {-# SCC "construct" #-} testFunction 0.01 words print filt c <- getCurrentTime putStrLn $ show (diffUTCTime c b) ++ "s to construct filter"