Skip to content

Commit

Permalink
Improve hash function
Browse files Browse the repository at this point in the history
- Hash chunks in the same order as the C implementation.
  (submitted a change to the C stubs to get the same result on all platforms:
   ocaml/Zarith#145)
- Call caml_hash_mix_final to compute the final hash value and restrict
  the result to a positive 31-bit integer.

Signed-off-by: Jérôme Vouillon <[email protected]>
  • Loading branch information
vouillon committed Nov 30, 2023
1 parent 6ae094f commit c2b3e1f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
25 changes: 17 additions & 8 deletions runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ function ml_z_mul_overflows(x,y){

//external init: unit -> unit
//Provides: ml_z_init
//Requires: caml_zarith_marshal, caml_zarith_unmarshal, caml_custom_ops, ml_z_hash, ml_z_compare
//Requires: caml_zarith_marshal, caml_zarith_unmarshal, caml_custom_ops, jsoo_z_hash, ml_z_compare
function ml_z_init(unit) {
caml_custom_ops['_z'] =
{ serialize : caml_zarith_marshal,
deserialize : caml_zarith_unmarshal,
hash : ml_z_hash,
hash : jsoo_z_hash,
compare : ml_z_compare,
};
return 0 }
Expand Down Expand Up @@ -498,13 +498,15 @@ function ml_z_pow(z1, i1) {
return ml_z_normalize(bigInt(z1).pow(i1));
}

//external hash: t -> int
//Provides: ml_z_hash const
//Provides: jsoo_z_hash const
//Requires: bigInt, caml_hash_mix_int
function ml_z_hash(z1) {
var a = bigInt(z1).toArray(Math.pow(2, 32));
function jsoo_z_hash(z1) {
if (!z1) return 0;

z1 = bigInt(z1)
var a = z1.toArray(Math.pow(2, 32));
var acc = 0;
for (var i = 0; i < a.value.length; i++) {
for (var i = a.value.length - 1; i >= 0 ; i--) {
acc = caml_hash_mix_int(acc, a.value[i]);
}
if(a.value.length % 2 != 0) {
Expand All @@ -513,7 +515,14 @@ function ml_z_hash(z1) {
if(a.isNegative){
acc = acc + 1
}
return acc | 0
return acc | 0;
}

//external hash: t -> int
//Provides: ml_z_hash const
//Requires: jsoo_z_hash, caml_hash_mix_final, caml_hash_mix_int
function ml_z_hash(z1) {
return caml_hash_mix_final(caml_hash_mix_int(0, jsoo_z_hash(z1))) & 0x3FFFFFFF
}

//external to_bits: t -> string
Expand Down
2 changes: 1 addition & 1 deletion test/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ module Ml_z_hash = struct
Static.quickcheck ~f:(fun x -> [%message (x : t) (hash x : int)]) ();
[%expect
{|
((hash 1b8bb80aec20e0754b953210f67f7eca) (uniqueness_rate 85.742188)) |}]
((hash 06e8f27264e3dcc3b402b536aa76725a) (uniqueness_rate 85.742188)) |}]
;;
end

0 comments on commit c2b3e1f

Please sign in to comment.