From 723e4f1905e6a30556ae08f8df1892e4f34eba94 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Mon, 4 Mar 2013 14:27:06 +0100 Subject: [PATCH] bugfix in hashtable removal; many more tests for hashtable --- pHashtbl.ml | 6 ++-- tests/test_pHashtbl.ml | 74 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/pHashtbl.ml b/pHashtbl.ml index 4a4a2f03..6732595c 100644 --- a/pHashtbl.ml +++ b/pHashtbl.ml @@ -38,7 +38,7 @@ and state = Used | Empty | Deleted let my_null () = (Obj.magic None, Obj.magic None, Empty) -let my_deleted () = (Obj.magic None, Obj.magic None, Deleted) +let my_deleted key = (key, Obj.magic None, Deleted) (** Create a table. Size will be >= 2 *) let create ?(max_load=0.8) ?(eq=fun x y -> x = y) @@ -124,7 +124,7 @@ let replace t key value = match buckets.(j) with | (key', _, Used) when t.eq key key' -> buckets.(j) <- (key, value, Used) (* replace value *) - | (_, _, Deleted) |(_, _, Empty) -> + | (_, _, Deleted) | (_, _, Empty) -> buckets.(j) <- (key, value, Used); t.size <- t.size + 1 (* insert and increment size *) | (_, _, Used) -> @@ -144,7 +144,7 @@ let remove t key = let j = addr h n i in match buckets.(j) with | (key', _, Used) when t.eq key key' -> - buckets.(i) <- (my_deleted ()); t.size <- t.size - 1 (* remove slot *) + buckets.(j) <- (my_deleted key'); t.size <- t.size - 1 (* remove slot *) | (_, _, Deleted) | (_, _, Used) -> probe h n (i+1) (* search further *) | (_, _, Empty) -> () (* not present *) diff --git a/tests/test_pHashtbl.ml b/tests/test_pHashtbl.ml index d2535ecb..6eca5c0e 100644 --- a/tests/test_pHashtbl.ml +++ b/tests/test_pHashtbl.ml @@ -6,7 +6,81 @@ let test_add () = PHashtbl.replace h 42 "foo"; OUnit.assert_equal (PHashtbl.find h 42) "foo" +let my_list = + [ 1, "a"; + 2, "b"; + 3, "c"; + 4, "d"; + ] + +let my_seq = Sequence.of_list my_list + +let test_of_seq () = + let h = PHashtbl.create 5 in + PHashtbl.of_seq h my_seq; + OUnit.assert_equal (PHashtbl.find h 2) "b"; + OUnit.assert_equal (PHashtbl.find h 1) "a"; + OUnit.assert_raises Not_found (fun () -> PHashtbl.find h 42); + () + +let test_to_seq () = + let h = PHashtbl.create 5 in + PHashtbl.of_seq h my_seq; + let l = Sequence.to_list (PHashtbl.to_seq h) in + OUnit.assert_equal my_list (List.sort compare l) + +let test_resize () = + let h = PHashtbl.create 5 in + for i = 0 to 10 do + PHashtbl.add h i (string_of_int i); + done; + OUnit.assert_bool "must have been resized" (PHashtbl.length h > 5); + () + +let test_eq () = + let h = PHashtbl.create 3 + ~eq:(fun x y -> x mod 2 = y mod 2) + ~hash:(fun i -> i mod 2) in + PHashtbl.add h 1 "odd"; + PHashtbl.add h 2 "even"; + OUnit.assert_equal (PHashtbl.find h 3) "odd"; + OUnit.assert_equal (PHashtbl.find h 51) "odd"; + OUnit.assert_equal (PHashtbl.find h 42) "even"; + () + +let test_copy () = + let h = PHashtbl.create 2 in + PHashtbl.add h 1 "one"; + OUnit.assert_equal (PHashtbl.find h 1) "one"; + OUnit.assert_raises Not_found (fun () -> PHashtbl.find h 2); + let h' = PHashtbl.copy h in + PHashtbl.add h' 2 "two"; + OUnit.assert_equal (PHashtbl.find h' 1) "one"; + OUnit.assert_equal (PHashtbl.find h' 2) "two"; + OUnit.assert_equal (PHashtbl.find h 1) "one"; + OUnit.assert_raises Not_found (fun () -> PHashtbl.find h 2); + () + +let test_remove () = + let h = PHashtbl.create 3 in + PHashtbl.of_seq h my_seq; + OUnit.assert_equal (PHashtbl.find h 2) "b"; + OUnit.assert_equal (PHashtbl.find h 3) "c"; + OUnit.assert_equal (PHashtbl.find h 4) "d"; + OUnit.assert_equal (PHashtbl.length h) 4; + PHashtbl.remove h 2; + OUnit.assert_equal (PHashtbl.find h 3) "c"; + OUnit.assert_equal (PHashtbl.length h) 3; + (* test that 2 has been removed *) + OUnit.assert_raises Not_found (fun () -> PHashtbl.find h 2) + let suite = "test_pHashtbl" >::: [ "test_add" >:: test_add; + "test_of_seq" >:: test_of_seq; + "test_to_seq" >:: test_to_seq; + "test_resize" >:: test_resize; + "test_eq" >:: test_eq; + "test_copy" >:: test_copy; + "test_remove" >:: test_remove; ]