diff --git a/jscomp/others/.depend b/jscomp/others/.depend index 221f3b9e3f..6ff549ebed 100644 --- a/jscomp/others/.depend +++ b/jscomp/others/.depend @@ -28,7 +28,7 @@ bs_internalBuckets.cmj : bs_internalBucketsType.cmj bs_Array.cmj bs_HashMap.cmj : bs_internalBucketsType.cmj bs_internalBuckets.cmj \ bs_Hash.cmj bs_Bag.cmj bs_Array.cmj bs_HashMap.cmi bs_HashSet.cmj : bs_internalSetBuckets.cmj bs_internalBucketsType.cmj \ - bs_Hash.cmj bs_Bag.cmj bs_Array.cmj bs_HashSet.cmi + bs_Hash.cmj bs_Bag.cmj bs_Array.cmj bs.cmj bs_HashSet.cmi bs_HashSetString.cmj : bs_internalSetBuckets.cmj bs_internalBucketsType.cmj \ bs_Array.cmj bs.cmj bs_HashSetString.cmi bs_HashSetInt.cmj : bs_internalSetBuckets.cmj bs_internalBucketsType.cmj \ diff --git a/jscomp/others/bs_HashSet.ml b/jscomp/others/bs_HashSet.ml index 1e9fee3f43..13036d71a3 100644 --- a/jscomp/others/bs_HashSet.ml +++ b/jscomp/others/bs_HashSet.ml @@ -197,3 +197,30 @@ let mem (type a) (type id) (h : (a,id) t) (key : a) = let module M = (val dict) in mem0 ~hash:M.hash ~eq:M.eq data key +let ofArray0 ~hash ~eq arr = + let len = Bs.Array.length arr in + let v = create0 len in + for i = 0 to len - 1 do + add0 ~eq ~hash v (Bs.Array.unsafe_get arr i) + done ; + v + +(* TOOD: optimize heuristics for resizing *) +let addArray0 ~hash ~eq h arr = + let len = Bs.Array.length arr in + for i = 0 to len - 1 do + add0 h ~eq ~hash (Bs_Array.unsafe_get arr i) + done + +let ofArray (type a) (type id) + ~dict:(dict:(a,id) Bs_Hash.t) arr = + let module M = (val dict) in + B.bag ~dict + ~data:M.(ofArray0 ~eq~hash arr) + +let addArray (type a) (type id) + (h : (a,id) t) arr = + let dict,data = B.(dict h, data h) in + let module M = (val dict) in + M.(addArray0 ~hash ~eq data arr) + diff --git a/jscomp/others/bs_HashSet.mli b/jscomp/others/bs_HashSet.mli index 11b64aa088..b8d3906db9 100644 --- a/jscomp/others/bs_HashSet.mli +++ b/jscomp/others/bs_HashSet.mli @@ -1,11 +1,9 @@ - - type ('a, 'id) t0 type ('a, 'id) t = - (('a, 'id) Bs_Hash.t, - ('a, 'id) t0) Bs_Bag.bag - + (('a, 'id) Bs_Hash.t, + ('a, 'id) t0) Bs_Bag.bag + (** The type of hash tables from type ['a] to type ['b]. *) val create0 : int -> ('a, 'id) t0 @@ -62,9 +60,9 @@ val reset : ('a, 'id) t -> unit val add0 : - hash:('a,'id) Bs_Hash.hash -> - eq:('a,'id) Bs_Hash.eq -> - ('a,'id) t0 -> 'a -> unit + hash:('a,'id) Bs_Hash.hash -> + eq:('a,'id) Bs_Hash.eq -> + ('a,'id) t0 -> 'a -> unit val add : ('a, 'id) t -> 'a -> unit (** [Hashtbl.add tbl x y] adds a binding of [x] to [y] in table [tbl]. Previous bindings for [x] are not removed, but simply @@ -85,13 +83,13 @@ val remove0: eq:('a,'id) Bs_Hash.eq -> ('a, 'id) t0 -> 'a -> unit val remove: -('a, 'id) t -> 'a -> unit + ('a, 'id) t -> 'a -> unit (** [Hashtbl.remove tbl x] removes the current binding of [x] in [tbl], restoring the previous binding if it exists. It does nothing if [x] is not bound in [tbl]. *) - + val iter0 : ('a -> unit [@bs]) -> ('a, 'id) t0 -> unit val iter : ('a -> unit [@bs]) -> ('a, 'id) t -> unit @@ -129,7 +127,7 @@ val fold : ('a -> 'c -> 'c [@bs]) -> ('a, 'id) t -> 'c -> 'c of OCaml. For randomized hash tables, the order of enumeration is entirely random. *) - + val length0 : ('a, 'id) t0 -> int val length : ('a, 'id) t -> int (** [Hashtbl.length tbl] returns the number of bindings in [tbl]. @@ -180,3 +178,22 @@ val logStats : _ t -> unit val toArray0 : ('a,'id) t0 -> 'a array val toArray : ('a,'id) t -> 'a array + +val ofArray0 : + hash:('a,'id) Bs_Hash.hash -> + eq:('a,'id) Bs_Hash.eq -> + 'a array -> + ('a, 'id) t0 + +val ofArray : + dict:('a,'id) Bs_Hash.t -> + 'a array -> + ('a,'id) t + +val addArray0 : + hash:('a,'id) Bs_Hash.hash -> + eq:('a,'id) Bs_Hash.eq -> + ('a,'id) t0 -> 'a array -> unit + +val addArray: + ('a,'id) t -> 'a array -> unit \ No newline at end of file diff --git a/jscomp/others/bs_HashSetInt.ml b/jscomp/others/bs_HashSetInt.ml index 3169f87932..41c9727c11 100644 --- a/jscomp/others/bs_HashSetInt.ml +++ b/jscomp/others/bs_HashSetInt.ml @@ -143,4 +143,11 @@ let ofArray arr = for i = 0 to len - 1 do add v (Bs.Array.unsafe_get arr i) done ; - v \ No newline at end of file + v + +(* TOOD: optimize heuristics for resizing *) +let addArray h arr = + let len = Bs.Array.length arr in + for i = 0 to len - 1 do + add h (Bs_Array.unsafe_get arr i) +done \ No newline at end of file diff --git a/jscomp/others/bs_HashSetInt.mli b/jscomp/others/bs_HashSetInt.mli index 208433545c..979837d100 100644 --- a/jscomp/others/bs_HashSetInt.mli +++ b/jscomp/others/bs_HashSetInt.mli @@ -170,4 +170,6 @@ val logStats : t -> unit val toArray : t -> key array -val ofArray : key array -> t \ No newline at end of file +val ofArray : key array -> t + +val addArray : t -> key array -> unit \ No newline at end of file diff --git a/jscomp/others/bs_HashSetString.ml b/jscomp/others/bs_HashSetString.ml index 5ae5dfa9ca..3a71ce1860 100644 --- a/jscomp/others/bs_HashSetString.ml +++ b/jscomp/others/bs_HashSetString.ml @@ -143,4 +143,11 @@ let ofArray arr = for i = 0 to len - 1 do add v (Bs.Array.unsafe_get arr i) done ; - v \ No newline at end of file + v + +(* TOOD: optimize heuristics for resizing *) +let addArray h arr = + let len = Bs.Array.length arr in + for i = 0 to len - 1 do + add h (Bs_Array.unsafe_get arr i) +done \ No newline at end of file diff --git a/jscomp/others/bs_HashSetString.mli b/jscomp/others/bs_HashSetString.mli index b66051f161..5e5b82d8a6 100644 --- a/jscomp/others/bs_HashSetString.mli +++ b/jscomp/others/bs_HashSetString.mli @@ -170,4 +170,6 @@ val logStats : t -> unit val toArray : t -> key array -val ofArray : key array -> t \ No newline at end of file +val ofArray : key array -> t + +val addArray : t -> key array -> unit \ No newline at end of file diff --git a/jscomp/others/hashset.cppo.ml b/jscomp/others/hashset.cppo.ml index 6f07f30843..a22ffcb2ab 100644 --- a/jscomp/others/hashset.cppo.ml +++ b/jscomp/others/hashset.cppo.ml @@ -14,7 +14,7 @@ let hash (s : key) = final_mix (caml_hash_mix_int 0 s) #else [%error "unknown type"] -#endif + #endif module N = Bs_internalSetBuckets module C = Bs_internalBucketsType @@ -152,4 +152,11 @@ let ofArray arr = for i = 0 to len - 1 do add v (Bs.Array.unsafe_get arr i) done ; - v \ No newline at end of file + v + +(* TOOD: optimize heuristics for resizing *) +let addArray h arr = + let len = Bs.Array.length arr in + for i = 0 to len - 1 do + add h (Bs_Array.unsafe_get arr i) +done \ No newline at end of file diff --git a/jscomp/others/hashset.cppo.mli b/jscomp/others/hashset.cppo.mli index 7cd0d1f713..74e4b66861 100644 --- a/jscomp/others/hashset.cppo.mli +++ b/jscomp/others/hashset.cppo.mli @@ -174,4 +174,6 @@ val logStats : t -> unit val toArray : t -> key array -val ofArray : key array -> t \ No newline at end of file +val ofArray : key array -> t + +val addArray : t -> key array -> unit \ No newline at end of file diff --git a/jscomp/test/bs_hashset_int_test.js b/jscomp/test/bs_hashset_int_test.js index a3cb648510..89dde3137d 100644 --- a/jscomp/test/bs_hashset_int_test.js +++ b/jscomp/test/bs_hashset_int_test.js @@ -38,6 +38,26 @@ var xs = Bs_SetInt.toArray(Bs_SetInt.ofArray(Bs_HashSetInt.toArray(v))); eq("File \"bs_hashset_int_test.ml\", line 19, characters 5-12", xs, Array_data_util.range(30, 120)); +var u$1 = Bs_Array.append(Array_data_util.randomRange(0, 100000), Array_data_util.randomRange(0, 100)); + +var v$1 = Bs_HashSetInt.create(40); + +Bs_HashSetInt.addArray(v$1, u$1); + +eq("File \"bs_hashset_int_test.ml\", line 25, characters 5-12", Bs_HashSetInt.length(v$1), 100001); + +for(var i = 0; i <= 1000; ++i){ + Bs_HashSetInt.remove(v$1, i); +} + +eq("File \"bs_hashset_int_test.ml\", line 29, characters 5-12", Bs_HashSetInt.length(v$1), 99000); + +for(var i$1 = 0; i$1 <= 2000; ++i$1){ + Bs_HashSetInt.remove(v$1, i$1); +} + +eq("File \"bs_hashset_int_test.ml\", line 33, characters 5-12", Bs_HashSetInt.length(v$1), 98000); + Mt.from_pair_suites("bs_hashset_int_test.ml", suites[0]); var N = 0; diff --git a/jscomp/test/bs_hashset_int_test.ml b/jscomp/test/bs_hashset_int_test.ml index 0783a598fc..9d61af6547 100644 --- a/jscomp/test/bs_hashset_int_test.ml +++ b/jscomp/test/bs_hashset_int_test.ml @@ -17,5 +17,18 @@ let () = eq __LOC__ (N.length v) 91 ; let xs = S.toArray (S.ofArray (N.toArray v)) in eq __LOC__ xs (I.range 30 120) + +let () = + let u = I.randomRange 0 100_000 ++ I.randomRange 0 100 in + let v = N.create 40 in + N.addArray v u ; + eq __LOC__ (N.length v) 100_001; + for i = 0 to 1_000 do + N.remove v i + done ; + eq __LOC__ (N.length v ) 99_000; + for i = 0 to 2_000 do + N.remove v i + done ; + eq __LOC__ (N.length v ) 98_000 let () = Mt.from_pair_suites __FILE__ !suites - \ No newline at end of file diff --git a/lib/js/bs_HashSet.js b/lib/js/bs_HashSet.js index ac28f1e3b5..3902f0878b 100644 --- a/lib/js/bs_HashSet.js +++ b/lib/js/bs_HashSet.js @@ -212,6 +212,36 @@ function mem(h, key) { return mem0(dict[/* hash */0], dict[/* eq */1], data, key); } +function ofArray0(hash, eq, arr) { + var len = arr.length; + var v = Bs_internalBucketsType.create0(len); + for(var i = 0 ,i_finish = len - 1 | 0; i <= i_finish; ++i){ + add0(hash, eq, v, arr[i]); + } + return v; +} + +function addArray0(hash, eq, h, arr) { + var len = arr.length; + for(var i = 0 ,i_finish = len - 1 | 0; i <= i_finish; ++i){ + add0(hash, eq, h, arr[i]); + } + return /* () */0; +} + +function ofArray(dict, arr) { + return { + dict: dict, + data: ofArray0(dict[/* hash */0], dict[/* eq */1], arr) + }; +} + +function addArray(h, arr) { + var dict = h.dict; + var data = h.data; + return addArray0(dict[/* hash */0], dict[/* eq */1], data, arr); +} + var create0 = Bs_internalBucketsType.create0; var clear0 = Bs_internalBucketsType.clear0; @@ -250,4 +280,8 @@ exports.logStats0 = logStats0; exports.logStats = logStats; exports.toArray0 = toArray0; exports.toArray = toArray; +exports.ofArray0 = ofArray0; +exports.ofArray = ofArray; +exports.addArray0 = addArray0; +exports.addArray = addArray; /* Bs_internalBucketsType Not a pure module */ diff --git a/lib/js/bs_HashSetInt.js b/lib/js/bs_HashSetInt.js index 239cbacb2c..d5a57f4e72 100644 --- a/lib/js/bs_HashSetInt.js +++ b/lib/js/bs_HashSetInt.js @@ -174,6 +174,14 @@ function ofArray(arr) { return v; } +function addArray(h, arr) { + var len = arr.length; + for(var i = 0 ,i_finish = len - 1 | 0; i <= i_finish; ++i){ + add(h, arr[i]); + } + return /* () */0; +} + var create = Bs_internalBucketsType.create0; var clear = Bs_internalBucketsType.clear0; @@ -202,4 +210,5 @@ exports.length = length; exports.logStats = logStats; exports.toArray = toArray; exports.ofArray = ofArray; +exports.addArray = addArray; /* Bs_internalBucketsType Not a pure module */ diff --git a/lib/js/bs_HashSetString.js b/lib/js/bs_HashSetString.js index a88a93f779..342c4b36ad 100644 --- a/lib/js/bs_HashSetString.js +++ b/lib/js/bs_HashSetString.js @@ -174,6 +174,14 @@ function ofArray(arr) { return v; } +function addArray(h, arr) { + var len = arr.length; + for(var i = 0 ,i_finish = len - 1 | 0; i <= i_finish; ++i){ + add(h, arr[i]); + } + return /* () */0; +} + var create = Bs_internalBucketsType.create0; var clear = Bs_internalBucketsType.clear0; @@ -202,4 +210,5 @@ exports.length = length; exports.logStats = logStats; exports.toArray = toArray; exports.ofArray = ofArray; +exports.addArray = addArray; /* Bs_internalBucketsType Not a pure module */