From 83009aac10db4d5e098853df1693eaa28d8edc34 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Mon, 13 Mar 2023 13:33:08 -0400 Subject: [PATCH] feat(cchash): native FNV hash for int64/int32 --- src/core/CCHash.ml | 16 ++++++++++++---- tests/core/t_hash.ml | 6 +++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/core/CCHash.ml b/src/core/CCHash.ml index e82189ca..a65959ff 100644 --- a/src/core/CCHash.ml +++ b/src/core/CCHash.ml @@ -20,8 +20,8 @@ let hash_int_ n = (h := Int64.(mul !h fnv_prime)); h := Int64.(logxor !h (of_int ((n lsr (k * 8)) land 0xff))) done; + (* truncate back to int and remove sign *) Int64.to_int !h land max_int -(* truncate back to int and remove sign *) let combine2 a b = let h = ref fnv_offset_basis in @@ -82,11 +82,19 @@ let bool b = 2) let char x = hash_int_ (Char.code x) -let int32 (x : int32) = Hashtbl.hash x (* TODO: FNV *) -let int64 (x : int64) = Hashtbl.hash x (* TODO: FNV *) +(* hash an integer *) +let int64 n : int = + let h = ref fnv_offset_basis in + for k = 0 to 7 do + (h := Int64.(mul !h fnv_prime)); + h := Int64.(logxor !h (logand (shift_right_logical n (k * 8)) 0xffL)) + done; + (* truncate back to int and remove sign *) + Int64.to_int !h land max_int -let nativeint (x : nativeint) = Hashtbl.hash x +let int32 (x : int32) = int64 (Int64.of_int32 x) +let nativeint (x : nativeint) = int64 (Int64.of_nativeint x) (* do not hash more than 128 bytes in strings/bytes *) let max_len_b_ = 128 diff --git a/tests/core/t_hash.ml b/tests/core/t_hash.ml index 012f47c8..7248c8ce 100644 --- a/tests/core/t_hash.ml +++ b/tests/core/t_hash.ml @@ -10,4 +10,8 @@ t @@ fun () -> int 0 >= 0;; t @@ fun () -> char 'c' >= 0;; t @@ fun () -> int 152352 = int 152352;; t @@ fun () -> list_comm int [ 1; 2 ] = list_comm int [ 2; 1 ];; -t @@ fun () -> list_comm int [ 1; 2 ] <> list_comm int [ 2; 3 ] +t @@ fun () -> list_comm int [ 1; 2 ] <> list_comm int [ 2; 3 ];; + +q Q.int (fun i -> + Q.assume (i >= 0); + int i = int64 (Int64.of_int i))