diff --git a/jscomp/bin/all_ounit_tests.i.ml b/jscomp/bin/all_ounit_tests.i.ml index 7f14da9465..48baaa23f5 100644 --- a/jscomp/bin/all_ounit_tests.i.ml +++ b/jscomp/bin/all_ounit_tests.i.ml @@ -3504,20 +3504,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = (* 4103 *) let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = (* 0 *) let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -3526,7 +3530,7 @@ let check_add (h : _ Hash_set_gen.t) key = let mem (h : _ Hash_set_gen.t) key = (* 3102 *) Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data (key_index h key)) -# 106 +# 110 end @@ -3641,20 +3645,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = (* 15004 *) let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = (* 0 *) let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -4069,20 +4077,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = (* 101 *) let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = (* 8 *) let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -4319,20 +4331,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = (* 0 *) let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = (* 0 *) let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -4665,10 +4681,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = (* 2000 *) let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -4679,43 +4695,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> (* 0 *) true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + (* 0 *) match bucketlist with + | Empty -> + (* 0 *) Empty + | Cons(k, i, next) -> + (* 0 *) if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - (* 0 *) let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = (* 0 *) match bucketlist with - | Empty -> - (* 0 *) Empty - | Cons(k, i, next) -> - (* 0 *) if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in - let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + (* 0 *) let i = key_index h key in + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = (* 0 *) match bucketlist with | Empty -> - (* 0 *) raise Not_found + (* 0 *) raise Not_found | Cons(k, d, rest) -> - (* 0 *) if eq_key key k then d else find_rec key rest + (* 0 *) if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - (* 0 *) match h.data.(key_index h key) with + (* 0 *) match Array.unsafe_get h.data (key_index h key) with | Empty -> (* 0 *) raise Not_found | Cons(k1, d1, rest1) -> - (* 0 *) if eq_key key k1 then d1 else + (* 0 *) if eq_key key k1 then d1 else match rest1 with | Empty -> (* 0 *) raise Not_found | Cons(k2, d2, rest2) -> - (* 0 *) if eq_key key k2 then d2 else + (* 0 *) if eq_key key k2 then d2 else match rest2 with | Empty -> (* 0 *) raise Not_found | Cons(k3, d3, rest3) -> - (* 0 *) if eq_key key k3 then d3 else find_rec key rest3 + (* 0 *) if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = (* 0 *) Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -4723,42 +4747,46 @@ let find_default (h : _ t) key default = (* 0 *) Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = (* 0 *) let rec find_in_bucket (bucketlist : _ bucketlist) = (* 0 *) match bucketlist with - | Empty -> + | Empty -> (* 0 *) [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> (* 0 *) if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = (* 2000 *) let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = (* 4462 *) match bucketlist with | Empty -> - (* 1000 *) raise_notrace Not_found + (* 1000 *) raise_notrace Not_found | Cons(k, i, next) -> - (* 3462 *) if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + (* 3462 *) if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = (* 0 *) let rec mem_in_bucket (bucketlist : _ bucketlist) = (* 0 *) match bucketlist with - | Empty -> + | Empty -> (* 0 *) false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> (* 0 *) eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - (* 0 *) let map = create 51 in + (* 0 *) let len = List.length ks in + let map = create len in List.iter2 (fun k v -> (* 0 *) add map k v) ks vs ; map diff --git a/jscomp/bin/all_ounit_tests.ml b/jscomp/bin/all_ounit_tests.ml index eba6c154af..eaafd8cd29 100644 --- a/jscomp/bin/all_ounit_tests.ml +++ b/jscomp/bin/all_ounit_tests.ml @@ -3504,20 +3504,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -3526,7 +3530,7 @@ let check_add (h : _ Hash_set_gen.t) key = let mem (h : _ Hash_set_gen.t) key = Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data (key_index h key)) -# 106 +# 110 end @@ -3641,20 +3645,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -4069,20 +4077,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -4319,20 +4331,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -4665,10 +4681,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -4679,43 +4695,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + match bucketlist with + | Empty -> + Empty + | Cons(k, i, next) -> + if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with - | Empty -> - Empty - | Cons(k, i, next) -> - if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = match bucketlist with | Empty -> - raise Not_found + raise Not_found | Cons(k, d, rest) -> - if eq_key key k then d else find_rec key rest + if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - match h.data.(key_index h key) with + match Array.unsafe_get h.data (key_index h key) with | Empty -> raise Not_found | Cons(k1, d1, rest1) -> - if eq_key key k1 then d1 else + if eq_key key k1 then d1 else match rest1 with | Empty -> raise Not_found | Cons(k2, d2, rest2) -> - if eq_key key k2 then d2 else + if eq_key key k2 then d2 else match rest2 with | Empty -> raise Not_found | Cons(k3, d3, rest3) -> - if eq_key key k3 then d3 else find_rec key rest3 + if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -4723,42 +4747,46 @@ let find_default (h : _ t) key default = Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = let rec find_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with | Empty -> - raise_notrace Not_found + raise_notrace Not_found | Cons(k, i, next) -> - if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = let rec mem_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - let map = create 51 in + let len = List.length ks in + let map = create len in List.iter2 (fun k v -> add map k v) ks vs ; map diff --git a/jscomp/bin/whole_compiler.ml b/jscomp/bin/whole_compiler.ml index 2ed3379f73..b0cf12444c 100644 --- a/jscomp/bin/whole_compiler.ml +++ b/jscomp/bin/whole_compiler.ml @@ -23685,10 +23685,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -23699,43 +23699,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + match bucketlist with + | Empty -> + Empty + | Cons(k, i, next) -> + if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with - | Empty -> - Empty - | Cons(k, i, next) -> - if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = match bucketlist with | Empty -> - raise Not_found + raise Not_found | Cons(k, d, rest) -> - if eq_key key k then d else find_rec key rest + if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - match h.data.(key_index h key) with + match Array.unsafe_get h.data (key_index h key) with | Empty -> raise Not_found | Cons(k1, d1, rest1) -> - if eq_key key k1 then d1 else + if eq_key key k1 then d1 else match rest1 with | Empty -> raise Not_found | Cons(k2, d2, rest2) -> - if eq_key key k2 then d2 else + if eq_key key k2 then d2 else match rest2 with | Empty -> raise Not_found | Cons(k3, d3, rest3) -> - if eq_key key k3 then d3 else find_rec key rest3 + if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -23743,42 +23751,46 @@ let find_default (h : _ t) key default = Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = let rec find_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with | Empty -> - raise_notrace Not_found + raise_notrace Not_found | Cons(k, i, next) -> - if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = let rec mem_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - let map = create 51 in + let len = List.length ks in + let map = create len in List.iter2 (fun k v -> add map k v) ks vs ; map @@ -24804,132 +24816,6 @@ let build_lazy_queue ppf queue (ast_table : _ t String_map.t) ) -(* let (//) = Filename.concat *) -(* let dep_lit = " :" *) -(* let length_space = String.length space *) -(* let space = " " *) - -(* let handle_depfile oprefix (fn : string) : unit = *) -(* let op_concat s = match oprefix with None -> s | Some v -> v // s in *) -(* let data = *) -(* Binary_cache.read_build_cache (op_concat Binary_cache.bsbuild_cache) in *) -(* let deps = *) -(* match Ext_string.ends_with_then_chop fn Literals.suffix_mlast with *) -(* | Some input_file -> *) -(* let stru = Binary_ast.read_ast Ml fn in *) -(* let set = read_parse_and_extract Ml stru in *) -(* let dependent_file = (input_file ^ Literals.suffix_cmj) ^ dep_lit in *) -(* let (files, len) = *) -(* String_set.fold *) -(* (fun k ((acc, len) as v) -> *) -(* match String_map.find k data with *) -(* | {ml = Ml s | Re s } *) -(* | {mll = Some s } *) -(* -> *) -(* let new_file = op_concat @@ Filename.chop_extension s ^ Literals.suffix_cmj *) -(* in (new_file :: acc , len + String.length new_file + length_space) *) -(* | {mli = Mli s | Rei s } -> *) -(* let new_file = op_concat @@ Filename.chop_extension s ^ Literals.suffix_cmi in *) -(* (new_file :: acc , len + String.length new_file + length_space) *) -(* | _ -> assert false *) -(* | exception Not_found -> v *) -(* ) set ([],String.length dependent_file)in *) -(* Ext_string.unsafe_concat_with_length len *) -(* space *) -(* (dependent_file :: files) *) -(* | None -> *) -(* begin match Ext_string.ends_with_then_chop fn Literals.suffix_mliast with *) -(* | Some input_file -> *) -(* let stri = Binary_ast.read_ast Mli fn in *) -(* let s = read_parse_and_extract Mli stri in *) -(* let dependent_file = (input_file ^ Literals.suffix_cmi) ^ dep_lit in *) -(* let (files, len) = *) -(* String_set.fold *) -(* (fun k ((acc, len) as v) -> *) -(* match String_map.find k data with *) -(* | { ml = Ml f | Re f } *) -(* | { mll = Some f } *) -(* | { mli = Mli f | Rei f } -> *) -(* let new_file = (op_concat @@ Filename.chop_extension f ^ Literals.suffix_cmi) in *) -(* (new_file :: acc , len + String.length new_file + length_space) *) -(* | _ -> assert false *) -(* | exception Not_found -> v *) -(* ) s ([], String.length dependent_file) in *) -(* Ext_string.unsafe_concat_with_length len *) -(* space *) -(* (dependent_file :: files) *) -(* | None -> *) -(* raise (Arg.Bad ("don't know what to do with " ^ fn)) *) -(* end *) -(* in *) -(* let output = fn ^ Literals.suffix_d in *) -(* Ext_pervasives.with_file_as_chan output (fun v -> output_string v deps) *) - - -(* let handle_bin_depfile oprefix (fn : string) : unit = *) -(* let op_concat s = match oprefix with None -> s | Some v -> v // s in *) -(* let data = *) -(* Binary_cache.read_build_cache (op_concat Binary_cache.bsbuild_cache) in *) -(* match Ext_string.ends_with_then_chop fn Literals.suffix_mldeps with *) -(* | Some input_file -> *) -(* let set = *) -(* let ichan = open_in_bin fn in *) -(* let set : String_set.t = input_value ichan in *) -(* let () = close_in ichan in *) -(* set in *) -(* let dependent_file = (input_file ^ Literals.suffix_cmj) ^ dep_lit in *) -(* let (files, len) = *) -(* String_set.fold *) -(* (fun k ((acc, len) as v) -> *) -(* match String_map.find k data with *) -(* | {ml = Ml s | Re s } *) -(* | {mll = Some s } *) -(* -> *) -(* let new_file = op_concat @@ Filename.chop_extension s ^ Literals.suffix_cmj *) -(* in (new_file :: acc , len + String.length new_file + length_space) *) -(* | {mli = Mli s | Rei s } -> *) -(* let new_file = op_concat @@ Filename.chop_extension s ^ Literals.suffix_cmi in *) -(* (new_file :: acc , len + String.length new_file + length_space) *) -(* | _ -> assert false *) -(* | exception Not_found -> v *) -(* ) set ([],String.length dependent_file)in *) -(* let deps = Ext_string.unsafe_concat_with_length len *) -(* space *) -(* (dependent_file :: files) *) -(* in *) -(* let output = input_file ^ Literals.suffix_mlastd in *) -(* Ext_pervasives.with_file_as_chan output (fun v -> output_string v deps) *) - -(* | None -> *) -(* begin match Ext_string.ends_with_then_chop fn Literals.suffix_mlideps with *) -(* | Some input_file -> *) -(* let set = *) -(* let ichan = open_in_bin fn in *) -(* let set : String_set.t = input_value ichan in *) -(* let () = close_in ichan in *) -(* set in *) -(* let dependent_file = (input_file ^ Literals.suffix_cmi) ^ dep_lit in *) -(* let (files, len) = *) -(* String_set.fold *) -(* (fun k ((acc, len) as v) -> *) -(* match String_map.find k data with *) -(* | { ml = Ml f | Re f } *) -(* | { mll = Some f } *) -(* | { mli = Mli f | Rei f } -> *) -(* let new_file = (op_concat @@ Filename.chop_extension f ^ Literals.suffix_cmi) in *) -(* (new_file :: acc , len + String.length new_file + length_space) *) -(* | _ -> assert false *) -(* | exception Not_found -> v *) -(* ) set ([], String.length dependent_file) in *) -(* let deps = Ext_string.unsafe_concat_with_length len *) -(* space *) -(* (dependent_file :: files) in *) -(* let output = input_file ^ Literals.suffix_mliastd in *) -(* Ext_pervasives.with_file_as_chan output (fun v -> output_string v deps) *) -(* | None -> *) -(* raise (Arg.Bad ("don't know what to do with " ^ fn)) *) -(* end *) - end module Binary_ast : sig #1 "binary_ast.mli" @@ -58625,20 +58511,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -59092,20 +58982,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -63060,20 +62954,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -66876,7 +66774,7 @@ type key = Ident.t type 'a t = (key, 'a) Hashtbl_gen.t let key_index (h : _ t ) (key : key) = (Bs_hash_stubs.hash_stamp_and_name key.stamp key.name ) land (Array.length h.data - 1) - (* (Bs_hash_stubs.hash_string_int key.name key.stamp ) land (Array.length h.data - 1) *) +(* (Bs_hash_stubs.hash_string_int key.name key.stamp ) land (Array.length h.data - 1) *) let eq_key = Ext_ident.equal # 33 @@ -66894,10 +66792,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -66908,43 +66806,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + match bucketlist with + | Empty -> + Empty + | Cons(k, i, next) -> + if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with - | Empty -> - Empty - | Cons(k, i, next) -> - if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = match bucketlist with | Empty -> - raise Not_found + raise Not_found | Cons(k, d, rest) -> - if eq_key key k then d else find_rec key rest + if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - match h.data.(key_index h key) with + match Array.unsafe_get h.data (key_index h key) with | Empty -> raise Not_found | Cons(k1, d1, rest1) -> - if eq_key key k1 then d1 else + if eq_key key k1 then d1 else match rest1 with | Empty -> raise Not_found | Cons(k2, d2, rest2) -> - if eq_key key k2 then d2 else + if eq_key key k2 then d2 else match rest2 with | Empty -> raise Not_found | Cons(k3, d3, rest3) -> - if eq_key key k3 then d3 else find_rec key rest3 + if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -66952,42 +66858,46 @@ let find_default (h : _ t) key default = Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = let rec find_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with | Empty -> - raise_notrace Not_found + raise_notrace Not_found | Cons(k, i, next) -> - if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = let rec mem_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - let map = create 51 in + let len = List.length ks in + let map = create len in List.iter2 (fun k v -> add map k v) ks vs ; map @@ -67644,11 +67554,11 @@ end = struct #1 "hashtbl_make.ml" # 22 "ext/hashtbl.cppo.ml" module Make (Key : Hashtbl.HashedType) = struct -type key = Key.t -type 'a t = (key, 'a) Hashtbl_gen.t -let key_index (h : _ t ) (key : key) = - (Key.hash key ) land (Array.length h.data - 1) -let eq_key = Key.equal + type key = Key.t + type 'a t = (key, 'a) Hashtbl_gen.t + let key_index (h : _ t ) (key : key) = + (Key.hash key ) land (Array.length h.data - 1) + let eq_key = Key.equal # 33 @@ -67666,10 +67576,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -67680,43 +67590,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + match bucketlist with + | Empty -> + Empty + | Cons(k, i, next) -> + if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with - | Empty -> - Empty - | Cons(k, i, next) -> - if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = match bucketlist with | Empty -> - raise Not_found + raise Not_found | Cons(k, d, rest) -> - if eq_key key k then d else find_rec key rest + if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - match h.data.(key_index h key) with + match Array.unsafe_get h.data (key_index h key) with | Empty -> raise Not_found | Cons(k1, d1, rest1) -> - if eq_key key k1 then d1 else + if eq_key key k1 then d1 else match rest1 with | Empty -> raise Not_found | Cons(k2, d2, rest2) -> - if eq_key key k2 then d2 else + if eq_key key k2 then d2 else match rest2 with | Empty -> raise Not_found | Cons(k3, d3, rest3) -> - if eq_key key k3 then d3 else find_rec key rest3 + if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -67724,46 +67642,50 @@ let find_default (h : _ t) key default = Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = let rec find_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with | Empty -> - raise_notrace Not_found + raise_notrace Not_found | Cons(k, i, next) -> - if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = let rec mem_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - let map = create 51 in + let len = List.length ks in + let map = create len in List.iter2 (fun k v -> add map k v) ks vs ; map -# 145 +# 157 end end @@ -68628,20 +68550,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -94355,10 +94281,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -94369,43 +94295,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + match bucketlist with + | Empty -> + Empty + | Cons(k, i, next) -> + if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with - | Empty -> - Empty - | Cons(k, i, next) -> - if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = match bucketlist with | Empty -> - raise Not_found + raise Not_found | Cons(k, d, rest) -> - if eq_key key k then d else find_rec key rest + if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - match h.data.(key_index h key) with + match Array.unsafe_get h.data (key_index h key) with | Empty -> raise Not_found | Cons(k1, d1, rest1) -> - if eq_key key k1 then d1 else + if eq_key key k1 then d1 else match rest1 with | Empty -> raise Not_found | Cons(k2, d2, rest2) -> - if eq_key key k2 then d2 else + if eq_key key k2 then d2 else match rest2 with | Empty -> raise Not_found | Cons(k3, d3, rest3) -> - if eq_key key k3 then d3 else find_rec key rest3 + if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -94413,42 +94347,46 @@ let find_default (h : _ t) key default = Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = let rec find_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with | Empty -> - raise_notrace Not_found + raise_notrace Not_found | Cons(k, i, next) -> - if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = let rec mem_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - let map = create 51 in + let len = List.length ks in + let map = create len in List.iter2 (fun k v -> add map k v) ks vs ; map diff --git a/jscomp/depends/ast_extract.ml b/jscomp/depends/ast_extract.ml index 64f46722bf..fde1f2a635 100644 --- a/jscomp/depends/ast_extract.ml +++ b/jscomp/depends/ast_extract.ml @@ -330,129 +330,3 @@ let build_lazy_queue ppf queue (ast_table : _ t String_map.t) | exception Not_found -> assert false ) - -(* let (//) = Filename.concat *) -(* let dep_lit = " :" *) -(* let length_space = String.length space *) -(* let space = " " *) - -(* let handle_depfile oprefix (fn : string) : unit = *) -(* let op_concat s = match oprefix with None -> s | Some v -> v // s in *) -(* let data = *) -(* Binary_cache.read_build_cache (op_concat Binary_cache.bsbuild_cache) in *) -(* let deps = *) -(* match Ext_string.ends_with_then_chop fn Literals.suffix_mlast with *) -(* | Some input_file -> *) -(* let stru = Binary_ast.read_ast Ml fn in *) -(* let set = read_parse_and_extract Ml stru in *) -(* let dependent_file = (input_file ^ Literals.suffix_cmj) ^ dep_lit in *) -(* let (files, len) = *) -(* String_set.fold *) -(* (fun k ((acc, len) as v) -> *) -(* match String_map.find k data with *) -(* | {ml = Ml s | Re s } *) -(* | {mll = Some s } *) -(* -> *) -(* let new_file = op_concat @@ Filename.chop_extension s ^ Literals.suffix_cmj *) -(* in (new_file :: acc , len + String.length new_file + length_space) *) -(* | {mli = Mli s | Rei s } -> *) -(* let new_file = op_concat @@ Filename.chop_extension s ^ Literals.suffix_cmi in *) -(* (new_file :: acc , len + String.length new_file + length_space) *) -(* | _ -> assert false *) -(* | exception Not_found -> v *) -(* ) set ([],String.length dependent_file)in *) -(* Ext_string.unsafe_concat_with_length len *) -(* space *) -(* (dependent_file :: files) *) -(* | None -> *) -(* begin match Ext_string.ends_with_then_chop fn Literals.suffix_mliast with *) -(* | Some input_file -> *) -(* let stri = Binary_ast.read_ast Mli fn in *) -(* let s = read_parse_and_extract Mli stri in *) -(* let dependent_file = (input_file ^ Literals.suffix_cmi) ^ dep_lit in *) -(* let (files, len) = *) -(* String_set.fold *) -(* (fun k ((acc, len) as v) -> *) -(* match String_map.find k data with *) -(* | { ml = Ml f | Re f } *) -(* | { mll = Some f } *) -(* | { mli = Mli f | Rei f } -> *) -(* let new_file = (op_concat @@ Filename.chop_extension f ^ Literals.suffix_cmi) in *) -(* (new_file :: acc , len + String.length new_file + length_space) *) -(* | _ -> assert false *) -(* | exception Not_found -> v *) -(* ) s ([], String.length dependent_file) in *) -(* Ext_string.unsafe_concat_with_length len *) -(* space *) -(* (dependent_file :: files) *) -(* | None -> *) -(* raise (Arg.Bad ("don't know what to do with " ^ fn)) *) -(* end *) -(* in *) -(* let output = fn ^ Literals.suffix_d in *) -(* Ext_pervasives.with_file_as_chan output (fun v -> output_string v deps) *) - - -(* let handle_bin_depfile oprefix (fn : string) : unit = *) -(* let op_concat s = match oprefix with None -> s | Some v -> v // s in *) -(* let data = *) -(* Binary_cache.read_build_cache (op_concat Binary_cache.bsbuild_cache) in *) -(* match Ext_string.ends_with_then_chop fn Literals.suffix_mldeps with *) -(* | Some input_file -> *) -(* let set = *) -(* let ichan = open_in_bin fn in *) -(* let set : String_set.t = input_value ichan in *) -(* let () = close_in ichan in *) -(* set in *) -(* let dependent_file = (input_file ^ Literals.suffix_cmj) ^ dep_lit in *) -(* let (files, len) = *) -(* String_set.fold *) -(* (fun k ((acc, len) as v) -> *) -(* match String_map.find k data with *) -(* | {ml = Ml s | Re s } *) -(* | {mll = Some s } *) -(* -> *) -(* let new_file = op_concat @@ Filename.chop_extension s ^ Literals.suffix_cmj *) -(* in (new_file :: acc , len + String.length new_file + length_space) *) -(* | {mli = Mli s | Rei s } -> *) -(* let new_file = op_concat @@ Filename.chop_extension s ^ Literals.suffix_cmi in *) -(* (new_file :: acc , len + String.length new_file + length_space) *) -(* | _ -> assert false *) -(* | exception Not_found -> v *) -(* ) set ([],String.length dependent_file)in *) -(* let deps = Ext_string.unsafe_concat_with_length len *) -(* space *) -(* (dependent_file :: files) *) -(* in *) -(* let output = input_file ^ Literals.suffix_mlastd in *) -(* Ext_pervasives.with_file_as_chan output (fun v -> output_string v deps) *) - -(* | None -> *) -(* begin match Ext_string.ends_with_then_chop fn Literals.suffix_mlideps with *) -(* | Some input_file -> *) -(* let set = *) -(* let ichan = open_in_bin fn in *) -(* let set : String_set.t = input_value ichan in *) -(* let () = close_in ichan in *) -(* set in *) -(* let dependent_file = (input_file ^ Literals.suffix_cmi) ^ dep_lit in *) -(* let (files, len) = *) -(* String_set.fold *) -(* (fun k ((acc, len) as v) -> *) -(* match String_map.find k data with *) -(* | { ml = Ml f | Re f } *) -(* | { mll = Some f } *) -(* | { mli = Mli f | Rei f } -> *) -(* let new_file = (op_concat @@ Filename.chop_extension f ^ Literals.suffix_cmi) in *) -(* (new_file :: acc , len + String.length new_file + length_space) *) -(* | _ -> assert false *) -(* | exception Not_found -> v *) -(* ) set ([], String.length dependent_file) in *) -(* let deps = Ext_string.unsafe_concat_with_length len *) -(* space *) -(* (dependent_file :: files) in *) -(* let output = input_file ^ Literals.suffix_mliastd in *) -(* Ext_pervasives.with_file_as_chan output (fun v -> output_string v deps) *) -(* | None -> *) -(* raise (Arg.Bad ("don't know what to do with " ^ fn)) *) -(* end *) diff --git a/jscomp/ext/hash_set.cppo.ml b/jscomp/ext/hash_set.cppo.ml index e3f95d4091..ceaaf0dc6d 100644 --- a/jscomp/ext/hash_set.cppo.ml +++ b/jscomp/ext/hash_set.cppo.ml @@ -80,20 +80,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false diff --git a/jscomp/ext/hash_set.ml b/jscomp/ext/hash_set.ml index 3957a67612..68b5a2018d 100644 --- a/jscomp/ext/hash_set.ml +++ b/jscomp/ext/hash_set.ml @@ -56,20 +56,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false @@ -78,6 +82,6 @@ let check_add (h : _ Hash_set_gen.t) key = let mem (h : _ Hash_set_gen.t) key = Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data (key_index h key)) -# 106 +# 110 end diff --git a/jscomp/ext/hash_set_poly.ml b/jscomp/ext/hash_set_poly.ml index 74749b2e4a..a5481bea19 100644 --- a/jscomp/ext/hash_set_poly.ml +++ b/jscomp/ext/hash_set_poly.ml @@ -56,20 +56,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false diff --git a/jscomp/ext/hashtbl.cppo.ml b/jscomp/ext/hashtbl.cppo.ml index a5829e1024..4759688077 100644 --- a/jscomp/ext/hashtbl.cppo.ml +++ b/jscomp/ext/hashtbl.cppo.ml @@ -3,7 +3,7 @@ type key = Ident.t type 'a t = (key, 'a) Hashtbl_gen.t let key_index (h : _ t ) (key : key) = (Bs_hash_stubs.hash_stamp_and_name key.stamp key.name ) land (Array.length h.data - 1) - (* (Bs_hash_stubs.hash_string_int key.name key.stamp ) land (Array.length h.data - 1) *) +(* (Bs_hash_stubs.hash_string_int key.name key.stamp ) land (Array.length h.data - 1) *) let eq_key = Ext_ident.equal #elif defined TYPE_STRING type key = string @@ -20,14 +20,14 @@ let eq_key = Ext_int.equal #elif defined TYPE_FUNCTOR module Make (Key : Hashtbl.HashedType) = struct -type key = Key.t -type 'a t = (key, 'a) Hashtbl_gen.t -let key_index (h : _ t ) (key : key) = - (Key.hash key ) land (Array.length h.data - 1) -let eq_key = Key.equal + type key = Key.t + type 'a t = (key, 'a) Hashtbl_gen.t + let key_index (h : _ t ) (key : key) = + (Key.hash key ) land (Array.length h.data - 1) + let eq_key = Key.equal #else -[%error "unknown type"] + [%error "unknown type"] #endif type ('a, 'b) bucketlist = ('a,'b) Hashtbl_gen.bucketlist @@ -44,10 +44,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -58,43 +58,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + match bucketlist with + | Empty -> + Empty + | Cons(k, i, next) -> + if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with - | Empty -> - Empty - | Cons(k, i, next) -> - if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = match bucketlist with | Empty -> - raise Not_found + raise Not_found | Cons(k, d, rest) -> - if eq_key key k then d else find_rec key rest + if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - match h.data.(key_index h key) with + match Array.unsafe_get h.data (key_index h key) with | Empty -> raise Not_found | Cons(k1, d1, rest1) -> - if eq_key key k1 then d1 else + if eq_key key k1 then d1 else match rest1 with | Empty -> raise Not_found | Cons(k2, d2, rest2) -> - if eq_key key k2 then d2 else + if eq_key key k2 then d2 else match rest2 with | Empty -> raise Not_found | Cons(k3, d3, rest3) -> - if eq_key key k3 then d3 else find_rec key rest3 + if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -102,42 +110,46 @@ let find_default (h : _ t) key default = Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = let rec find_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with | Empty -> - raise_notrace Not_found + raise_notrace Not_found | Cons(k, i, next) -> - if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = let rec mem_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - let map = create 51 in + let len = List.length ks in + let map = create len in List.iter2 (fun k v -> add map k v) ks vs ; map diff --git a/jscomp/ext/hashtbl_make.ml b/jscomp/ext/hashtbl_make.ml index 68415dbbec..189ccefb24 100644 --- a/jscomp/ext/hashtbl_make.ml +++ b/jscomp/ext/hashtbl_make.ml @@ -1,10 +1,10 @@ # 22 "ext/hashtbl.cppo.ml" module Make (Key : Hashtbl.HashedType) = struct -type key = Key.t -type 'a t = (key, 'a) Hashtbl_gen.t -let key_index (h : _ t ) (key : key) = - (Key.hash key ) land (Array.length h.data - 1) -let eq_key = Key.equal + type key = Key.t + type 'a t = (key, 'a) Hashtbl_gen.t + let key_index (h : _ t ) (key : key) = + (Key.hash key ) land (Array.length h.data - 1) + let eq_key = Key.equal # 33 @@ -22,10 +22,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -36,43 +36,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + match bucketlist with + | Empty -> + Empty + | Cons(k, i, next) -> + if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with - | Empty -> - Empty - | Cons(k, i, next) -> - if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = match bucketlist with | Empty -> - raise Not_found + raise Not_found | Cons(k, d, rest) -> - if eq_key key k then d else find_rec key rest + if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - match h.data.(key_index h key) with + match Array.unsafe_get h.data (key_index h key) with | Empty -> raise Not_found | Cons(k1, d1, rest1) -> - if eq_key key k1 then d1 else + if eq_key key k1 then d1 else match rest1 with | Empty -> raise Not_found | Cons(k2, d2, rest2) -> - if eq_key key k2 then d2 else + if eq_key key k2 then d2 else match rest2 with | Empty -> raise Not_found | Cons(k3, d3, rest3) -> - if eq_key key k3 then d3 else find_rec key rest3 + if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -80,44 +88,48 @@ let find_default (h : _ t) key default = Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = let rec find_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with | Empty -> - raise_notrace Not_found + raise_notrace Not_found | Cons(k, i, next) -> - if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = let rec mem_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - let map = create 51 in + let len = List.length ks in + let map = create len in List.iter2 (fun k v -> add map k v) ks vs ; map -# 145 +# 157 end diff --git a/jscomp/ext/ident_hash_set.ml b/jscomp/ext/ident_hash_set.ml index 7d740c4614..4e22ddf275 100644 --- a/jscomp/ext/ident_hash_set.ml +++ b/jscomp/ext/ident_hash_set.ml @@ -55,20 +55,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false diff --git a/jscomp/ext/ident_hashtbl.ml b/jscomp/ext/ident_hashtbl.ml index 008d63b598..728b427baa 100644 --- a/jscomp/ext/ident_hashtbl.ml +++ b/jscomp/ext/ident_hashtbl.ml @@ -3,7 +3,7 @@ type key = Ident.t type 'a t = (key, 'a) Hashtbl_gen.t let key_index (h : _ t ) (key : key) = (Bs_hash_stubs.hash_stamp_and_name key.stamp key.name ) land (Array.length h.data - 1) - (* (Bs_hash_stubs.hash_string_int key.name key.stamp ) land (Array.length h.data - 1) *) +(* (Bs_hash_stubs.hash_string_int key.name key.stamp ) land (Array.length h.data - 1) *) let eq_key = Ext_ident.equal # 33 @@ -21,10 +21,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -35,43 +35,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + match bucketlist with + | Empty -> + Empty + | Cons(k, i, next) -> + if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with - | Empty -> - Empty - | Cons(k, i, next) -> - if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = match bucketlist with | Empty -> - raise Not_found + raise Not_found | Cons(k, d, rest) -> - if eq_key key k then d else find_rec key rest + if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - match h.data.(key_index h key) with + match Array.unsafe_get h.data (key_index h key) with | Empty -> raise Not_found | Cons(k1, d1, rest1) -> - if eq_key key k1 then d1 else + if eq_key key k1 then d1 else match rest1 with | Empty -> raise Not_found | Cons(k2, d2, rest2) -> - if eq_key key k2 then d2 else + if eq_key key k2 then d2 else match rest2 with | Empty -> raise Not_found | Cons(k3, d3, rest3) -> - if eq_key key k3 then d3 else find_rec key rest3 + if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -79,42 +87,46 @@ let find_default (h : _ t) key default = Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = let rec find_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with | Empty -> - raise_notrace Not_found + raise_notrace Not_found | Cons(k, i, next) -> - if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = let rec mem_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - let map = create 51 in + let len = List.length ks in + let map = create len in List.iter2 (fun k v -> add map k v) ks vs ; map diff --git a/jscomp/ext/int_hash_set.ml b/jscomp/ext/int_hash_set.ml index ecb8e1b0e0..aeb964f031 100644 --- a/jscomp/ext/int_hash_set.ml +++ b/jscomp/ext/int_hash_set.ml @@ -55,20 +55,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false diff --git a/jscomp/ext/int_hashtbl.ml b/jscomp/ext/int_hashtbl.ml index 7acf7e0a51..a6fa8805cd 100644 --- a/jscomp/ext/int_hashtbl.ml +++ b/jscomp/ext/int_hashtbl.ml @@ -21,10 +21,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -35,43 +35,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + match bucketlist with + | Empty -> + Empty + | Cons(k, i, next) -> + if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with - | Empty -> - Empty - | Cons(k, i, next) -> - if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = match bucketlist with | Empty -> - raise Not_found + raise Not_found | Cons(k, d, rest) -> - if eq_key key k then d else find_rec key rest + if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - match h.data.(key_index h key) with + match Array.unsafe_get h.data (key_index h key) with | Empty -> raise Not_found | Cons(k1, d1, rest1) -> - if eq_key key k1 then d1 else + if eq_key key k1 then d1 else match rest1 with | Empty -> raise Not_found | Cons(k2, d2, rest2) -> - if eq_key key k2 then d2 else + if eq_key key k2 then d2 else match rest2 with | Empty -> raise Not_found | Cons(k3, d3, rest3) -> - if eq_key key k3 then d3 else find_rec key rest3 + if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -79,42 +87,46 @@ let find_default (h : _ t) key default = Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = let rec find_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with | Empty -> - raise_notrace Not_found + raise_notrace Not_found | Cons(k, i, next) -> - if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = let rec mem_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - let map = create 51 in + let len = List.length ks in + let map = create len in List.iter2 (fun k v -> add map k v) ks vs ; map diff --git a/jscomp/ext/string_hash_set.ml b/jscomp/ext/string_hash_set.ml index 0735c0bab0..5403490893 100644 --- a/jscomp/ext/string_hash_set.ml +++ b/jscomp/ext/string_hash_set.ml @@ -55,20 +55,24 @@ let remove (h : _ Hash_set_gen.t) key = let add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h end let check_add (h : _ Hash_set_gen.t) key = let i = key_index h key in - if not (Hash_set_gen.small_bucket_mem eq_key key (Array.unsafe_get h.data i)) then + let h_data = h.data in + let old_bucket = (Array.unsafe_get h_data i) in + if not (Hash_set_gen.small_bucket_mem eq_key key old_bucket) then begin - h.data.(i) <- key :: h.data.(i); + Array.unsafe_set h_data i (key :: old_bucket); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hash_set_gen.resize key_index h; + if h.size > Array.length h_data lsl 1 then Hash_set_gen.resize key_index h; true end else false diff --git a/jscomp/ext/string_hashtbl.ml b/jscomp/ext/string_hashtbl.ml index d976ac190e..f70c7493ce 100644 --- a/jscomp/ext/string_hashtbl.ml +++ b/jscomp/ext/string_hashtbl.ml @@ -20,10 +20,10 @@ let stats = Hashtbl_gen.stats let add (h : _ t) key info = let i = key_index h key in - let bucket : _ bucketlist = Cons(key, info, h.data.(i)) in - h.data.(i) <- bucket; + let h_data = h.data in + Array.unsafe_set h_data i (Cons(key, info, (Array.unsafe_get h_data i))); h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h (* after upgrade to 4.04 we should provide an efficient [replace_or_init] *) let modify_or_init (h : _ t) key modf default = @@ -34,43 +34,51 @@ let modify_or_init (h : _ t) key modf default = else find_bucket next | Empty -> true in let i = key_index h key in - if find_bucket h.data.(i) then + let h_data = h.data in + if find_bucket (Array.unsafe_get h_data i) then begin - h.data.(i) <- Cons(key,default (),h.data.(i)); + Array.unsafe_set h_data i (Cons(key,default (), Array.unsafe_get h_data i)); h.size <- h.size + 1 ; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h end + +let rec remove_bucket key (h : _ t) (bucketlist : _ bucketlist) : _ bucketlist = + match bucketlist with + | Empty -> + Empty + | Cons(k, i, next) -> + if eq_key k key + then begin h.size <- h.size - 1; next end + else Cons(k, i, remove_bucket key h next) + let remove (h : _ t ) key = - let rec remove_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with - | Empty -> - Empty - | Cons(k, i, next) -> - if eq_key k key - then begin h.size <- h.size - 1; next end - else Cons(k, i, remove_bucket next) in let i = key_index h key in - h.data.(i) <- remove_bucket h.data.(i) + let h_data = h.data in + let old_h_szie = h.size in + let new_bucket = remove_bucket key h (Array.unsafe_get h_data i) in + if old_h_szie <> h.size then + Array.unsafe_set h_data i new_bucket let rec find_rec key (bucketlist : _ bucketlist) = match bucketlist with | Empty -> - raise Not_found + raise Not_found | Cons(k, d, rest) -> - if eq_key key k then d else find_rec key rest + if eq_key key k then d else find_rec key rest let find_exn (h : _ t) key = - match h.data.(key_index h key) with + match Array.unsafe_get h.data (key_index h key) with | Empty -> raise Not_found | Cons(k1, d1, rest1) -> - if eq_key key k1 then d1 else + if eq_key key k1 then d1 else match rest1 with | Empty -> raise Not_found | Cons(k2, d2, rest2) -> - if eq_key key k2 then d2 else + if eq_key key k2 then d2 else match rest2 with | Empty -> raise Not_found | Cons(k3, d3, rest3) -> - if eq_key key k3 then d3 else find_rec key rest3 + if eq_key key k3 then d3 else find_rec key rest3 let find_opt (h : _ t) key = Hashtbl_gen.small_bucket_opt eq_key key (Array.unsafe_get h.data (key_index h key)) @@ -78,42 +86,46 @@ let find_default (h : _ t) key default = Hashtbl_gen.small_bucket_default eq_key key default (Array.unsafe_get h.data (key_index h key)) let find_all (h : _ t) key = let rec find_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> [] - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> if eq_key k key then d :: find_in_bucket rest else find_in_bucket rest in - find_in_bucket h.data.(key_index h key) + find_in_bucket (Array.unsafe_get h.data (key_index h key)) let replace h key info = let rec replace_bucket (bucketlist : _ bucketlist) : _ bucketlist = match bucketlist with | Empty -> - raise_notrace Not_found + raise_notrace Not_found | Cons(k, i, next) -> - if eq_key k key - then Cons(key, info, next) - else Cons(k, i, replace_bucket next) in + if eq_key k key + then Cons(key, info, next) + else Cons(k, i, replace_bucket next) in let i = key_index h key in - let l = h.data.(i) in + let h_data = h.data in + let l = Array.unsafe_get h_data i in try - h.data.(i) <- replace_bucket l + Array.unsafe_set h_data i (replace_bucket l) with Not_found -> - h.data.(i) <- Cons(key, info, l); - h.size <- h.size + 1; - if h.size > Array.length h.data lsl 1 then Hashtbl_gen.resize key_index h + begin + Array.unsafe_set h_data i (Cons(key, info, l)); + h.size <- h.size + 1; + if h.size > Array.length h_data lsl 1 then Hashtbl_gen.resize key_index h; + end let mem (h : _ t) key = let rec mem_in_bucket (bucketlist : _ bucketlist) = match bucketlist with - | Empty -> + | Empty -> false - | Cons(k, d, rest) -> + | Cons(k, d, rest) -> eq_key k key || mem_in_bucket rest in - mem_in_bucket h.data.(key_index h key) + mem_in_bucket (Array.unsafe_get h.data (key_index h key)) let of_list2 ks vs = - let map = create 51 in + let len = List.length ks in + let map = create len in List.iter2 (fun k v -> add map k v) ks vs ; map diff --git a/jscomp/test/.depend b/jscomp/test/.depend index ee31385a83..8b06a34ac3 100644 --- a/jscomp/test/.depend +++ b/jscomp/test/.depend @@ -84,6 +84,7 @@ class5_test.cmj : mt.cmj ../stdlib/list.cmj class6_test.cmj : mt.cmj class7_test.cmj : ../stdlib/oo.cmj mt.cmj class8_test.cmj : mt.cmj +class_fib_open_recursion_test.cmj : mt.cmj ../stdlib/hashtbl.cmj class_repr.cmj : ../stdlib/oo.cmj class_setter_getter.cmj : ../runtime/js.cmj class_setter_getter.cmi class_test.cmj : mt.cmj