Skip to content

Commit a3abf40

Browse files
committed
add CCInt64.{hash,hash_to_int64}
1 parent 4e2f922 commit a3abf40

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

src/core/CCInt64.ml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,25 @@ include Int64
55

66
let min : t -> t -> t = Stdlib.min
77
let max : t -> t -> t = Stdlib.max
8-
let hash x = Stdlib.abs (to_int x)
98
let sign i = compare i zero
109

10+
(* use FNV:
11+
https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function *)
12+
let hash_to_int64 (n : t) =
13+
let offset_basis = 0xcbf29ce484222325L in
14+
let prime = 0x100000001b3L in
15+
16+
let h = ref offset_basis in
17+
for k = 0 to 7 do
18+
h := mul !h prime;
19+
(* h := h xor (k-th bit of n) *)
20+
h := logxor !h (logand (shift_left n (k * 8)) 0xffL)
21+
done;
22+
logand !h max_int
23+
24+
let[@inline] hash (n : t) : int =
25+
to_int (hash_to_int64 n) land CCShims_.Stdlib.max_int
26+
1127
(* see {!CCInt.popcount} for more details *)
1228
let[@inline] popcount (b : t) : int =
1329
let m1 = 0x5555555555555555L in

src/core/CCInt64.mli

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,13 @@ val max : t -> t -> t
2727
@since 3.0 *)
2828

2929
val hash : t -> int
30-
(** [hash x] computes the hash of [x].
31-
Like {!Stdlib.abs (to_int x)}. *)
30+
(** [hash x] computes the hash of [x], a non-negative integer.
31+
Uses FNV since NEXT_RELEASE *)
32+
33+
val hash_to_int64 : t -> t
34+
(** Like {!hash} but does not truncate.
35+
Uses FNV.
36+
@since NEXT_RELEASE *)
3237

3338
val popcount : t -> int
3439
(** Number of bits set to 1.

0 commit comments

Comments
 (0)