Skip to content

Commit f796255

Browse files
committed
add toArray, addArray in hashMap
1 parent 84c431b commit f796255

17 files changed

+257
-519
lines changed

jscomp/others/.depend

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ bs_Queue.cmj : bs_Array.cmj bs_Queue.cmi
2525
bs_List.cmj : js_json.cmj bs_Array.cmj bs_List.cmi
2626
bs_internalBucketsType.cmj : bs_Array.cmj
2727
bs_internalSetBuckets.cmj : bs_internalBucketsType.cmj bs_Array.cmj bs.cmj
28-
bs_internalBuckets.cmj : bs_internalBucketsType.cmj bs_Array.cmj
28+
bs_internalBuckets.cmj : bs_internalBucketsType.cmj bs_Array.cmj bs.cmj
2929
bs_HashMap.cmj : bs_internalBucketsType.cmj bs_internalBuckets.cmj \
3030
bs_Hash.cmj bs_Bag.cmj bs_Array.cmj bs_HashMap.cmi
3131
bs_HashSet.cmj : bs_internalSetBuckets.cmj bs_internalBucketsType.cmj \
@@ -53,9 +53,9 @@ js_global.cmj :
5353
js_cast.cmj : js_cast.cmi
5454
js_promise.cmj :
5555
bs_HashMapInt.cmj : bs_internalBucketsType.cmj bs_internalBuckets.cmj \
56-
bs_Array.cmj bs_HashMapInt.cmi
56+
bs_Array.cmj bs.cmj bs_HashMapInt.cmi
5757
bs_HashMapString.cmj : bs_internalBucketsType.cmj bs_internalBuckets.cmj \
58-
bs_Array.cmj bs_HashMapString.cmi
58+
bs_Array.cmj bs.cmj bs_HashMapString.cmi
5959
node_process.cmi : js_dict.cmi
6060
js_re.cmi :
6161
js_null_undefined.cmi :

jscomp/others/bs_HashMap.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -261,5 +261,5 @@ let mem (type a) (type b) (type id) (h : (a,b,id) t) (key : a) =
261261
let module M = (val dict) in
262262
mem0 ~hash:M.hash ~eq:M.eq data key
263263

264-
let filterMapInplace f h =
265-
filterMapInplace0 f (B.data h)
264+
let filterMapInplace h f =
265+
filterMapInplace0 (B.data h) f

jscomp/others/bs_HashMap.mli

+2-31
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ val fold : ('a, 'b, 'id) t -> 'c -> ('a -> 'b -> 'c -> 'c [@bs]) -> 'c
163163
of OCaml. For randomized hash tables, the order of enumeration
164164
is entirely random. *)
165165

166-
val filterMapInplace0 : ('a -> 'b -> 'b option [@bs]) -> ('a, 'b, 'id) t0 -> unit
167-
val filterMapInplace : ('a -> 'b -> 'b option [@bs]) -> ('a, 'b, 'id) t -> unit
166+
val filterMapInplace0 : ('a, 'b, 'id) t0 -> ('a -> 'b -> 'b option [@bs]) -> unit
167+
val filterMapInplace : ('a, 'b, 'id) t -> ('a -> 'b -> 'b option [@bs]) -> unit
168168

