packages feed

hashable 1.1.0.0 → 1.1.1.0

raw patch · 4 files changed

+74/−44 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Hashable: hashWithSalt :: Hashable a => Int -> a -> Int

Files

CHANGES view
@@ -1,9 +1,25 @@+Version 1.1.1.0++* Added hashWithSalt, which allows the user to create different hash+  values for the same input by providing different seeds.  This is+  useful for application like Cuckoo hashing which need a family of+  hash functions.++* Fixed a bug in the Hashable instance for Int64/Word64 on 32-bit+  platforms.++* Improved resilience to leading zero in the input being hashed.+ Version 1.1.0.0  * Added instance for: strict and lazy Texts, ThreadId+ * Added hashPtrWithSalt and hashByteArrayWithSalt.+ * Faster ByteArray# hashing.+ * Fixed a signedness bug that affected ByteString.+ * Fix ByteString hashing to work correctly on both 32 and 64-bit   platforms. 
Data/Hashable.hs view
@@ -8,7 +8,7 @@ --                (c) Johan Tibell 2011 --                (c) Bryan O'Sullivan 2011 -- License     :  BSD-style--- Maintainer  :  fox@ucw.cz+-- Maintainer  :  johan.tibell@gmail.com -- Stability   :  provisional -- Portability :  portable --@@ -65,7 +65,15 @@ ------------------------------------------------------------------------ -- * Computing hash values +-- | A default salt used in the default implementation of+-- 'hashWithSalt'.+defaultSalt :: Int+defaultSalt = 17+{-# INLINE defaultSalt #-}+ -- | The class of types that can be converted to a hash value.+--+-- Minimal implementation: 'hash' or 'hashWithSalt'. class Hashable a where     -- | Return a hash value for the argument.     --@@ -87,7 +95,20 @@     --    may improve the performance of hashing-based data     --    structures.     hash :: a -> Int+    hash = hashWithSalt defaultSalt +    -- | Return a hash value for the argument, using the given salt.+    --+    -- This method can be used to compute different hash values for+    -- the same input by providing a different salt in each+    -- application of the method.+    --+    -- The contract for 'hashWithSalt' is the same as for 'hash', with+    -- the additional requirement that any instance that defines+    -- 'hashWithSalt' must make use of the salt in its implementation.+    hashWithSalt :: Int -> a -> Int+    hashWithSalt salt x = salt `combine` hash x+ instance Hashable () where hash _ = 0  instance Hashable Bool where hash x = case x of { True -> 1; False -> 0 }@@ -98,7 +119,7 @@ instance Hashable Int32 where hash = fromIntegral instance Hashable Int64 where     hash n-        | bitSize n == 64 = fromIntegral n+        | bitSize (undefined :: Int) == 64 = fromIntegral n         | otherwise = fromIntegral (fromIntegral n `xor`                                    (fromIntegral n `shiftR` 32 :: Word64)) @@ -108,7 +129,7 @@ instance Hashable Word32 where hash = fromIntegral instance Hashable Word64 where     hash n-        | bitSize n == 64 = fromIntegral n+        | bitSize (undefined :: Int) == 64 = fromIntegral n         | otherwise = fromIntegral (n `xor` (n `shiftR` 32))  instance Hashable Char where hash = fromEnum@@ -122,38 +143,44 @@     hash (Right b) = 1 `combine` hash b  instance (Hashable a1, Hashable a2) => Hashable (a1, a2) where-    hash (a1, a2) = hash a1 `combine` hash a2+    hash (a1, a2) = defaultSalt `combine` hash a1 `combine` hash a2  instance (Hashable a1, Hashable a2, Hashable a3) => Hashable (a1, a2, a3) where-    hash (a1, a2, a3) = hash a1 `combine` hash a2 `combine` hash a3+    hash (a1, a2, a3) = defaultSalt `combine` hash a1 `combine` hash a2+                        `combine` hash a3  instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4) =>          Hashable (a1, a2, a3, a4) where-    hash (a1, a2, a3, a4) = hash a1 `combine` hash a2 `combine` hash a3-                            `combine` hash a4+    hash (a1, a2, a3, a4) = defaultSalt `combine` hash a1 `combine` hash a2+                            `combine` hash a3 `combine` hash a4  instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5)       => Hashable (a1, a2, a3, a4, a5) where     hash (a1, a2, a3, a4, a5) =-        hash a1 `combine` hash a2 `combine` hash a3 `combine` hash a4 `combine`-        hash a5+        defaultSalt `combine` hash a1 `combine` hash a2 `combine` hash a3+        `combine` hash a4 `combine` hash a5  instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5,           Hashable a6) => Hashable (a1, a2, a3, a4, a5, a6) where     hash (a1, a2, a3, a4, a5, a6) =-        hash a1 `combine` hash a2 `combine` hash a3 `combine` hash a4 `combine`-        hash a5 `combine` hash a6+        defaultSalt `combine` hash a1 `combine` hash a2 `combine` hash a3+        `combine` hash a4 `combine` hash a5 `combine` hash a6  instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5,           Hashable a6, Hashable a7) =>          Hashable (a1, a2, a3, a4, a5, a6, a7) where     hash (a1, a2, a3, a4, a5, a6, a7) =-        hash a1 `combine` hash a2 `combine` hash a3 `combine` hash a4 `combine`-        hash a5 `combine` hash a6 `combine` hash a7+        defaultSalt `combine` hash a1 `combine` hash a2 `combine` hash a3+        `combine` hash a4 `combine` hash a5 `combine` hash a6 `combine` hash a7 +-- | Default salt for hashing string like types.+stringSalt :: Int+stringSalt = 5381+ instance Hashable a => Hashable [a] where     {-# SPECIALIZE instance Hashable [Char] #-}-    hash = foldl' hashAndCombine 0+    hash = foldl' hashAndCombine stringSalt+    hashWithSalt = foldl' hashAndCombine  -- | Compute the hash of a ThreadId.  For GHC, we happen to know a -- trick to make this fast.@@ -178,38 +205,25 @@               B.unsafeUseAsCStringLen bs $ \(p, len) ->               hashPtr p (fromIntegral len) --- The arguments to this function are flipped to make the function--- easier to use with a left fold.---- | Compute a hash value for this 'B.ByteString', using an initial--- salt.-hashByteStringWithSalt :: Int           -- ^ salt-                       -> B.ByteString  -- ^ data to hash-                       -> Int           -- ^ hash value-hashByteStringWithSalt salt bs =-    B.inlinePerformIO $ B.unsafeUseAsCStringLen bs $ \(p, len) ->-    hashPtrWithSalt p (fromIntegral len) salt+    hashWithSalt salt bs = B.inlinePerformIO $+                           B.unsafeUseAsCStringLen bs $ \(p, len) ->+                           hashPtrWithSalt p (fromIntegral len) salt  instance Hashable BL.ByteString where-    hash = BL.foldlChunks hashByteStringWithSalt 0+    hash = BL.foldlChunks hashWithSalt stringSalt+    hashWithSalt = BL.foldlChunks hashWithSalt  instance Hashable T.Text where     hash (T.Text arr off len) = hashByteArray (TA.aBA arr)                                 (off `shiftL` 1) (len `shiftL` 1) --- The arguments to this function are flipped to make the function--- easier to use with a left fold.---- | Compute a hash value for this 'B.Text', using an initial--- salt.-hashTextWithSalt :: Int     -- ^ salt-                 -> T.Text  -- ^ data to hash-                 -> Int     -- ^ hash value-hashTextWithSalt salt (T.Text arr off len) =-    hashByteArrayWithSalt (TA.aBA arr) (off `shiftL` 1) (len `shiftL` 1) salt+    hashWithSalt salt (T.Text arr off len) =+        hashByteArrayWithSalt (TA.aBA arr) (off `shiftL` 1) (len `shiftL` 1)+        salt  instance Hashable LT.Text where-    hash = LT.foldlChunks hashTextWithSalt 0+    hash = LT.foldlChunks hashWithSalt stringSalt+    hashWithSalt = LT.foldlChunks hashWithSalt  ------------------------------------------------------------------------ -- * Creating new instances@@ -250,7 +264,7 @@ hashPtr :: Ptr a      -- ^ pointer to the data to hash         -> Int        -- ^ length, in bytes         -> IO Int     -- ^ hash value-hashPtr p len = hashPtrWithSalt p len 0+hashPtr p len = hashPtrWithSalt p len stringSalt  -- | Compute a hash value for the content of this pointer, using an -- initial salt.@@ -277,7 +291,7 @@               -> Int         -- ^ offset, in bytes               -> Int         -- ^ length, in bytes               -> Int         -- ^ hash value-hashByteArray ba0 off len = hashByteArrayWithSalt ba0 off len 0+hashByteArray ba0 off len = hashByteArrayWithSalt ba0 off len stringSalt {-# INLINE hashByteArray #-}  -- | Compute a hash value for the content of this 'ByteArray#', using
hashable.cabal view
@@ -1,5 +1,5 @@ Name:                hashable-Version:             1.1.0.0+Version:             1.1.1.0 Synopsis:            A class for types that can be converted to a hash value Description:         This package defines a class, 'Hashable', for types that                      can be converted to a hash value.  This class
tests/Properties.hs view
@@ -6,7 +6,7 @@  module Main (main) where -import Data.Hashable (hash, hashByteArray, hashPtr)+import Data.Hashable (Hashable(hash), hashByteArray, hashPtr) import qualified Data.Text as T import qualified Data.Text.Lazy as L import Foreign (unsafePerformIO)@@ -15,7 +15,7 @@                  writeWord8Array#) import GHC.ST (ST(..), runST) import GHC.Word (Word8(..))-import Test.QuickCheck+import Test.QuickCheck hiding ((.&.)) import Test.Framework (Test, defaultMain, testGroup) import Test.Framework.Providers.QuickCheck2 (testProperty) @@ -37,11 +37,11 @@  -- | Content equality implies hash equality. pText :: T.Text -> T.Text -> Bool-pText a b = (a == b) == (hash a == hash b)+pText a b = if (a == b) then (hash a == hash b) else True  -- | Content equality implies hash equality. pTextLazy :: L.Text -> L.Text -> Bool-pTextLazy a b = (a == b) == (hash a == hash b)+pTextLazy a b = if (a == b) then (hash a == hash b) else True  -- | A small positive integer. newtype ChunkSize = ChunkSize { unCS :: Int }