packages feed

bloomfilter-redis 0.1.0.0 → 0.1.0.1

raw patch · 6 files changed

+38/−21 lines, 6 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Data.RedisBloom: querySafeBF :: (Applicative f, MonadRedis m, RedisCtx m f) => Bloom a -> a -> m (f Bool)
- Data.RedisBloom.Hash.FNV: fnvPrime :: (Num a, FiniteBits a) => a
+ Data.RedisBloom.Hash.FNV: fnvPrime :: forall a. (Num a, FiniteBits a) => a
- Data.RedisBloom.Suggestions: suggestCapacity :: (Integral a, RealFrac b, Floating b) => a -> b -> Capacity
+ Data.RedisBloom.Suggestions: suggestCapacity :: forall a b. (Integral a, RealFrac b, Floating b) => a -> b -> Capacity
- Data.RedisBloom.Suggestions: suggestHashCount :: (Integral a) => a -> Capacity -> HashCount
+ Data.RedisBloom.Suggestions: suggestHashCount :: forall a. (Integral a) => a -> Capacity -> HashCount

Files

CHANGELOG.md view
@@ -1,3 +1,9 @@+0.1.0.1+------+* README improvements+* Compatibility with GHC 7.8/base-4.7+* Test suite improvements+ 0.1.0.0 ------ Initial release
README.md view
@@ -1,9 +1,11 @@+# bloomfilter-redis [![Build Status](https://travis-ci.org/hesiod/bloomfilter-redis.svg?branch=master)](https://travis-ci.org/hesiod/bloomfilter-redis)+ Distributed bloom filters on Redis (using the Hedis client).  The hash family algorithm is partly inspired by [Brian O'Sullivan's bloomfilter package](https://hackage.haskell.org/package/bloomfilter). -# Features+## Features  * Implementation of the FNV-1/FNV-1a hash function is included * Automatic derivation of a hash family from a single hash function@@ -13,7 +15,7 @@ * Every `Hashable` type can be added to the bloom filter * Every `Binary` type can be hashed -# Benchmark and Testing suite+## Benchmark and Testing suite  A benchmark for the FNV hash function is included and can be invoked using `cabal bench` or `stack bench`.@@ -21,15 +23,15 @@  A testing suite using `tasty` is included. -# Further Information-## Todo+## Further Information+### Todo  * Separate the FNV hash function into a separate package * The actual operations (`addBF`, `queryBF`, etc) should   ideally live in a `MonadReader (Bloom a)`, but this requires   some work on the Hedis side because of `RedisCtx` -## Caveats+### Caveats  * The only supported FNV hash sizes are 32 and 64 bits.   Support for larger widths is a matter of having a
bloomfilter-redis.cabal view
@@ -1,5 +1,5 @@ name:                bloomfilter-redis-version:             0.1.0.0+version:             0.1.0.1 synopsis:            Distributed bloom filters on Redis (using the Hedis client). description:   Distributed bloom filters on Redis (using the Hedis client).
src/Data/RedisBloom.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE CPP #-} {-# LANGUAGE Trustworthy #-} @@ -11,7 +12,7 @@      -- ** Static bloom filter configuration      Bloom(..),      -- * Bloom filter operations-     createBF, createIfNewBF, addBF, queryBF+     createBF, createIfNewBF, addBF, queryBF, querySafeBF     ) where  #if !MIN_VERSION_base(4,8,0)@@ -57,26 +58,28 @@       (Capacity cap) = capacity bf       one = pack "1" -getBit :: (MonadRedis m, RedisCtx m (Either Reply)) => Bloom a -> Integer -> m Bool+getBit :: forall m f a. (Functor f, MonadRedis m, RedisCtx m f) => Bloom a -> Integer -> m (f Bool) getBit bf i = do   r <- getbit (key bf) i-  let l = case r of-             Left _ -> False-             Right j -> j >= 1-  return l+  return . fmap (>= 1) $ (r :: f Integer)  -- | Query whether an element exists in the bloom filter.+querySafeBF :: (Applicative f, MonadRedis m, RedisCtx m f) => Bloom a -> a -> m (f Bool)+querySafeBF bf = query (capacity bf) (getBit bf) (hf bf)++-- | Query whether an element exists in the bloom filter. -- -- Gracefully fails upon failure by returning 'False'. queryBF :: (MonadRedis m, RedisCtx m (Either Reply)) => Bloom a -> a -> m Bool-queryBF bf = query (capacity bf) (getBit bf) (hf bf)+queryBF bf = fmap (either (const False) id) . query (capacity bf) (getBit bf) (hf bf) -query :: Monad m => Capacity -> (Integer -> m Bool) -> HashFamily a -> a -> m Bool+query :: (Applicative f, Monad m) => Capacity -> (Integer -> m (f Bool)) -> HashFamily a -> a -> m (f Bool) query (Capacity c) q hashf x = do   let hashes = fmap (toInteger . (`mod` c) . fromIntegral) . hashf $ x   lookupMany q hashes -lookupMany :: (Traversable t, Monad m) => (a -> m Bool) -> t a -> m Bool+lookupMany :: (Applicative f, Traversable t, Monad m) => (a -> m (f Bool)) -> t a -> m (f Bool) lookupMany lookupBit hashes = do   bools <- mapM lookupBit hashes-  return . getAll . foldMap All $ bools+  let b' = fmap (getAll . foldMap All) . sequenceA $ bools+  return b'
test/Common.hs view
@@ -5,6 +5,7 @@  #if !MIN_VERSION_base(4,8,0) import Prelude hiding (mapM, mapM_)+import Data.Foldable (Foldable(..), mapM_) import Data.Traversable (Traversable(..)) #endif import Data.Hashable@@ -27,7 +28,7 @@  createAddQuery :: Hashable a => Bloom a -> a -> Redis Bool createAddQuery b x = createBF b >> addBF b x >> queryBF b x-createAddL :: (Hashable a, Traversable t) => Bloom a -> t a -> Redis ()+createAddL :: (Hashable a, Foldable t) => Bloom a -> t a -> Redis () createAddL b l = createBF b >> mapM_ (addBF b) l queryL :: (Hashable a, Traversable t) => Bloom a -> t a -> Redis (t Bool) queryL b = mapM (queryBF b)
test/TestBloom.hs view
@@ -1,3 +1,12 @@+{-# LANGUAGE CPP #-}++#if !MIN_VERSION_base(4,8,0)+import Data.Foldable (foldMap)+#endif+import Data.List (nub)+import Data.Monoid (All(..))+import Data.Word (Word32, Word64)+ import Test.Tasty import Test.Tasty.Runners import Test.Tasty.Ingredients.Rerun@@ -5,11 +14,7 @@ import Test.Tasty.HUnit as HU hiding (assert) import Test.QuickCheck.Monadic -import Data.List (nub)-import Data.Monoid (All(..))-import Data.Word (Word32, Word64) import Database.Redis- import Data.RedisBloom import Data.RedisBloom.Hash.FNV import Data.RedisBloom.Suggestions