feat(cchash): native FNV hash for int64/int32

This commit is contained in:
Simon Cruanes 2023-03-13 13:33:08 -04:00
parent a7b14c5620
commit 83009aac10
No known key found for this signature in database
GPG key ID: EBFFF6F283F3A2B4
2 changed files with 17 additions and 5 deletions

View file

@ -20,8 +20,8 @@ let hash_int_ n =
(h := Int64.(mul !h fnv_prime)); (h := Int64.(mul !h fnv_prime));
h := Int64.(logxor !h (of_int ((n lsr (k * 8)) land 0xff))) h := Int64.(logxor !h (of_int ((n lsr (k * 8)) land 0xff)))
done; done;
(* truncate back to int and remove sign *)
Int64.to_int !h land max_int Int64.to_int !h land max_int
(* truncate back to int and remove sign *)
let combine2 a b = let combine2 a b =
let h = ref fnv_offset_basis in let h = ref fnv_offset_basis in
@ -82,11 +82,19 @@ let bool b =
2) 2)
let char x = hash_int_ (Char.code x) 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 *) (* do not hash more than 128 bytes in strings/bytes *)
let max_len_b_ = 128 let max_len_b_ = 128

View file

@ -10,4 +10,8 @@ t @@ fun () -> int 0 >= 0;;
t @@ fun () -> char 'c' >= 0;; t @@ fun () -> char 'c' >= 0;;
t @@ fun () -> int 152352 = int 152352;; 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; 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))