Skip to content

Commit 3a47063

Browse files
committed
Fix mantis 5349, semantic of replace
The closed bug report is about classic hashtable but it is also applicable for weak hashtable (thanks @signoles for the heads up)
1 parent ec173d0 commit 3a47063

File tree

2 files changed

+28
-22
lines changed

2 files changed

+28
-22
lines changed

stdlib/ephemeron.ml

+25-19
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ module GenHashTable = struct
3636
type 'a container
3737
val create: t -> 'a -> 'a container
3838
val hash: int -> t -> int
39-
val equal: t -> 'a container -> equal
39+
val equal: 'a container -> t -> equal
4040
val get_data: 'a container -> 'a option
4141
val get_key: 'a container -> t option
42-
val set_data: 'a container -> 'a -> unit
42+
val set_key_data: 'a container -> t -> 'a -> unit
4343
val check_key: 'a container -> bool
4444
end) : SeededS with type key = H.t
4545
= struct
@@ -161,7 +161,7 @@ module GenHashTable = struct
161161
let rec remove_bucket = function
162162
| Empty -> Empty
163163
| Cons(hk, c, next) when hkey = hk ->
164-
begin match H.equal key c with
164+
begin match H.equal c key with
165165
| ETrue -> h.size <- h.size - 1; next
166166
| EFalse -> Cons(hk, c, remove_bucket next)
167167
| EDead ->
@@ -182,7 +182,7 @@ module GenHashTable = struct
182182
| Empty ->
183183
raise Not_found
184184
| Cons(hk, c, rest) when hkey = hk ->
185-
begin match H.equal key c with
185+
begin match H.equal c key with
186186
| ETrue ->
187187
begin match H.get_data c with
188188
| None ->
@@ -208,7 +208,7 @@ module GenHashTable = struct
208208
let rec find_in_bucket = function
209209
| Empty -> []
210210
| Cons(hk, c, rest) when hkey = hk ->
211-
begin match H.equal key c with
211+
begin match H.equal c key with
212212
| ETrue -> begin match H.get_data c with
213213
| None ->
214214
find_in_bucket rest
@@ -228,13 +228,8 @@ module GenHashTable = struct
228228
let rec replace_bucket = function
229229
| Empty -> raise Not_found
230230
| Cons(hk, c, next) when hkey = hk ->
231-
begin match H.equal key c with
232-
| ETrue -> begin match H.get_data c with
233-
| None ->
234-
(** This case is not impossible, cf remove *)
235-
replace_bucket next
236-
| Some d -> H.set_data c info
237-
end
231+
begin match H.equal c key with
232+
| ETrue -> H.set_key_data c key info
238233
| EFalse | EDead -> replace_bucket next
239234
end
240235
| Cons(_,_,next) -> replace_bucket next
@@ -255,7 +250,7 @@ module GenHashTable = struct
255250
| Empty ->
256251
false
257252
| Cons(hk, c, rest) when hk = hkey ->
258-
begin match H.equal key c with
253+
begin match H.equal c key with
259254
| ETrue -> true
260255
| EFalse | EDead -> mem_in_bucket rest
261256
end
@@ -403,7 +398,7 @@ module K1 = struct
403398
set_key c k;
404399
c
405400
let hash = H.hash
406-
let equal k c =
401+
let equal c k =
407402
(** {!get_key_copy} is not used because the equality of the user can be
408403
the physical equality *)
409404
match get_key c with
@@ -412,7 +407,10 @@ module K1 = struct
412407
if H.equal k k' then GenHashTable.ETrue else GenHashTable.EFalse
413408
let get_data = get_data
414409
let get_key = get_key
415-
let set_data = set_data
410+
let set_key_data c k d =
411+
unset_data c;
412+
set_key c k;
413+
set_data c d
416414
let check_key = check_key
417415
end)
418416

@@ -479,7 +477,7 @@ module K2 = struct
479477
c
480478
let hash seed (k1,k2) =
481479
H1.hash seed k1 + H2.hash seed k2 * 65599
482-
let equal (k1,k2) c =
480+
let equal c (k1,k2) =
483481
match get_key1 c, get_key2 c with
484482
| None, _ | _ , None -> GenHashTable.EDead
485483
| Some k1', Some k2' ->
@@ -490,7 +488,10 @@ module K2 = struct
490488
match get_key1 c, get_key2 c with
491489
| None, _ | _ , None -> None
492490
| Some k1', Some k2' -> Some (k1', k2')
493-
let set_data = set_data
491+
let set_key_data c (k1,k2) d =
492+
unset_data c;
493+
set_key1 c k1; set_key2 c k2;
494+
set_data c d
494495
let check_key c = check_key1 c && check_key2 c
495496
end)
496497

@@ -554,7 +555,7 @@ module Kn = struct
554555
h := H.hash seed k.(i) * 65599 + !h;
555556
done;
556557
!h
557-
let equal k c =
558+
let equal c k =
558559
let len = Array.length k in
559560
let len' = length c in
560561
if len != len' then GenHashTable.EFalse
@@ -589,7 +590,12 @@ module Kn = struct
589590
in
590591
let a = Array.make len k0 in
591592
fill a (len-1)
592-
let set_data = set_data
593+
let set_key_data c k d =
594+
unset_data c;
595+
for i=0 to Array.length k -1 do
596+
set_key c i k.(i);
597+
done;
598+
set_data c d
593599
let check_key c =
594600
let rec check c i =
595601
i < 0 || (check_key c i && check c (i-1)) in

stdlib/ephemeron.mli

+3-3
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ module GenHashTable: sig
286286

287287
val hash: int -> t -> int
288288
(** same as {!Hashtbl.SeededHashedType} *)
289-
val equal: t -> 'a container -> equal
289+
val equal: 'a container -> t -> equal
290290
(** equality predicate used to compare a key with the one in a
291291
container. Can return [EDead] if the keys in the container are
292292
dead *)
@@ -298,8 +298,8 @@ module GenHashTable: sig
298298
(** [get_key cont] returns the keys if they are all alive *)
299299
val get_data: 'a container -> 'a option
300300
(** [get_data cont] return the data if it is alive *)
301-
val set_data: 'a container -> 'a -> unit
302-
(** [set_data cont] modify the data *)
301+
val set_key_data: 'a container -> t -> 'a -> unit
302+
(** [set_key_data cont] modify the key and data *)
303303
val check_key: 'a container -> bool
304304
(** [check_key cont] checks if all the keys contained in the data
305305
are alive *)

0 commit comments

Comments
 (0)