Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use xxhash for byte hashing #301

Merged
merged 1 commit into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ See also https://pvp.haskell.org/faq
## Version 1.4.5.0

* Drop support for GHCs prior 8.6.5
* Use xxhash for hashing bytestrings and bytearrays.
Note: when compiling binaries for distribution, you may need to disable
`arch-native` flag.

## Version 1.4.4.0

Expand Down
56 changes: 0 additions & 56 deletions cbits/fnv.c

This file was deleted.

15 changes: 12 additions & 3 deletions hashable-bench/hashable-bench.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ tested-with:

extra-source-files:
include/HsHashable.h
include/HsXXHash.h
xxHash-0.8.2/xxhash.h

flag integer-gmp
description:
Expand All @@ -50,13 +52,19 @@ library

other-modules:
Data.Hashable.Class
Data.Hashable.FFI
Data.Hashable.Generic.Instances
Data.Hashable.Imports
Data.Hashable.LowLevel
Data.Hashable.Mix
Data.Hashable.XXH3

include-dirs: include xxHash-0.8.2/
includes:
HsHashable.h
HsXXHash.h
xxhash.h

c-sources: cbits/fnv.c
include-dirs: include
hs-source-dirs: src
build-depends:
base >=4.10.1.0 && <4.21
Expand Down Expand Up @@ -116,6 +124,7 @@ library
UnliftedFFITypes

ghc-options: -Wall -fwarn-tabs
ghc-options: -optc=-march=native -optc-mtune=native

benchmark hashable-benchmark
-- We cannot depend on the hashable library directly as that creates
Expand Down Expand Up @@ -143,7 +152,7 @@ benchmark hashable-benchmark
if impl(ghc >=7.2.1)
cpp-options: -DGENERICS

ghc-options: -Wall -O2
ghc-options: -Wall
default-language: Haskell2010

source-repository head
Expand Down
1 change: 1 addition & 0 deletions hashable-bench/xxHash-0.8.2
52 changes: 49 additions & 3 deletions hashable.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ tested-with:
extra-source-files:
CHANGES.md
include/HsHashable.h
include/HsXXHash.h
README.md
xxHash-0.8.2/xxhash.h

flag integer-gmp
description:
Expand All @@ -56,6 +58,14 @@ flag integer-gmp
manual: False
default: True

flag arch-native
description:
Use @-march=native@ when compiling C sources.
You may need to disable this flag if you are building distributable binaries

manual: True
default: True

flag random-initial-seed
description:
Randomly initialize the initial seed on each final executable invocation
Expand All @@ -74,13 +84,19 @@ library

other-modules:
Data.Hashable.Class
Data.Hashable.FFI
Data.Hashable.Generic.Instances
Data.Hashable.Imports
Data.Hashable.LowLevel
Data.Hashable.Mix
Data.Hashable.XXH3

include-dirs: include xxHash-0.8.2
includes:
HsHashable.h
HsXXHash.h
xxhash.h

c-sources: cbits/fnv.c
include-dirs: include
hs-source-dirs: src
build-depends:
, base >=4.12.0.0 && <4.21
Expand Down Expand Up @@ -149,7 +165,12 @@ library
TypeOperators
UnliftedFFITypes

ghc-options: -Wall -fwarn-tabs
ghc-options: -Wall

if flag(arch-native)
-- Cabal doesn't pass cc-options to "ordinary" Haskell source compilation
-- https://github.com/haskell/cabal/issues/9801
ghc-options: -optc=-march=native -optc-mtune=native

if impl(ghc >=9.0)
-- these flags may abort compilation with GHC-8.10
Expand Down Expand Up @@ -190,6 +211,31 @@ test-suite hashable-tests
ghc-options: -Wall -fno-warn-orphans
default-language: Haskell2010

test-suite xxhash-tests
type: exitcode-stdio-1.0
hs-source-dirs: tests src
main-is: xxhash-tests.hs
other-modules:
Data.Hashable.FFI
Data.Hashable.XXH3

default-language: Haskell2010
build-depends:
, base
, bytestring
, primitive ^>=0.9.0.0
, tasty ^>=1.5
, tasty-hunit ^>=0.10.1
, tasty-quickcheck ^>=0.10.3

include-dirs: include xxHash-0.8.2
includes:
HsXXHash.h
xxhash.h

if !impl(ghc >=9.4)
build-depends: data-array-byte >=0.1.0.1 && <0.2

test-suite hashable-examples
type: exitcode-stdio-1.0
build-depends:
Expand Down
14 changes: 0 additions & 14 deletions include/HsHashable.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,8 @@
#ifndef HS_HASHABLE_H
#define HS_HASHABLE_H

#include "MachDeps.h"
#include <stdint.h>

#if WORD_SIZE_IN_BITS == 64
#define FNV_PRIME 1099511628211
#define FNV_SIGNED int64_t
#define FNV_UNSIGNED uint64_t
#else
#define FNV_PRIME 16777619
#define FNV_SIGNED int32_t
#define FNV_UNSIGNED uint32_t
#endif

uint64_t hs_hashable_init();

FNV_UNSIGNED hashable_fnv_hash(const unsigned char* str, FNV_SIGNED len, FNV_UNSIGNED salt);
FNV_UNSIGNED hashable_fnv_hash_offset(const unsigned char* str, FNV_SIGNED offset, FNV_SIGNED len, FNV_UNSIGNED salt);

#endif
35 changes: 35 additions & 0 deletions include/HsXXHash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef HS_XXHASH_H
#define HS_XXHASH_H

#include <stdint.h>

#define XXH_INLINE_ALL
#include "xxhash.h"

#define hs_XXH3_sizeof_state_s sizeof(struct XXH3_state_s)

static inline uint64_t hs_XXH3_64bits_withSeed_offset(const uint8_t *ptr, size_t off, size_t len, uint64_t seed) {
return XXH3_64bits_withSeed(ptr + off, len, seed);
}

static inline uint64_t hs_XXH3_64bits_withSeed_u64(uint64_t val, uint64_t seed) {
return XXH3_64bits_withSeed(&val, sizeof(val), seed);
}

static inline uint64_t hs_XXH3_64bits_withSeed_u32(uint32_t val, uint64_t seed) {
return XXH3_64bits_withSeed(&val, sizeof(val), seed);
}

static inline void hs_XXH3_64bits_update_offset(XXH3_state_t *statePtr, const uint8_t *ptr, size_t off, size_t len) {
XXH3_64bits_update(statePtr, ptr + off, len);
}

static inline void hs_XXH3_64bits_update_u64(XXH3_state_t *statePtr, uint64_t val) {
XXH3_64bits_update(statePtr, &val, sizeof(val));
}

static inline void hs_XXH3_64bits_update_u32(XXH3_state_t *statePtr, uint32_t val) {
XXH3_64bits_update(statePtr, &val, sizeof(val));
}

#endif /* HS_XXHASH_H */
Loading
Loading