added a is_empty function for FHashtbl;

more tests for FHashtbl
This commit is contained in:
Simon Cruanes 2013-03-10 15:04:38 +01:00
parent a688d5dbc0
commit dabc9df46e
3 changed files with 31 additions and 1 deletions

View file

@ -41,6 +41,8 @@ module type S = sig
val empty : int -> 'a t val empty : int -> 'a t
(** The empty hashtable (with sub-hashtables of given size) *) (** The empty hashtable (with sub-hashtables of given size) *)
val is_empty : _ t -> bool
val find : 'a t -> key -> 'a val find : 'a t -> key -> 'a
(** Find the binding for this key, or raise Not_found *) (** Find the binding for this key, or raise Not_found *)
@ -159,6 +161,15 @@ module Tree(X : HASH) = struct
let size = max size 4 in (* size >= 4 *) let size = max size 4 in (* size >= 4 *)
Table (empty_buckets size) Table (empty_buckets size)
let rec is_empty_array a i =
if i = Array.length a then true
else (a.(i) = Empty || a.(i) = Deleted) && is_empty_array a (i+1)
let rec is_empty t =
match t with
| Split (l, r) -> is_empty l && is_empty r
| Table a -> is_empty_array (PArray.reroot a) 0
(** The address in a bucket array, after probing [i] times *) (** The address in a bucket array, after probing [i] times *)
let addr n h i = ((h land max_int) + i) mod n let addr n h i = ((h land max_int) + i) mod n
@ -358,6 +369,12 @@ module Flat(X : HASH) = struct
size = 0; size = 0;
} }
let rec is_empty_array a i =
if i = Array.length a then true
else (a.(i) = Empty || a.(i) = Deleted) && is_empty_array a (i+1)
let is_empty t = is_empty_array (PArray.reroot t.buckets) 0
(** Index of slot, for i-th probing starting from hash [h] in (** Index of slot, for i-th probing starting from hash [h] in
a table of length [n] *) a table of length [n] *)
let addr h n i = ((h land max_int) + i) mod n let addr h n i = ((h land max_int) + i) mod n

View file

@ -41,6 +41,8 @@ module type S = sig
val empty : int -> 'a t val empty : int -> 'a t
(** The empty hashtable (with sub-hashtables of given size) *) (** The empty hashtable (with sub-hashtables of given size) *)
val is_empty : _ t -> bool
val find : 'a t -> key -> 'a val find : 'a t -> key -> 'a
(** Find the binding for this key, or raise Not_found *) (** Find the binding for this key, or raise Not_found *)

View file

@ -2,7 +2,6 @@
open OUnit open OUnit
module Test(SomeHashtbl : FHashtbl.S with type key = int) = struct module Test(SomeHashtbl : FHashtbl.S with type key = int) = struct
let test_add () = let test_add () =
let h = SomeHashtbl.empty 32 in let h = SomeHashtbl.empty 32 in
let h = SomeHashtbl.replace h 42 "foo" in let h = SomeHashtbl.replace h 42 "foo" in
@ -79,6 +78,17 @@ module Test(SomeHashtbl : FHashtbl.S with type key = int) = struct
(* test that 2 has been removed *) (* test that 2 has been removed *)
OUnit.assert_raises Not_found (fun () -> SomeHashtbl.find h 2) OUnit.assert_raises Not_found (fun () -> SomeHashtbl.find h 2)
let test_size () =
let open Sequence.Infix in
let n = 10000 in
let seq = Sequence.map (fun i -> i, string_of_int i) (0 -- n) in
let h = SomeHashtbl.of_seq seq in
OUnit.assert_equal (n+1) (SomeHashtbl.size h);
let h = Sequence.fold (fun h i -> SomeHashtbl.remove h i) h (0 -- 500) in
OUnit.assert_equal (n-500) (SomeHashtbl.size h);
OUnit.assert_bool "is_empty" (SomeHashtbl.is_empty (SomeHashtbl.empty 16));
()
let suite = let suite =
"test_FHashtbl" >::: "test_FHashtbl" >:::
[ "test_add" >:: test_add; [ "test_add" >:: test_add;
@ -88,6 +98,7 @@ module Test(SomeHashtbl : FHashtbl.S with type key = int) = struct
"test_persistent" >:: test_persistent; "test_persistent" >:: test_persistent;
"test_big" >:: test_big; "test_big" >:: test_big;
"test_remove" >:: test_remove; "test_remove" >:: test_remove;
"test_size" >:: test_size;
] ]
end end