169169
val length0 : ('a, 'b, 'id) t0 -> int
170170
val length : ('a, 'b, 'id) t -> int
@@ -196,36 +196,7 @@ val logStats : _ t -> unit
196196
buckets by size.
197197
@since 4.00.0 *)
198198

199-
(** {6 Functorial interface} *)
200199

201-
(** The functorial interface allows the use of specific comparison
202-
and hash functions, either for performance/security concerns,
203-
or because keys are not hashable/comparable with the polymorphic builtins.
204-
205-
For instance, one might want to specialize a table for integer keys:
206-
{[
207-
module IntHash =
208-
struct
209-
type t = int
210-
let equal i j = i=j
211-
let hash i = i land max_int
212-
end
213-
214-
module IntHashtbl = Hashtbl.Make(IntHash)
215-
216-
let h = IntHashtbl.create 17 in
217-
IntHashtbl.add h 12 "hello";;
218-
]}
219-
220-
This creates a new module [IntHashtbl], with a new type ['a
221-
IntHashtbl.t] of tables from [int] to ['a]. In this example, [h]
222-
contains [string] values so its type is [string IntHashtbl.t].
223-
224-
Note that the new type ['a IntHashtbl.t] is not compatible with
225-
the type [('a,'b) Hashtbl.t] of the generic interface. For
226-
example, [Hashtbl.length h] would not type-check, you must use
227-
[IntHashtbl.length].
228-
*)
229200

230201

231202

jscomp/others/bs_HashMapInt.ml

+18-1
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,21 @@ let iter = N.iter0
203203
let fold = N.fold0
204204
let logStats = N.logStats0
205205
let filterMapInplace = N.filterMapInplace0
206-
206+
let toArray = N.toArray0
207+
208+
let ofArray arr =
209+
let len = Bs.Array.length arr in
210+
let v = create len in
211+
for i = 0 to len - 1 do
212+
let k,value = (Bs.Array.unsafe_get arr i) in
213+
add v k value
214+
done ;
215+
v
216+
217+
(* TOOD: optimize heuristics for resizing *)
218+
let addArray h arr =
219+
let len = Bs.Array.length arr in
220+
for i = 0 to len - 1 do
221+
let k,v = (Bs_Array.unsafe_get arr i) in
222+
add h k v
223+
done

jscomp/others/bs_HashMapInt.mli

+12-158
Original file line numberDiff line numberDiff line change
@@ -7,44 +7,6 @@ type 'b t
77

88

99
val create : int -> 'b t
10-
(** [Hashtbl.create n] creates a new, empty hash table, with
11-
initial size [n]. For best results, [n] should be on the
12-
order of the expected number of elements that will be in
13-
the table. The table grows as needed, so [n] is just an
14-
initial guess.
15-
16-
The optional [random] parameter (a boolean) controls whether
17-
the internal organization of the hash table is randomized at each
18-
execution of [Hashtbl.create] or deterministic over all executions.
19-
20-
A hash table that is created with [~random:false] uses a
21-
fixed hash function ({!Hashtbl.hash}) to distribute keys among
22-
buckets. As a consequence, collisions between keys happen
23-
deterministically. In Web-facing applications or other
24-
security-sensitive applications, the deterministic collision
25-
patterns can be exploited by a malicious user to create a
26-
denial-of-service attack: the attacker sends input crafted to
27-
create many collisions in the table, slowing the application down.
28-
29-
A hash table that is created with [~random:true] uses the seeded
30-
hash function {!Hashtbl.seeded_hash} with a seed that is randomly
31-
chosen at hash table creation time. In effect, the hash function
32-
used is randomly selected among [2^{30}] different hash functions.
33-
All these hash functions have different collision patterns,
34-
rendering ineffective the denial-of-service attack described above.
35-
However, because of randomization, enumerating all elements of the
36-
hash table using {!Hashtbl.fold} or {!Hashtbl.iter} is no longer
37-
deterministic: elements are enumerated in different orders at
38-
different runs of the program.
39-
40-
If no [~random] parameter is given, hash tables are created
41-
in non-random mode by default. This default can be changed
42-
either programmatically by calling {!Hashtbl.randomize} or by
43-
setting the [R] flag in the [OCAMLRUNPARAM] environment variable.
44-
45-
@before 4.00.0 the [random] parameter was not present and all
46-
hash tables were created in non-randomized mode. *)
47-
4810

4911
val clear : 'b t -> unit
5012
(** Empty a hash table. Use [reset] instead of [clear] to shrink the
@@ -56,146 +18,38 @@ val reset : 'b t -> unit
5618
to its initial size.
5719
@since 4.00.0 *)
5820

21+
val add : 'a t -> key -> 'a -> unit
5922

23+
val findOpt: 'a t -> key -> 'a option
6024

61-
62-
val add : 'b t -> key -> 'b -> unit
63-
(** [Hashtbl.add tbl x y] adds a binding of [x] to [y] in table [tbl].
64-
Previous bindings for [x] are not removed, but simply
65-
hidden. That is, after performing {!Hashtbl.remove}[ tbl x],
66-
the previous binding for [x], if any, is restored.
67-
(Same behavior as with association lists.) *)
68-
69-
val findOpt:
70-
'b t -> key -> 'b option
71-
(** [findOpt tbl x] returns the current binding of [x] in [tbl],
72-
*)
73-
74-
val findAll: 'b t -> key -> 'b list
25+
val findAll: 'a t -> key -> 'a list
7526
(** [Hashtbl.find_all tbl x] returns the list of all data
7627
associated with [x] in [tbl].
7728
The current binding is returned first, then the previous
7829
bindings, in reverse order of introduction in the table. *)
7930

80-
val mem:
81-
'b t -> key -> bool
82-
(** [Hashtbl.mem tbl x] checks if [x] is bound in [tbl]. *)
31+
val mem: 'b t -> key -> bool
8332

84-
val remove:
85-
'b t -> key -> unit
86-
(** [Hashtbl.remove tbl x] removes the current binding of [x] in [tbl],
87-
restoring the previous binding if it exists.
88-
It does nothing if [x] is not bound in [tbl]. *)
33+
val remove: 'a t -> key -> unit
8934

90-
val removeAll:
91-
'b t -> key -> unit
35+
val removeAll: 'b t -> key -> unit
9236

93-
94-
val replace:
95-
'b t -> key -> 'b -> unit
96-
(** [Hashtbl.replace tbl x y] replaces the current binding of [x]
97-
in [tbl] by a binding of [x] to [y]. If [x] is unbound in [tbl],
98-
a binding of [x] to [y] is added to [tbl].
99-
This is functionally equivalent to {!Hashtbl.remove}[ tbl x]
100-
followed by {!Hashtbl.add}[ tbl x y]. *)
37+
val replace: 'b t -> key -> 'b -> unit
10138

10239

10340
val iter : 'b t -> (key -> 'b -> unit [@bs]) -> unit
104-
(** [Hashtbl.iter f tbl] applies [f] to all bindings in table [tbl].
105-
[f] receives the key as first argument, and the associated value
106-
as second argument. Each binding is presented exactly once to [f].
107-
108-
The order in which the bindings are passed to [f] is unspecified.
109-
However, if the table contains several bindings for the same key,
110-
they are passed to [f] in reverse order of introduction, that is,
111-
the most recent binding is passed first.
112-
113-
If the hash table was created in non-randomized mode, the order
114-
in which the bindings are enumerated is reproducible between
115-
successive runs of the program, and even between minor versions
116-
of OCaml. For randomized hash tables, the order of enumeration
117-
is entirely random. *)
118-
11941

12042
val fold : 'b t -> 'c -> (key -> 'b -> 'c -> 'c [@bs]) -> 'c
121-
(** [Hashtbl.fold f tbl init] computes
122-
[(f kN dN ... (f k1 d1 init)...)],
123-
where [k1 ... kN] are the keys of all bindings in [tbl],
124-
and [d1 ... dN] are the associated values.
125-
Each binding is presented exactly once to [f].
126-
127-
The order in which the bindings are passed to [f] is unspecified.
128-
However, if the table contains several bindings for the same key,
129-
they are passed to [f] in reverse order of introduction, that is,
130-
the most recent binding is passed first.
131-
132-
If the hash table was created in non-randomized mode, the order
133-
in which the bindings are enumerated is reproducible between
134-
successive runs of the program, and even between minor versions
135-
of OCaml. For randomized hash tables, the order of enumeration
136-
is entirely random. *)
13743

13844

139-
val filterMapInplace : (key -> 'b -> 'b option [@bs]) -> 'b t -> unit
45+
val filterMapInplace : 'a t -> (key -> 'a -> 'a option [@bs]) -> unit
14046

141-
val length : 'b t -> int
142-
(** [Hashtbl.length tbl] returns the number of bindings in [tbl].
143-
It takes constant time. Multiple bindings are counted once each, so
144-
[Hashtbl.length] gives the number of times [Hashtbl.iter] calls its
145-
first argument. *)
146-
147-
148-
(*
149-
type statistics = {
150-
num_bindings: int;
151-
(** Number of bindings present in the table.
152-
Same value as returned by {!Hashtbl.length}. *)
153-
num_buckets: int;
154-
(** Number of buckets in the table. *)
155-
max_bucket_length: int;
156-
(** Maximal number of bindings per bucket. *)
157-
bucket_histogram: int array
158-
(** Histogram of bucket sizes. This array [histo] has
159-
length [max_bucket_length + 1]. The value of
160-
[histo.(i)] is the number of buckets whose size is [i]. *)
161-
} *)
162-
47+
val length : _ t -> int
16348
val logStats : _ t -> unit
164-
(** [Hashtbl.stats tbl] returns statistics about the table [tbl]:
165-
number of buckets, size of the biggest bucket, distribution of
166-
buckets by size.
167-
@since 4.00.0 *)
168-
169-
(** {6 Functorial interface} *)
170-
171-
(** The functorial interface allows the use of specific comparison
172-
and hash functions, either for performance/security concerns,
173-
or because keys are not hashable/comparable with the polymorphic builtins.
174-
175-
For instance, one might want to specialize a table for integer keys:
176-
{[
177-
module IntHash =
178-
struct
179-
type t = int
180-
let equal i j = i=j
181-
let hash i = i land max_int
182-
end
183-
184-
module IntHashtbl = Hashtbl.Make(IntHash)
185-
186-
let h = IntHashtbl.create 17 in
187-
IntHashtbl.add h 12 "hello";;
188-
]}
189-
190-
This creates a new module [IntHashtbl], with a new type ['a
191-
IntHashtbl.t] of tables from [int] to ['a]. In this example, [h]
192-
contains [string] values so its type is [string IntHashtbl.t].
19349

194-
Note that the new type ['a IntHashtbl.t] is not compatible with
195-
the type [('a,'b) Hashtbl.t] of the generic interface. For
196-
example, [Hashtbl.length h] would not type-check, you must use
197-
[IntHashtbl.length].
198-
*)
50+
val toArray : 'a t -> (key * 'a) array
51+
val ofArray : (key * 'a) array -> 'a t
52+
val addArray : 'a t -> (key * 'a) array -> unit
19953

20054

20155

jscomp/others/bs_HashMapString.ml

+18-1
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,21 @@ let iter = N.iter0
203203
let fold = N.fold0
204204
let logStats = N.logStats0
205205
let filterMapInplace = N.filterMapInplace0
206-
206+
let toArray = N.toArray0
207+
208+
let ofArray arr =
209+
let len = Bs.Array.length arr in
210+
let v = create len in
211+
for i = 0 to len - 1 do
212+
let k,value = (Bs.Array.unsafe_get arr i) in
213+
add v k value
214+
done ;
215+
v
216+
217+
(* TOOD: optimize heuristics for resizing *)
218+
let addArray h arr =
219+
let len = Bs.Array.length arr in
220+
for i = 0 to len - 1 do
221+
let k,v = (Bs_Array.unsafe_get arr i) in
222+
add h k v
223+
done

0 commit comments

Comments
 (0)