Skip to content

Commit cf80d47

Browse files
committed
refactor(bloomfilter): abstract over hashes with Hasher type class
1 parent 08445e8 commit cf80d47

File tree

4 files changed

+46
-19
lines changed

4 files changed

+46
-19
lines changed

bloomfilter/src/Data/BloomFilter/Blocked.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ module Data.BloomFilter.Blocked (
6565

6666
-- * Low level variants
6767
Hashes,
68-
hashes,
68+
Hasher(hashes),
6969
insertHashes,
7070
elemHashes,
7171
-- ** Prefetching
@@ -114,14 +114,14 @@ create bloomsalt bloomsize body =
114114
-- | Insert a value into a mutable Bloom filter. Afterwards, a
115115
-- membership query for the same value is guaranteed to return @True@.
116116
insert :: Hashable a => MBloom s a -> a -> ST s ()
117-
insert = \ !mb !x -> insertHashes mb (hashes (mbHashSalt mb) x)
117+
insert = \ !mb !x -> insertHashes mb (hashes mb x)
118118

119119
{-# INLINE elem #-}
120120
-- | Query an immutable Bloom filter for membership. If the value is
121121
-- present, return @True@. If the value is not present, there is
122122
-- /still/ some possibility that @True@ will be returned.
123123
elem :: Hashable a => a -> Bloom a -> Bool
124-
elem = \ !x !b -> elemHashes b (hashes (hashSalt b) x)
124+
elem = \ !x !b -> elemHashes b (hashes b x)
125125

126126
-- | Same as 'elem' but with the opposite argument order:
127127
--
@@ -241,7 +241,7 @@ insertMany bloom key n =
241241
prepareProbes !i !i_w
242242
| i_w < 0x0f && i < n = do
243243
k <- key i
244-
let !kh = hashes (mbHashSalt bloom) k
244+
let !kh = hashes bloom k
245245
prefetchInsert bloom kh
246246
P.writePrimArray buf i_w kh
247247
prepareProbes (i+1) (i_w+1)
@@ -264,7 +264,7 @@ insertMany bloom key n =
264264
-- (from the read end of the buffer).
265265
| i < n = do
266266
k <- key i
267-
let !kh = hashes (mbHashSalt bloom) k
267+
let !kh = hashes bloom k
268268
prefetchInsert bloom kh
269269
P.writePrimArray buf i_w kh
270270
insertProbe

bloomfilter/src/Data/BloomFilter/Blocked/Internal.hs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
module Data.BloomFilter.Blocked.Internal (
1010
-- * Mutable Bloom filters
1111
MBloom,
12-
mbHashSalt,
1312
new,
1413
maxSizeBits,
1514

@@ -22,7 +21,7 @@ module Data.BloomFilter.Blocked.Internal (
2221
-- * Hash-based operations
2322
Hashes,
2423
Salt (Salt),
25-
hashes,
24+
Hasher (hashes),
2625
insertHashes,
2726
prefetchInsert,
2827
elemHashes,
@@ -44,7 +43,7 @@ import Control.Exception (assert)
4443
import Control.Monad.Primitive (PrimMonad, PrimState)
4544
import Control.Monad.ST (ST)
4645
import Data.Bits
47-
import Data.Kind (Type)
46+
import Data.Kind (Constraint, Type)
4847
import Data.Primitive.ByteArray
4948
import Data.Primitive.PrimArray
5049
import Data.Primitive.Types (Prim (..))
@@ -331,9 +330,23 @@ type role Hashes nominal
331330
newtype Salt = Salt Word64
332331
deriving stock (Eq, Show)
333332

334-
{-# INLINE hashes #-}
335-
hashes :: (Hashable a) => Salt -> a -> Hashes a
336-
hashes = \ (Salt !salt) !x -> Hashes (hashSalt64 salt x)
333+
type Hasher :: (Type -> Type) -> Constraint
334+
class Hasher b where
335+
hashes :: (Hashable a) => b a -> a -> Hashes a
336+
337+
instance Hasher (MBloom s) where
338+
hashes :: (Hashable a) => MBloom s a -> a -> Hashes a
339+
hashes = \ !mb !x -> hashesWithSalt (mbHashSalt mb) x
340+
{-# INLINE hashes #-}
341+
342+
instance Hasher Bloom where
343+
hashes :: (Hashable a) => Bloom a -> a -> Hashes a
344+
hashes = \ !b !x -> hashesWithSalt (hashSalt b) x
345+
{-# INLINE hashes #-}
346+
347+
{-# INLINE hashesWithSalt #-}
348+
hashesWithSalt :: (Hashable a) => Salt -> a -> Hashes a
349+
hashesWithSalt = \ (Salt !salt) !x -> Hashes (hashSalt64 salt x)
337350

338351
{-# INLINE blockIxAndBitGen #-}
339352
-- | The scheme for turning 'Hashes' into block and bit indexes is as follows:

bloomfilter/src/Data/BloomFilter/Classic.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,13 @@ create bloomsalt bloomsize body =
115115
-- | Insert a value into a mutable Bloom filter. Afterwards, a
116116
-- membership query for the same value is guaranteed to return @True@.
117117
insert :: Hashable a => MBloom s a -> a -> ST s ()
118-
insert !mb !x = insertHashes mb (hashes (mbHashSalt mb) x)
118+
insert !mb !x = insertHashes mb (hashes mb x)
119119

120120
-- | Query an immutable Bloom filter for membership. If the value is
121121
-- present, return @True@. If the value is not present, there is
122122
-- /still/ some possibility that @True@ will be returned.
123123
elem :: Hashable a => a -> Bloom a -> Bool
124-
elem = \ !x !b -> elemHashes b (hashes (hashSalt b) x)
124+
elem = \ !x !b -> elemHashes b (hashes b x)
125125

126126
-- | Same as 'elem' but with the opposite argument order:
127127
--
@@ -144,7 +144,7 @@ notElem = \ x b -> not (x `elem` b)
144144
-- present, return @True@. If the value is not present, there is
145145
-- /still/ some possibility that @True@ will be returned.
146146
read :: Hashable a => MBloom s a -> a -> ST s Bool
147-
read !mb !x = readHashes mb (hashes (mbHashSalt mb) x)
147+
read !mb !x = readHashes mb (hashes mb x)
148148

149149
-- | Build an immutable Bloom filter from a seed value. The seeding
150150
-- function populates the filter as follows.

bloomfilter/src/Data/BloomFilter/Classic/Internal.hs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module Data.BloomFilter.Classic.Internal (
2121
-- * Hash-based operations
2222
Hashes,
2323
Salt (Salt),
24-
hashes,
24+
Hasher (hashes),
2525
insertHashes,
2626
elemHashes,
2727
readHashes,
@@ -42,7 +42,7 @@ import Control.Exception (assert)
4242
import Control.Monad.Primitive (PrimMonad, PrimState)
4343
import Control.Monad.ST (ST)
4444
import Data.Bits
45-
import Data.Kind (Type)
45+
import Data.Kind (Constraint, Type)
4646
import Data.Primitive.ByteArray
4747
import Data.Primitive.PrimArray
4848
import Data.Primitive.Types (Prim (..))
@@ -439,9 +439,23 @@ https://github.com/facebook/rocksdb/blob/096fb9b67d19a9a180e7c906b4a0cdb2b2d0c1f
439439
evalHashes :: Hashes a -> Int -> Hash
440440
evalHashes (Hashes h1 h2) i = h1 + (h2 `unsafeShiftR` i)
441441

442+
type Hasher :: (Type -> Type) -> Constraint
443+
class Hasher b where
444+
hashes :: (Hashable a) => b a -> a -> Hashes a
445+
446+
instance Hasher (MBloom s) where
447+
hashes :: (Hashable a) => MBloom s a -> a -> Hashes a
448+
hashes = \ !mb !x -> hashesWithSalt (mbHashSalt mb) x
449+
{-# INLINE hashes #-}
450+
451+
instance Hasher Bloom where
452+
hashes :: (Hashable a) => Bloom a -> a -> Hashes a
453+
hashes = \ !b !x -> hashesWithSalt (hashSalt b) x
454+
{-# INLINE hashes #-}
455+
442456
-- | Create 'Hashes' structure.
443457
--
444458
-- It's simply hashes the value twice using seed 0 and 1.
445-
hashes :: Hashable a => Salt -> a -> Hashes a
446-
hashes (Salt salt) v = Hashes (hashSalt64 salt v) (hashSalt64 (salt + 1) v)
447-
{-# INLINE hashes #-}
459+
hashesWithSalt :: Hashable a => Salt -> a -> Hashes a
460+
hashesWithSalt (Salt salt) v = Hashes (hashSalt64 salt v) (hashSalt64 (salt + 1) v)
461+
{-# INLINE hashesWithSalt #-}

0 commit comments

Comments
 (0)