Skip to content

Commit

Permalink
Merge d1457a0 into b7d0dec
Browse files Browse the repository at this point in the history
  • Loading branch information
bobzhang committed Jan 29, 2018
2 parents b7d0dec + d1457a0 commit 061e3f2
Show file tree
Hide file tree
Showing 24 changed files with 598 additions and 760 deletions.
6 changes: 3 additions & 3 deletions jscomp/others/.depend
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ bs_HashMap.cmj : bs_internalBucketsType.cmj bs_internalBuckets.cmj \
bs_HashMultiMap.cmj : bs_internalBucketsType.cmj bs_internalBuckets.cmj \
bs_Hash.cmj bs_Array.cmj bs_HashMultiMap.cmi
bs_HashSet.cmj : bs_internalSetBuckets.cmj bs_internalBucketsType.cmj \
bs_HashSetString.cmj bs_HashSetInt.cmj bs_Hash.cmj bs_Array.cmj bs.cmj \
bs_HashSetString.cmj bs_HashSetInt.cmj bs_Hash.cmj bs_Array.cmj \
bs_HashSet.cmi
bs_HashSetString.cmj : bs_internalSetBuckets.cmj bs_internalBucketsType.cmj \
bs_Array.cmj bs.cmj bs_HashSetString.cmi
bs_Array.cmj bs_HashSetString.cmi
bs_HashSetInt.cmj : bs_internalSetBuckets.cmj bs_internalBucketsType.cmj \
bs_Array.cmj bs.cmj bs_HashSetInt.cmi
bs_Array.cmj bs_HashSetInt.cmi
bs_Bag.cmj :
bs_BagM.cmj :
bs_Cmp.cmj : bs_Cmp.cmi
Expand Down
122 changes: 53 additions & 69 deletions jscomp/others/bs_HashMap.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type ('a,'b,'id) t =



let rec copyBucketReHash ~hash ~h_buckets ~ndata_tail h old_bucket =
let rec copyBucketReHash ~hash ~h_buckets ~ndata_tail old_bucket =
match C.toOpt old_bucket with
| None -> ()
| Some cell ->
Expand All @@ -38,19 +38,19 @@ let rec copyBucketReHash ~hash ~h_buckets ~ndata_tail h old_bucket =
N.nextSet tail v (* cell put at the end *)
end;
A.setUnsafe ndata_tail nidx v;
copyBucketReHash ~hash ~h_buckets ~ndata_tail h (N.next cell)
copyBucketReHash ~hash ~h_buckets ~ndata_tail (N.next cell)


let resize ~hash h =
let odata = C.buckets h in
let osize = Array.length odata in
let osize = A.length odata in
let nsize = osize * 2 in
if nsize >= osize then begin (* no overflow *)
let h_buckets = A.makeUninitialized nsize in
let ndata_tail = A.makeUninitialized nsize in (* keep track of tail *)
C.bucketsSet h h_buckets; (* so that indexfun sees the new bucket count *)
for i = 0 to osize - 1 do
copyBucketReHash ~hash ~h_buckets ~ndata_tail h (A.getUnsafe odata i)
copyBucketReHash ~hash ~h_buckets ~ndata_tail (A.getUnsafe odata i)
done;
for i = 0 to nsize - 1 do
match C.toOpt (A.getUnsafe ndata_tail i) with
Expand All @@ -72,28 +72,29 @@ let rec replaceInBucket ~eq key info cell =
| Some cell ->
replaceInBucket ~eq key info cell

(* if [key] already exists, replace it, otherwise add it
Here we add it to the head, it could be tail
*)
let setDone0 ~hash ~eq h key value =
let set0 h key value ~eq ~hash =
let h_buckets = C.buckets h in
let i = (Bs_Hash.getHashInternal hash) key [@bs] land (Array.length h_buckets - 1) in
let l = Array.unsafe_get h_buckets i in
match C.toOpt l with
let buckets_len = A.length h_buckets in
let i = (Bs_Hash.getHashInternal hash) key [@bs] land (buckets_len - 1) in
let l = A.getUnsafe h_buckets i in
(match C.toOpt l with
| None ->
A.setUnsafe h_buckets i (C.return (N.bucket ~key ~value ~next:l));
A.setUnsafe h_buckets i (C.return (N.bucket ~key ~value ~next:C.emptyOpt));
C.sizeSet h (C.size h + 1);
if C.size h > Array.length (C.buckets h) lsl 1 then resize ~hash h
(* do we really need resize here ? *)
| Some bucket ->
begin
if replaceInBucket ~eq key value bucket then begin
A.setUnsafe h_buckets i (C.return (N.bucket ~key ~value ~next:l));
C.sizeSet h (C.size h + 1);
if C.size h > Array.length (C.buckets h) lsl 1 then resize ~hash h
(* TODO: duplicate bucklets ? *)
end
end
);
if C.size h > buckets_len lsl 1 then resize ~hash h

(* if [key] already exists, replace it, otherwise add it
Here we add it to the head, it could be tail
*)
let set h key value =
let eq, hash = C.eq h, C.hash h in
set0 h key value ~eq ~hash

let rec removeInBucket h h_buckets i key prec bucket ~eq =
match C.toOpt bucket with
Expand All @@ -108,9 +109,11 @@ let rec removeInBucket h h_buckets i key prec bucket ~eq =
end
else removeInBucket ~eq h h_buckets i key cell cell_next

let remove0 ~hash ~eq h key =

let remove h key =
let eq = C.eq h in
let h_buckets = C.buckets h in
let i = (Bs_Hash.getHashInternal hash) key [@bs] land (Array.length h_buckets - 1) in
let i = (Bs_Hash.getHashInternal (C.hash h)) key [@bs] land (A.length h_buckets - 1) in
let bucket = A.getUnsafe h_buckets i in
match C.toOpt bucket with
| None -> ()
Expand All @@ -124,49 +127,49 @@ let remove0 ~hash ~eq h key =
removeInBucket ~eq h h_buckets i key cell (N.next cell)


let rec findAux ~eq key buckets =
let rec getAux ~eq key buckets =
match C.toOpt buckets with
| None ->
None
| Some cell ->
if (Bs_Hash.getEqInternal eq) key (N.key cell) [@bs] then Some (N.value cell)
else findAux ~eq key (N.next cell)
if eq key (N.key cell) [@bs] then Some (N.value cell)
else getAux ~eq key (N.next cell)

let get0 ~hash ~eq h key =
let get h key =
let eq = Bs_Hash.getEqInternal (C.eq h) in
let h_buckets = C.buckets h in
let nid = (Bs_Hash.getHashInternal hash) key [@bs] land (Array.length h_buckets - 1) in
let nid = (Bs_Hash.getHashInternal (C.hash h)) key [@bs] land (A.length h_buckets - 1) in
match C.toOpt @@ A.getUnsafe h_buckets nid with
| None -> None
| Some cell1 ->
if (Bs_Hash.getEqInternal eq) key (N.key cell1) [@bs] then
if eq key (N.key cell1) [@bs] then
Some (N.value cell1)
else
match C.toOpt (N.next cell1) with
| None -> None
| Some cell2 ->
if (Bs_Hash.getEqInternal eq) key
(N.key cell2) [@bs] then
if eq key (N.key cell2) [@bs] then
Some (N.value cell2) else
match C.toOpt (N.next cell2) with
| None -> None
| Some cell3 ->
if (Bs_Hash.getEqInternal eq) key
(N.key cell3) [@bs] then
if eq key (N.key cell3) [@bs] then
Some (N.value cell3)
else
findAux ~eq key (N.next cell3)
getAux ~eq key (N.next cell3)


let rec memInBucket ~eq key cell =
(Bs_Hash.getEqInternal eq) (N.key cell) key [@bs] ||
eq (N.key cell) key [@bs] ||
(match C.toOpt (N.next cell) with
| None -> false
| Some nextCell ->
memInBucket ~eq key nextCell)

let has0 ~hash ~eq h key =
let has h key =
let eq = Bs_Hash.getEqInternal (C.eq h) in
let h_buckets = C.buckets h in
let nid = (Bs_Hash.getHashInternal hash) key [@bs] land (Array.length h_buckets - 1) in
let nid = (Bs_Hash.getHashInternal (C.hash h)) key [@bs] land (A.length h_buckets - 1) in
let bucket = A.getUnsafe h_buckets nid in
match C.toOpt bucket with
| None -> false
Expand All @@ -185,55 +188,36 @@ let size = C.size
let forEach = N.forEach
let reduce = N.reduce
let logStats = N.logStats

let set h key info =
setDone0 ~hash:(C.hash h) ~eq:(C.eq h) h key info

let remove h key =
remove0 ~hash:(C.hash h) ~eq:(C.eq h) h key

let get h key =
get0 ~hash:(C.hash h) ~eq:(C.eq h) h key

let has h key =
has0 ~hash:(C.hash h) ~eq:(C.eq h) h key

let keepMapInPlace = N.keepMapInPlace

let toArray = N.toArray
let copy = N.copy
let keysToArray = N.keysToArray
let valuesToArray = N.valuesToArray
let getBucketHistogram = N.getBucketHistogram
let isEmpty = C.isEmpty


let ofArray0 arr ~hash ~eq =


let ofArray (type a) (type id) arr ~dict:(dict:(a,id) Bs_Hash.t) =
let module M = (val dict) in
let eq, hash = M.eq, M.hash in
let len = A.length arr in
let v = C.make ~hash ~eq len in
for i = 0 to len - 1 do
let key,value = (A.getUnsafe arr i) in
setDone0 ~eq ~hash v key value
set0 ~eq ~hash v key value
done ;
v

(* TOOD: optimize heuristics for resizing *)
let mergeArrayDone0 h arr ~hash ~eq =
let mergeMany h arr =
let hash, eq = C.hash h , C.eq h in
let len = A.length arr in
for i = 0 to len - 1 do
let key,value = (A.getUnsafe arr i) in
setDone0 h ~eq ~hash key value
set0 h ~eq ~hash key value
done

let ofArray (type a) (type id) arr ~dict:(dict:(a,id) Bs_Hash.t) =
let module M = (val dict) in
ofArray0 ~eq:M.eq ~hash:M.hash arr


let mergeMany h arr =
mergeArrayDone0 ~hash:(C.hash h) ~eq:(C.eq h) h arr


let copy = N.copy

let keysToArray = N.keysToArray
let valuesToArray = N.valuesToArray
let getBucketHistogram = N.getBucketHistogram
let isEmpty h = C.size h = 0

module Int = Bs_HashMapInt
module String = Bs_HashMapString
27 changes: 9 additions & 18 deletions jscomp/others/bs_HashMap.mli
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,21 @@ val size: _ t -> int



val logStats: _ t -> unit
(** [logStats tbl] returns statistics about the table [tbl]:
number of buckets, size of the biggest bucket, distribution of
buckets by size.
*)




val toArray: ('key, 'value, 'id ) t -> ('key * 'value) array




val ofArray: ('key * 'value) array -> dict:('key,'id) Bs_Hash.t -> ('key, 'value, 'id ) t

val keysToArray: ('key, _, _) t -> 'key array
val valuesToArray: (_,'value,_) t -> 'value array
val ofArray: ('key * 'value) array -> dict:('key,'id) Bs_Hash.t -> ('key, 'value, 'id ) t
val mergeMany: ('key, 'value, 'id ) t -> ('key * 'value) array -> unit

val keysToArray:
('key, _, _) t -> 'key array
val valuesToArray:
(_,'value,_) t -> 'value array

val getBucketHistogram: _ t -> int array
val logStats: _ t -> unit
(** [logStats tbl] returns statistics about the table [tbl]:
number of buckets, size of the biggest bucket, distribution of
buckets by size.
*)



module Int = Bs_HashMapInt
Expand Down

0 comments on commit 061e3f2

Please sign in to comment.