Z-Data 0.7.4.0 → 0.8.0.0
raw patch · 8 files changed
+40/−23 lines, 8 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Z.Data.Vector.Base: instance Data.Hashable.Class.Hashable Z.Data.Vector.Base.Bytes
+ Z.Data.Vector.Base: instance GHC.Classes.Ord Z.Data.Vector.Base.Bytes
Files
- ChangeLog.md +4/−0
- README.md +2/−1
- Z-Data.cabal +9/−4
- Z/Data/Builder/Numeric.hs +3/−3
- Z/Data/Text/Print.hs +1/−1
- Z/Data/Vector/Base.hs +14/−8
- cbits/bytes.c +7/−4
- test/Z/Data/Vector/BaseSpec.hs +0/−2
ChangeLog.md view
@@ -1,5 +1,9 @@ # Revision history for Z-Data +## 0.8.0.0 -- 2021-04-20++* Change `Bytes` 's `Hashable` instance to use FNV-1a (proposed by @zypeh).+ ## 0.7.4.0 -- 2021-04-06 * Add `emptyArr` to `Z.Data.Array`.
README.md view
@@ -4,6 +4,7 @@ [](https://github.com/ZHaskell/z-data/actions) [](https://github.com/ZHaskell/z-data/actions) [](https://github.com/ZHaskell/z-data/actions)+[](https://gitter.im/Z-Haskell/community) This package is part of [ZHaskell](https://z.haskell.world) project, providing basic data structures and functions: @@ -55,7 +56,7 @@ > :set -XOverloadedStrings > > -- Builders can be used with OverloadedStrings-> B.buildBytes $ "builders: " >> B.hex (3 :: Word16) >> B.comma >> B.double 1.2345678+> B.build $ "builders: " >> B.hex (3 :: Word16) >> B.comma >> B.double 1.2345678 [98,117,105,108,100,101,114,115,58,32,48,48,48,51,44,49,46,50,51,52,53,54,55,56] > > B.buildText $ "builders: " >> B.hex (3 :: Word16) >> B.comma >> B.double 1.2345678
Z-Data.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: Z-Data-version: 0.7.4.0+version: 0.8.0.0 synopsis: Array, vector and text description: This package provides array, slice and text operations license: BSD-3-Clause@@ -187,9 +187,14 @@ cc-options: -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0600 else- extra-libraries:- stdc++- pthread+ if os(osx)+ extra-libraries:+ c+++ pthread+ else+ extra-libraries:+ stdc+++ pthread if flag(integer-simple) cpp-options: -DINTEGER_SIMPLE
Z/Data/Builder/Numeric.hs view
@@ -492,11 +492,11 @@ -- import Data.Word -- import Data.Int ----- > T.validate . B.buildBytes $ B.hex (125 :: Int8)+-- > T.validate . B.build $ B.hex (125 :: Int8) -- "7d"--- > T.validate . B.buildBytes $ B.hex (-1 :: Int8)+-- > T.validate . B.build $ B.hex (-1 :: Int8) -- "ff"--- > T.validate . B.buildBytes $ B.hex (125 :: Word16)+-- > T.validate . B.build $ B.hex (125 :: Word16) -- "007d" -- @ --
Z/Data/Text/Print.hs view
@@ -129,7 +129,7 @@ -- -- You should return a 'B.Builder' writing in UTF8 encoding only, i.e. --- -- @Z.Data.Text.validateMaybe (Z.Data.Builder.buildBytes (toUTF8BuilderP p a)) /= Nothing@+ -- @Z.Data.Text.validateMaybe (Z.Data.Builder.build (toUTF8BuilderP p a)) /= Nothing@ toUTF8BuilderP :: Int -> a -> B.Builder () default toUTF8BuilderP :: (Generic a, GToText (Rep a)) => Int -> a -> B.Builder ()
Z/Data/Vector/Base.hs view
@@ -444,10 +444,7 @@ compare = comparePrimVector comparePrimVector :: (Prim a, Ord a) => PrimVector a -> PrimVector a -> Ordering-{-# INLINE [1] comparePrimVector #-}-{-# RULES- "comparePrimVector/Bytes" comparePrimVector = compareBytes- #-}+{-# INLINE comparePrimVector #-} comparePrimVector (PrimVector baA sA lA) (PrimVector baB sB lB) | baA `sameArr` baB = if sA == sB then lA `compare` lB else go sA sB | otherwise = go sA sB@@ -460,6 +457,11 @@ in case o of EQ -> go (i+1) (j+1) x -> x +-- | This is an INCOHERENT instance, compare binary data using SIMD.+instance {-# INCOHERENT #-} Ord Bytes where+ {-# INLINE compare #-}+ compare = compareBytes+ compareBytes :: PrimVector Word8 -> PrimVector Word8 -> Ordering {-# INLINE compareBytes #-} compareBytes (PrimVector (PrimArray baA#) (I# sA#) lA)@@ -513,10 +515,7 @@ hashWithSalt = hashWithSaltPrimVector hashWithSaltPrimVector :: (Hashable a, Prim a) => Int -> PrimVector a -> Int-{-# INLINE [1] hashWithSaltPrimVector #-}-{-# RULES- "hashWithSaltPrimVector/Bytes" hashWithSaltPrimVector = hashWithSaltBytes- #-}+{-# INLINE hashWithSaltPrimVector #-} hashWithSaltPrimVector salt0 (PrimVector arr s l) = go salt0 s where -- we don't do a final hash with length to keep consistent with Bytes's instance@@ -524,6 +523,13 @@ go !salt !i | i >= end = salt | otherwise = go (hashWithSalt salt (indexPrimArray arr i)) (i+1)++-- | This is an INCOHERENT instance, hash binary data using FNV-1a+--+-- Note this is different from @Vector Word8@ or @[Word8]@ which use FNV-1.+instance {-# INCOHERENT #-} Hashable Bytes where+ {-# INLINE hashWithSalt #-}+ hashWithSalt = hashWithSaltBytes hashWithSaltBytes :: Int -> Bytes -> Int {-# INLINE hashWithSaltBytes #-}
cbits/bytes.c view
@@ -53,10 +53,13 @@ else return (p - a); } -/* FNV-1 hash+/* FNV-1a hash *- * The FNV-1 hash description: http://isthe.com/chongo/tech/comp/fnv/- * The FNV-1 hash is public domain: http://isthe.com/chongo/tech/comp/fnv/#public_domain+ * The FNV-1a hash description: http://isthe.com/chongo/tech/comp/fnv/#FNV-1a+ * The FNV-1a hash is public domain: http://isthe.com/chongo/tech/comp/fnv/#public_domain+ * + * Using FNV-1a because it has better avalanche properties compared to the FNV original version.+ * See also https://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed * * The original version from hashable use long type which doesn't match 'Int' in haskell and * cause problems on window, here we use HsInt.@@ -65,7 +68,7 @@ HsWord hash = salt; while (len--) {- hash = (hash * 16777619) ^ *str++;+ hash = (hash ^ *str++) * 16777619; } return hash;
test/Z/Data/Vector/BaseSpec.hs view
@@ -64,8 +64,6 @@ describe "Bytes Hashable instance property" . modifyMaxSuccess (*10) . modifyMaxSize (*10) $ do - prop "Vector Word8's hash should be equal to hashWithSalt (Bytes's one) (Bytes's length)" $ \ xs ->- hash (V.pack @V.Vector @Word8 xs) === hashWithSalt (hash (V.pack @V.PrimVector @Word8 xs)) (List.length xs) prop "Vector a's hash should be equal to [a]'s hash" $ \ xs -> hash (V.pack @V.Vector @Word8 xs) === hash xs prop "Vector a's hash should be equal to [a]'s hash" $ \ xs ->