From d584395685e11da7ae5f9b29a47eb9700526f380 Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Mon, 29 Sep 2025 16:39:05 +0200 Subject: [PATCH] Tests: Reverse bits during key generation This should result in more HashMap trees of full height (13 levels on 64-bit systems) being generated. Fixes #502. --- tests/Util/Key.hs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/Util/Key.hs b/tests/Util/Key.hs index 9088d110..0a375066 100644 --- a/tests/Util/Key.hs +++ b/tests/Util/Key.hs @@ -1,5 +1,6 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE MagicHash #-} {-# LANGUAGE TypeApplications #-} module Util.Key (Key(..), keyToInt, incKey, collisionAtHash) where @@ -7,6 +8,7 @@ module Util.Key (Key(..), keyToInt, incKey, collisionAtHash) where import Data.Bits (bit, (.&.)) import Data.Hashable (Hashable (hashWithSalt)) import Data.Word (Word16) +import GHC.Exts (Int (..), bitReverse#, int2Word#, word2Int#) import GHC.Generics (Generic) import Test.QuickCheck (Arbitrary (..), CoArbitrary (..), Function, Gen, Large) @@ -51,8 +53,8 @@ arbitraryHash = do , (1, QC.elements [-1, 0xFF, 0xFFF]) ] i <- QC.frequency gens - moreCollisions' <- QC.elements [moreCollisions, id] - pure (moreCollisions' i) + transform <- QC.elements [id, moreCollisions, bitReverse] + pure (transform i) -- | Mask out most bits to produce more collisions moreCollisions :: Int -> Int @@ -62,6 +64,11 @@ moreCollisions w = fromIntegral (w .&. moreCollisionsMask) moreCollisionsMask :: Int moreCollisionsMask = sum [bit n | n <- [0, 3, 8, 14, 61]] +-- | Reverse order of bits, in order to generate variation in the +-- high bits, resulting in HashMap trees of greater height. +bitReverse :: Int -> Int +bitReverse (I# i) = I# (word2Int# (bitReverse# (int2Word# i))) + keyToInt :: Key -> Int keyToInt (K h x) = h * fromEnum x