Skip to content

Instantly share code, notes, and snippets.

@gregorycollins
Created June 10, 2013 12:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gregorycollins/5748445 to your computer and use it in GitHub Desktop.
Save gregorycollins/5748445 to your computer and use it in GitHub Desktop.
Minimal failing test suite for hashable 1.2.0.7
name: hashable-is-broken
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.10
executable hashable-is-broken
main-is: Main.hs
build-depends: base == 4.5.*,
bytestring,
hashable == 1.2.0.7,
containers
default-language: Haskell2010
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
import Control.Monad (forM_)
import Data.Bits
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as S
import Data.Hashable (hash)
import Data.List (foldl', intercalate)
import qualified Data.Map as Map
import System.Info
import Text.Printf
------------------------------------------------------------------------------
-- A 10MB string
seedString :: ByteString
seedString = S.replicate 10000000 'a'
{-# NOINLINE seedString #-}
------------------------------------------------------------------------------
chopEvery :: Int -> ByteString -> [ByteString]
chopEvery n = go id
where
go dl s | S.null s = dl []
| otherwise = let (x, y) = S.splitAt n s
dl' = dl . (x :)
in go dl' y
------------------------------------------------------------------------------
pad :: Int -> String -> String
pad n s = if l >= n then s else s ++ b
where
l = length s
b = replicate (n - l) ' '
------------------------------------------------------------------------------
testChop :: Int -> IO ()
testChop n = analyse $! foldl' f Map.empty $ chopEvery n seedString
where
f !mp !s = let !h = hash s
in Map.insertWith' (+) h (1::Int) mp
prefix = "Chop " ++ show n
analyse mp | Map.size mp == 1 = putStrLn $ prefix ++ ": ok"
| otherwise = dumpFailure mp
dumpFailure mp = do
putStrLn $ prefix ++ ": FAILURE!"
putStrLn $ pad 18 "hashcode" ++ "count of occurrences"
forM_ (Map.toList mp) $ \(k,v) -> do
let a = printf "%016x" k
putStrLn $ pad 18 a ++ show v
------------------------------------------------------------------------------
printInfo :: IO ()
printInfo = putStrLn $ intercalate " " [ compilerName, show compilerVersion
, os , arch]
------------------------------------------------------------------------------
main :: IO ()
main = do
printInfo
forM_ [2..21] testChop
@gregorycollins
Copy link
Author

Sample output from my machine:

ghc Version {versionBranch = [7,4], versionTags = []} darwin x86_64
Chop 2: ok
Chop 3: FAILURE!
hashcode          count of occurrences
6aa49c10f6b04bf7  1
73d91e1735e567c3  3333333
Chop 4: ok
Chop 5: ok
Chop 6: FAILURE!
hashcode          count of occurrences
c68a8f643b763d6e  1
f3101af280323ed2  1666666
Chop 7: FAILURE!
hashcode          count of occurrences
d8d6323f3c945052  1428571
73d91e1735e567c3  1
Chop 8: ok
Chop 9: FAILURE!
hashcode          count of occurrences
a125b0dceddbb808  1111111
6aa49c10f6b04bf7  1
Chop 10: ok
Chop 11: FAILURE!
hashcode          count of occurrences
d9b68e5a1667ee11  1
2ccc7c40de079a55  909090
Chop 12: FAILURE!
hashcode          count of occurrences
c68a8f643b763d6e  1
e5363f87774972d0  833333
Chop 13: FAILURE!
hashcode          count of occurrences
d9b68e5a1667ee11  1
fce12f0ab88cf35b  769230
Chop 14: FAILURE!
hashcode          count of occurrences
d9b68e5a1667ee11  1
45a579294211e193  714285
Chop 15: FAILURE!
hashcode          count of occurrences
d9b68e5a1667ee11  1
dd88b3e3f1285d2e  666666
Chop 16: ok
Chop 17: FAILURE!
hashcode          count of occurrences
a3a2f9e6a6c3a713  1
3cda913e42f2ef0f  588235
Chop 18: FAILURE!
hashcode          count of occurrences
d9b68e5a1667ee11  1
fe5edf0cd75fdb12  555555
Chop 19: FAILURE!
hashcode          count of occurrences
d5e3922e409d39b4  526315
dd88b3e3f1285d2e  1
Chop 20: ok
Chop 21: FAILURE!
hashcode          count of occurrences
d9b68e5a1667ee11  1
ee94e80df517e35c  476190

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment