Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ghc-hashable for openSUSE:Factory 
checked in at 2021-10-12 21:49:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-hashable (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-hashable.new.2443 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-hashable"

Tue Oct 12 21:49:15 2021 rev:30 rq:924070 version:1.3.4.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-hashable/ghc-hashable.changes        
2021-09-10 23:41:07.346547329 +0200
+++ /work/SRC/openSUSE:Factory/.ghc-hashable.new.2443/ghc-hashable.changes      
2021-10-12 21:50:31.107971798 +0200
@@ -1,0 +2,22 @@
+Thu Oct  7 07:58:49 UTC 2021 - [email protected]
+
+- Update hashable to version 1.3.4.1.
+  ## Version 1.3.4.1
+
+   * Fix compilation on 32 bit platforms
+   * Fix `Tree` instance
+
+  ## Version 1.3.4.0
+   * `Text` and `ByteString` hashes include length.
+     This fixes a variant of 
https://github.com/haskell-unordered-containers/hashable/issues/74
+     for texts and bytestrings.
+     https://github.com/haskell-unordered-containers/hashable/pull/223
+   * Use correct prime in `combine`.
+     This should improve the hash quality of compound structures on 64bit 
systems.
+     https://github.com/haskell-unordered-containers/hashable/pull/224
+   * Add instance for types in `containers` package
+     https://github.com/haskell-unordered-containers/hashable/pull/226
+   * Change `Int`, `Int64` and `Word64` `hashWithSalt` slightly.
+     https://github.com/haskell-unordered-containers/hashable/pull/227
+
+-------------------------------------------------------------------

Old:
----
  hashable-1.3.3.0.tar.gz

New:
----
  hashable-1.3.4.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-hashable.spec ++++++
--- /var/tmp/diff_new_pack.ClW4F2/_old  2021-10-12 21:50:31.575972468 +0200
+++ /var/tmp/diff_new_pack.ClW4F2/_new  2021-10-12 21:50:31.575972468 +0200
@@ -19,7 +19,7 @@
 %global pkg_name hashable
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        1.3.3.0
+Version:        1.3.4.1
 Release:        0
 Summary:        A class for types that can be converted to a hash value
 License:        BSD-3-Clause
@@ -27,6 +27,7 @@
 Source0:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
 BuildRequires:  ghc-Cabal-devel
 BuildRequires:  ghc-bytestring-devel
+BuildRequires:  ghc-containers-devel
 BuildRequires:  ghc-deepseq-devel
 BuildRequires:  ghc-rpm-macros
 BuildRequires:  ghc-text-devel

++++++ hashable-1.3.3.0.tar.gz -> hashable-1.3.4.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.3.3.0/CHANGES.md 
new/hashable-1.3.4.1/CHANGES.md
--- old/hashable-1.3.3.0/CHANGES.md     2001-09-09 03:46:40.000000000 +0200
+++ new/hashable-1.3.4.1/CHANGES.md     2001-09-09 03:46:40.000000000 +0200
@@ -1,5 +1,23 @@
 See also https://pvp.haskell.org/faq
 
+## Version 1.3.4.1
+
+ * Fix compilation on 32 bit platforms
+ * Fix `Tree` instance
+
+## Version 1.3.4.0
+ * `Text` and `ByteString` hashes include length.
+   This fixes a variant of 
https://github.com/haskell-unordered-containers/hashable/issues/74
+   for texts and bytestrings.
+   https://github.com/haskell-unordered-containers/hashable/pull/223
+ * Use correct prime in `combine`.
+   This should improve the hash quality of compound structures on 64bit 
systems.
+   https://github.com/haskell-unordered-containers/hashable/pull/224
+ * Add instance for types in `containers` package
+   https://github.com/haskell-unordered-containers/hashable/pull/226
+ * Change `Int`, `Int64` and `Word64` `hashWithSalt` slightly.
+   https://github.com/haskell-unordered-containers/hashable/pull/227
+
 ## Version 1.3.3.0
 
  * `Text` hashing uses 64-bit FNV prime
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.3.3.0/hashable.cabal 
new/hashable-1.3.4.1/hashable.cabal
--- old/hashable-1.3.3.0/hashable.cabal 2001-09-09 03:46:40.000000000 +0200
+++ new/hashable-1.3.4.1/hashable.cabal 2001-09-09 03:46:40.000000000 +0200
@@ -1,6 +1,6 @@
 cabal-version:      1.12
 name:               hashable
-version:            1.3.3.0
+version:            1.3.4.1
 synopsis:           A class for types that can be converted to a hash value
 description:
   This package defines a class, 'Hashable', for types that
@@ -56,6 +56,7 @@
     Randomly initialize the initial seed on each final executable invocation
     This is useful for catching cases when you rely on (non-existent)
     stability of hashable's hash functions.
+    This is not a security feature.
 
   manual:      True
   default:     False
@@ -68,6 +69,8 @@
 
   other-modules:
     Data.Hashable.Class
+    Data.Hashable.Imports
+    Data.Hashable.LowLevel
     Data.Hashable.Generic.Instances
 
   c-sources:        cbits/fnv.c
@@ -76,6 +79,7 @@
   build-depends:
       base        >=4.5  && <4.17
     , bytestring  >=0.9  && <0.12
+    , containers  >=0.4.2.1 && <0.7
     , deepseq     >=1.3  && <1.5
     , ghc-prim
     , text        >=0.12 && <1.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.3.3.0/src/Data/Hashable/Class.hs 
new/hashable-1.3.4.1/src/Data/Hashable/Class.hs
--- old/hashable-1.3.3.0/src/Data/Hashable/Class.hs     2001-09-09 
03:46:40.000000000 +0200
+++ new/hashable-1.3.4.1/src/Data/Hashable/Class.hs     2001-09-09 
03:46:40.000000000 +0200
@@ -64,7 +64,6 @@
 import Control.Applicative (Const(..))
 import Control.Exception (assert)
 import Control.DeepSeq (NFData(rnf))
-import Data.Bits (shiftL, shiftR, xor)
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as BL
 import qualified Data.ByteString.Unsafe as B
@@ -78,7 +77,6 @@
 import qualified Data.Text.Lazy as TL
 import Data.Version (Version(..))
 import Data.Word (Word8, Word16, Word32, Word64)
-import Foreign.C (CString)
 import Foreign.Marshal.Utils (with)
 import Foreign.Ptr (Ptr, FunPtr, IntPtr, WordPtr, castPtr, castFunPtrToPtr, 
ptrToIntPtr)
 import Foreign.Storable (alignment, peek, sizeOf)
@@ -88,6 +86,12 @@
 import System.IO.Unsafe (unsafeDupablePerformIO)
 import System.Mem.StableName
 import Data.Unique (Unique, hashUnique)
+import qualified Data.IntMap as IntMap
+import qualified Data.IntSet as IntSet
+import qualified Data.Map as Map
+import qualified Data.Sequence as Seq
+import qualified Data.Set as Set
+import qualified Data.Tree as Tree
 
 -- As we use qualified F.Foldable, we don't get warnings with newer base
 import qualified Data.Foldable as F
@@ -127,12 +131,6 @@
 import Data.Word (Word)
 #endif
 
-#if MIN_VERSION_base(4,7,0)
-import Data.Bits (finiteBitSize)
-#else
-import Data.Bits (bitSize)
-#endif
-
 #if !(MIN_VERSION_bytestring(0,10,0))
 import qualified Data.ByteString.Lazy.Internal as BL  -- foldlChunks
 #endif
@@ -188,9 +186,8 @@
 #define Type *
 #endif
 
-#ifdef HASHABLE_RANDOM_SEED
-import System.IO.Unsafe (unsafePerformIO)
-#endif
+import Data.Hashable.Imports
+import Data.Hashable.LowLevel
 
 #include "MachDeps.h"
 
@@ -199,31 +196,6 @@
 ------------------------------------------------------------------------
 -- * Computing hash values
 
-#ifdef HASHABLE_RANDOM_SEED
-initialSeed :: Word64
-initialSeed = unsafePerformIO initialSeedC
-{-# NOINLINE initialSeed #-}
-
-foreign import capi "HsHashable.h hs_hashable_init" initialSeedC :: IO Word64
-#endif
-
--- | A default salt used in the implementation of 'hash'.
-defaultSalt :: Int
-#ifdef HASHABLE_RANDOM_SEED
-defaultSalt = hashWithSalt defaultSalt' initialSeed
-#else
-defaultSalt = defaultSalt'
-#endif
-{-# INLINE defaultSalt #-}
-
-defaultSalt' :: Int
-#if WORD_SIZE_IN_BITS == 64
-defaultSalt' = -3750763034362895579 -- 14695981039346656037 :: Int64
-#else
-defaultSalt' = -2128831035 -- 2166136261 :: Int32
-#endif
-{-# INLINE defaultSalt' #-}
-
 -- | The class of types that can be converted to a hash value.
 --
 -- Minimal implementation: 'hashWithSalt'.
@@ -334,7 +306,7 @@
 -- the non-generic instance use case. Instead we provide
 -- 'defaultHashWith'.
 defaultHashWithSalt :: Hashable a => Int -> a -> Int
-defaultHashWithSalt salt x = salt `combine` hash x
+defaultHashWithSalt salt x = salt `hashInt` hash x
 
 -- | Transform a value into a 'Hashable' value, then hash the
 -- transformed value using the given salt.
@@ -360,7 +332,7 @@
 
 instance Hashable Int where
     hash = id
-    hashWithSalt = defaultHashWithSalt
+    hashWithSalt = hashInt
 
 instance Hashable Int8 where
     hash = fromIntegral
@@ -375,15 +347,8 @@
     hashWithSalt = defaultHashWithSalt
 
 instance Hashable Int64 where
-    hash n
-#if MIN_VERSION_base(4,7,0)
-        | finiteBitSize (undefined :: Int) == 64 = fromIntegral n
-#else
-        | bitSize (undefined :: Int) == 64 = fromIntegral n
-#endif
-        | otherwise = fromIntegral (fromIntegral n `xor`
-                                   (fromIntegral n `shiftR` 32 :: Word64))
-    hashWithSalt = defaultHashWithSalt
+    hash = fromIntegral
+    hashWithSalt = hashInt64
 
 instance Hashable Word where
     hash = fromIntegral
@@ -402,14 +367,7 @@
     hashWithSalt = defaultHashWithSalt
 
 instance Hashable Word64 where
-    hash n
-#if MIN_VERSION_base(4,7,0)
-        | finiteBitSize (undefined :: Int) == 64 = fromIntegral n
-#else
-        | bitSize (undefined :: Int) == 64 = fromIntegral n
-#endif
-        | otherwise = fromIntegral (n `xor` (n `shiftR` 32))
-    hashWithSalt = defaultHashWithSalt
+    hashWithSalt = hashWord64
 
 instance Hashable () where
     hash = fromEnum
@@ -570,8 +528,8 @@
     hashWithSalt = hashWithSalt1
 
 instance Hashable1 Maybe where
-    liftHashWithSalt _ s Nothing = s `combine` 0
-    liftHashWithSalt h s (Just a) = s `combine` distinguisher `h` a
+    liftHashWithSalt _ s Nothing = s `hashInt` 0
+    liftHashWithSalt h s (Just a) = s `hashInt` distinguisher `h` a
 
 instance (Hashable a, Hashable b) => Hashable (Either a b) where
     hash (Left a)  = 0 `hashWithSalt` a
@@ -582,8 +540,8 @@
     liftHashWithSalt = defaultLiftHashWithSalt
 
 instance Hashable2 Either where
-    liftHashWithSalt2 h _ s (Left a) = s `combine` 0 `h` a
-    liftHashWithSalt2 _ h s (Right b) = s `combine` distinguisher `h` b
+    liftHashWithSalt2 h _ s (Left a) = s `hashInt` 0 `h` a
+    liftHashWithSalt2 _ h s (Right b) = s `hashInt` distinguisher `h` b
 
 instance (Hashable a1, Hashable a2) => Hashable (a1, a2) where
     hash (a1, a2) = hash a1 `hashWithSalt` a2
@@ -694,24 +652,35 @@
 instance Hashable B.ByteString where
     hashWithSalt salt bs = unsafeDupablePerformIO $
                            B.unsafeUseAsCStringLen bs $ \(p, len) ->
-                           hashPtrWithSalt p (fromIntegral len) salt
+                           hashPtrWithSalt p (fromIntegral len) (hashWithSalt 
salt len)
 
 instance Hashable BL.ByteString where
-    hashWithSalt = BL.foldlChunks hashWithSalt
+    hashWithSalt salt = finalise . BL.foldlChunks step (SP salt 0)
+      where
+        finalise (SP s l) = hashWithSalt s l
+        step (SP s l) bs  = unsafeDupablePerformIO $
+                            B.unsafeUseAsCStringLen bs $ \(p, len) -> do
+                                s' <- hashPtrWithSalt p (fromIntegral len) s
+                                return (SP s' (l + len))
 
 #if MIN_VERSION_bytestring(0,10,4)
 instance Hashable BSI.ShortByteString where
     hashWithSalt salt sbs@(BSI.SBS ba) =
-        hashByteArrayWithSalt ba 0 (BSI.length sbs) salt
+        hashByteArrayWithSalt ba 0 (BSI.length sbs) (hashWithSalt salt 
(BSI.length sbs))
 #endif
 
 instance Hashable T.Text where
     hashWithSalt salt (T.Text arr off len) =
         hashByteArrayWithSalt (TA.aBA arr) (off `shiftL` 1) (len `shiftL` 1)
-        salt
+        (hashWithSalt salt len)
 
 instance Hashable TL.Text where
-    hashWithSalt = TL.foldlChunks hashWithSalt
+    hashWithSalt salt = finalise . TL.foldlChunks step (SP salt 0)
+      where
+        finalise (SP s l) = hashWithSalt s l
+        step (SP s l) (T.Text arr off len) = SP
+            (hashByteArrayWithSalt (TA.aBA arr) (off `shiftL` 1) (len `shiftL` 
1) s)
+            (l + len)
 
 -- | Compute the hash of a ThreadId.
 hashThreadId :: ThreadId -> Int
@@ -797,27 +766,6 @@
         -> IO Int     -- ^ hash value
 hashPtr p len = hashPtrWithSalt p len defaultSalt
 
--- | Compute a hash value for the content of this pointer, using an
--- initial salt.
---
--- This function can for example be used to hash non-contiguous
--- segments of memory as if they were one contiguous segment, by using
--- the output of one hash as the salt for the next.
-hashPtrWithSalt :: Ptr a   -- ^ pointer to the data to hash
-                -> Int     -- ^ length, in bytes
-                -> Int     -- ^ salt
-                -> IO Int  -- ^ hash value
-hashPtrWithSalt p len salt =
-    fromIntegral `fmap` c_hashCString (castPtr p) (fromIntegral len)
-    (fromIntegral salt)
-
-foreign import capi unsafe "HsHashable.h hashable_fnv_hash" c_hashCString
-#if WORD_SIZE_IN_BITS == 64
-    :: CString -> Int64 -> Int64 -> IO Word64
-#else
-    :: CString -> Int32 -> Int32 -> IO Word32
-#endif
-
 -- | Compute a hash value for the content of this 'ByteArray#',
 -- beginning at the specified offset, using specified number of bytes.
 hashByteArray :: ByteArray#  -- ^ data to hash
@@ -827,38 +775,6 @@
 hashByteArray ba0 off len = hashByteArrayWithSalt ba0 off len defaultSalt
 {-# INLINE hashByteArray #-}
 
--- | Compute a hash value for the content of this 'ByteArray#', using
--- an initial salt.
---
--- This function can for example be used to hash non-contiguous
--- segments of memory as if they were one contiguous segment, by using
--- the output of one hash as the salt for the next.
-hashByteArrayWithSalt
-    :: ByteArray#  -- ^ data to hash
-    -> Int         -- ^ offset, in bytes
-    -> Int         -- ^ length, in bytes
-    -> Int         -- ^ salt
-    -> Int         -- ^ hash value
-hashByteArrayWithSalt ba !off !len !h =
-    fromIntegral $ c_hashByteArray ba (fromIntegral off) (fromIntegral len)
-    (fromIntegral h)
-
-#if __GLASGOW_HASKELL__ >= 802
-foreign import capi unsafe "HsHashable.h hashable_fnv_hash_offset" 
c_hashByteArray
-#else
-foreign import ccall unsafe "hashable_fnv_hash_offset" c_hashByteArray
-#endif
-#if WORD_SIZE_IN_BITS == 64
-    :: ByteArray# -> Int64 -> Int64 -> Int64 -> Word64
-#else
-    :: ByteArray# -> Int32 -> Int32 -> Int32 -> Word32
-#endif
-
--- | Combine two given hash values.  'combine' has zero as a left
--- identity.
-combine :: Int -> Int -> Int
-combine h1 h2 = (h1 * 16777619) `xor` h2
-
 instance Hashable Unique where
     hash = hashUnique
     hashWithSalt = defaultHashWithSalt
@@ -976,8 +892,8 @@
     hashWithSalt = hashWithSalt1
 
 instance (Hashable1 f, Hashable1 g) => Hashable1 (FS.Sum f g) where
-    liftHashWithSalt h s (FS.InL a) = liftHashWithSalt h (s `combine` 0) a
-    liftHashWithSalt h s (FS.InR a) = liftHashWithSalt h (s `combine` 
distinguisher) a
+    liftHashWithSalt h s (FS.InL a) = liftHashWithSalt h (s `hashInt` 0) a
+    liftHashWithSalt h s (FS.InR a) = liftHashWithSalt h (s `hashInt` 
distinguisher) a
 
 instance (Hashable1 f, Hashable1 g, Hashable a) => Hashable (FS.Sum f g a) 
where
     hashWithSalt = hashWithSalt1
@@ -1045,3 +961,67 @@
 instance Show1 Hashed where
   liftShowsPrec sp _ d (Hashed a _) = showsUnaryWith sp "hashed" d a
 #endif
+
+-------------------------------------------------------------------------------
+-- containers
+-------------------------------------------------------------------------------
+
+-- | @since 1.3.4.0
+instance Hashable2 Map.Map where
+    liftHashWithSalt2 hk hv s m = Map.foldlWithKey'
+        (\s' k v -> hv (hk s' k) v)
+        (hashWithSalt s (Map.size m))
+        m
+
+-- | @since 1.3.4.0
+instance Hashable k => Hashable1 (Map.Map k) where
+    liftHashWithSalt h s m = Map.foldlWithKey'
+        (\s' k v -> h (hashWithSalt s' k) v)
+        (hashWithSalt s (Map.size m))
+        m
+
+-- | @since 1.3.4.0
+instance (Hashable k, Hashable v) => Hashable (Map.Map k v) where
+    hashWithSalt = hashWithSalt2
+
+-- | @since 1.3.4.0
+instance Hashable1 IntMap.IntMap where
+    liftHashWithSalt h s m = IntMap.foldlWithKey'
+        (\s' k v -> h (hashWithSalt s' k) v)
+        (hashWithSalt s (IntMap.size m))
+        m
+
+-- | @since 1.3.4.0
+instance Hashable v => Hashable (IntMap.IntMap v) where
+    hashWithSalt = hashWithSalt1
+
+-- | @since 1.3.4.0
+instance Hashable1 Set.Set where
+    liftHashWithSalt h s x = Set.foldl' h (hashWithSalt s (Set.size x)) x
+
+-- | @since 1.3.4.0
+instance Hashable v => Hashable (Set.Set v) where
+    hashWithSalt = hashWithSalt1
+
+-- | @since 1.3.4.0
+instance Hashable IntSet.IntSet where
+    hashWithSalt salt x = IntSet.foldl' hashWithSalt
+        (hashWithSalt salt (IntSet.size x))
+        x
+
+-- | @since 1.3.4.0
+instance Hashable1 Seq.Seq where
+    liftHashWithSalt h s x = F.foldl' h (hashWithSalt s (Seq.length x)) x
+
+-- | @since 1.3.4.0
+instance Hashable v => Hashable (Seq.Seq v) where
+    hashWithSalt = hashWithSalt1
+
+-- | @since 1.3.4.0
+instance Hashable1 Tree.Tree where
+    liftHashWithSalt h = go where
+        go s (Tree.Node x xs) = liftHashWithSalt go (h s x) xs
+
+-- | @since 1.3.4.0
+instance Hashable v => Hashable (Tree.Tree v) where
+    hashWithSalt = hashWithSalt1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.3.3.0/src/Data/Hashable/Imports.hs 
new/hashable-1.3.4.1/src/Data/Hashable/Imports.hs
--- old/hashable-1.3.3.0/src/Data/Hashable/Imports.hs   1970-01-01 
01:00:00.000000000 +0100
+++ new/hashable-1.3.4.1/src/Data/Hashable/Imports.hs   2001-09-09 
03:46:40.000000000 +0200
@@ -0,0 +1,11 @@
+-- | This module exists to avoid conditional imports
+-- and unused import warnings.
+module Data.Hashable.Imports (
+    Int64, Int32,
+    Word64, Word32,
+    xor, shiftR, shiftL,
+) where
+
+import Data.Int (Int64, Int32)
+import Data.Word (Word64, Word32)
+import Data.Bits (xor, shiftR, shiftL)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.3.3.0/src/Data/Hashable/LowLevel.hs 
new/hashable-1.3.4.1/src/Data/Hashable/LowLevel.hs
--- old/hashable-1.3.3.0/src/Data/Hashable/LowLevel.hs  1970-01-01 
01:00:00.000000000 +0100
+++ new/hashable-1.3.4.1/src/Data/Hashable/LowLevel.hs  2001-09-09 
03:46:40.000000000 +0200
@@ -0,0 +1,129 @@
+{-# LANGUAGE CPP, BangPatterns, MagicHash, CApiFFI, UnliftedFFITypes #-}
+{-# LANGUAGE Trustworthy #-}
+-- | A module containing low-level hash primitives.
+module Data.Hashable.LowLevel (
+    Salt,
+    defaultSalt,
+    hashInt,
+    hashInt64,
+    hashWord64,
+    hashPtrWithSalt,
+    hashByteArrayWithSalt,
+) where
+
+#include "MachDeps.h"
+
+import Foreign.C (CString)
+import Foreign.Ptr (Ptr, castPtr)
+import GHC.Base (ByteArray#)
+
+#ifdef HASHABLE_RANDOM_SEED
+import System.IO.Unsafe (unsafePerformIO)
+#endif
+
+import Data.Hashable.Imports
+
+-------------------------------------------------------------------------------
+-- Initial seed
+-------------------------------------------------------------------------------
+
+type Salt = Int
+
+#ifdef HASHABLE_RANDOM_SEED
+initialSeed :: Word64
+initialSeed = unsafePerformIO initialSeedC
+{-# NOINLINE initialSeed #-}
+
+foreign import capi "HsHashable.h hs_hashable_init" initialSeedC :: IO Word64
+#endif
+
+-- | A default salt used in the implementation of 'hash'.
+defaultSalt :: Salt
+#ifdef HASHABLE_RANDOM_SEED
+defaultSalt = hashInt defaultSalt' (fromIntegral initialSeed)
+#else
+defaultSalt = defaultSalt'
+#endif
+{-# INLINE defaultSalt #-}
+
+defaultSalt' :: Salt
+#if WORD_SIZE_IN_BITS == 64
+defaultSalt' = -3750763034362895579 -- 14695981039346656037 :: Int64
+#else
+defaultSalt' = -2128831035 -- 2166136261 :: Int32
+#endif
+{-# INLINE defaultSalt' #-}
+
+-------------------------------------------------------------------------------
+-- Hash primitives
+-------------------------------------------------------------------------------
+
+-- | Hash 'Int'. First argument is a salt, second argument is an 'Int'.
+-- The result is new salt / hash value.
+hashInt :: Salt -> Int -> Salt
+#if WORD_SIZE_IN_BITS == 64
+hashInt s x = (s * 1099511628211) `xor` x
+#else
+hashInt s x = (s * 16777619) `xor` x
+#endif
+-- Note: FNV-1 hash takes a byte of data at once, here we take an 'Int',
+-- which is 4 or 8 bytes. Whether that's bad or not, I don't know.
+
+hashInt64  :: Salt -> Int64 -> Salt
+hashWord64 :: Salt -> Word64 -> Salt
+
+#if WORD_SIZE_IN_BITS == 64
+hashInt64  s x = hashInt s (fromIntegral x)
+hashWord64 s x = hashInt s (fromIntegral x)
+#else
+hashInt64  s x = hashInt (hashInt s (fromIntegral x)) (fromIntegral (x 
`shiftR` 32))
+hashWord64 s x = hashInt (hashInt s (fromIntegral x)) (fromIntegral (x 
`shiftR` 32))
+#endif
+
+-- | Compute a hash value for the content of this pointer, using an
+-- initial salt.
+--
+-- This function can for example be used to hash non-contiguous
+-- segments of memory as if they were one contiguous segment, by using
+-- the output of one hash as the salt for the next.
+hashPtrWithSalt :: Ptr a   -- ^ pointer to the data to hash
+                -> Int     -- ^ length, in bytes
+                -> Salt    -- ^ salt
+                -> IO Salt -- ^ hash value
+hashPtrWithSalt p len salt =
+    fromIntegral `fmap` c_hashCString (castPtr p) (fromIntegral len)
+    (fromIntegral salt)
+
+-- | Compute a hash value for the content of this 'ByteArray#', using
+-- an initial salt.
+--
+-- This function can for example be used to hash non-contiguous
+-- segments of memory as if they were one contiguous segment, by using
+-- the output of one hash as the salt for the next.
+hashByteArrayWithSalt
+    :: ByteArray#  -- ^ data to hash
+    -> Int         -- ^ offset, in bytes
+    -> Int         -- ^ length, in bytes
+    -> Salt        -- ^ salt
+    -> Salt        -- ^ hash value
+hashByteArrayWithSalt ba !off !len !h =
+    fromIntegral $ c_hashByteArray ba (fromIntegral off) (fromIntegral len)
+    (fromIntegral h)
+
+foreign import capi unsafe "HsHashable.h hashable_fnv_hash" c_hashCString
+#if WORD_SIZE_IN_BITS == 64
+    :: CString -> Int64 -> Int64 -> IO Word64
+#else
+    :: CString -> Int32 -> Int32 -> IO Word32
+#endif
+
+#if __GLASGOW_HASKELL__ >= 802
+foreign import capi unsafe "HsHashable.h hashable_fnv_hash_offset" 
c_hashByteArray
+#else
+foreign import ccall unsafe "hashable_fnv_hash_offset" c_hashByteArray
+#endif
+#if WORD_SIZE_IN_BITS == 64
+    :: ByteArray# -> Int64 -> Int64 -> Int64 -> Word64
+#else
+    :: ByteArray# -> Int32 -> Int32 -> Int32 -> Word32
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hashable-1.3.3.0/tests/Regress.hs 
new/hashable-1.3.4.1/tests/Regress.hs
--- old/hashable-1.3.3.0/tests/Regress.hs       2001-09-09 03:46:40.000000000 
+0200
+++ new/hashable-1.3.4.1/tests/Regress.hs       2001-09-09 03:46:40.000000000 
+0200
@@ -5,12 +5,19 @@
 module Regress (regressions) where
 
 import qualified Test.Framework as F
+import Control.Monad (when)
 import Test.Framework.Providers.HUnit (testCase)
-import Test.HUnit ((@=?))
+import Test.HUnit (assertFailure, (@=?))
 import GHC.Generics (Generic)
 import Data.List (nub)
 import Data.Fixed (Pico)
 import Data.Text (Text)
+import Data.ByteString (ByteString)
+
+import qualified Data.Text.Lazy as TL
+import qualified Data.ByteString.Char8 as BS8
+import qualified Data.ByteString.Lazy as BSL
+import qualified Data.ByteString.Lazy.Char8 as BSL8
 
 #ifdef HAVE_MMAP
 import qualified Regress.Mmap as Mmap
@@ -41,8 +48,49 @@
         hs @=? nub hs
 #if WORD_SIZE_IN_BITS == 64
     , testCase "64 bit Text" $ do
-        hash ("hello world" :: Text) @=? 2668910425102664189
+        hash ("hello world" :: Text) @=? -3875242662334356092
 #endif
+    , F.testGroup "concatenation"
+        [ testCase "String" $ do
+            let lhs, rhs :: (String, String)
+                lhs = ("foo", "bar")
+                rhs = ("foobar", "")
+
+            when (hash lhs == hash rhs) $ do
+                assertFailure "Should have different hashes"
+
+        , testCase "Text" $ do
+            let lhs, rhs :: (Text, Text)
+                lhs = ("foo", "bar")
+                rhs = ("foobar", "")
+
+            when (hash lhs == hash rhs) $ do
+                assertFailure "Should have different hashes"
+
+        , testCase "Lazy Text" $ do
+            let lhs, rhs :: (TL.Text, TL.Text)
+                lhs = ("foo", "bar")
+                rhs = ("foobar", "")
+
+            when (hash lhs == hash rhs) $ do
+                assertFailure "Should have different hashes"
+
+        , testCase "ByteString" $ do
+            let lhs, rhs :: (ByteString, ByteString)
+                lhs = (BS8.pack "foo", BS8.pack "bar")
+                rhs = (BS8.pack "foobar", BS8.empty)
+
+            when (hash lhs == hash rhs) $ do
+                assertFailure "Should have different hashes"
+
+        , testCase "Lazy ByteString" $ do
+            let lhs, rhs :: (BSL.ByteString, BSL.ByteString)
+                lhs = (BSL8.pack "foo", BSL8.pack "bar")
+                rhs = (BSL8.pack "foobar", BSL.empty)
+
+            when (hash lhs == hash rhs) $ do
+                assertFailure "Should have different hashes"
+        ]
     ]
   where
     nullaryCase :: Int -> SumOfNullary -> IO ()

Reply via email to