1
1
{-# LANGUAGE DeriveAnyClass #-}
2
2
{-# LANGUAGE DeriveGeneric #-}
3
+ {-# LANGUAGE MagicHash #-}
3
4
{-# LANGUAGE TypeApplications #-}
4
5
5
6
module Util.Key (Key (.. ), keyToInt , incKey , collisionAtHash ) where
6
7
7
8
import Data.Bits (bit , (.&.) )
8
9
import Data.Hashable (Hashable (hashWithSalt ))
9
10
import Data.Word (Word16 )
11
+ import GHC.Exts (Int (.. ), bitReverse #, int2Word #, word2Int #)
10
12
import GHC.Generics (Generic )
11
13
import Test.QuickCheck (Arbitrary (.. ), CoArbitrary (.. ), Function , Gen , Large )
12
14
@@ -51,8 +53,8 @@ arbitraryHash = do
51
53
, (1 , QC. elements [- 1 , 0xFF , 0xFFF ])
52
54
]
53
55
i <- QC. frequency gens
54
- moreCollisions' <- QC. elements [moreCollisions, id ]
55
- pure (moreCollisions' i)
56
+ transform <- QC. elements [id , moreCollisions, bitReverse ]
57
+ pure (transform i)
56
58
57
59
-- | Mask out most bits to produce more collisions
58
60
moreCollisions :: Int -> Int
@@ -62,6 +64,11 @@ moreCollisions w = fromIntegral (w .&. moreCollisionsMask)
62
64
moreCollisionsMask :: Int
63
65
moreCollisionsMask = sum [bit n | n <- [0 , 3 , 8 , 14 , 61 ]]
64
66
67
+ -- | Reverse order of bits, in order to generate variation in the
68
+ -- high bits, resulting in HashMap trees of greater height.
69
+ bitReverse :: Int -> Int
70
+ bitReverse (I # i) = I # (word2Int# (bitReverse# (int2Word# i)))
71
+
65
72
keyToInt :: Key -> Int
66
73
keyToInt (K h x) = h * fromEnum x
67
74
0 commit comments