From dabc9df46e34fffda2f8c162901802fb9a049ef7 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Sun, 10 Mar 2013 15:04:38 +0100 Subject: [PATCH] added a is_empty function for FHashtbl; more tests for FHashtbl --- fHashtbl.ml | 17 +++++++++++++++++ fHashtbl.mli | 2 ++ tests/test_fHashtbl.ml | 13 ++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/fHashtbl.ml b/fHashtbl.ml index f1e66dc9..56610856 100644 --- a/fHashtbl.ml +++ b/fHashtbl.ml @@ -41,6 +41,8 @@ module type S = sig val empty : int -> 'a t (** The empty hashtable (with sub-hashtables of given size) *) + val is_empty : _ t -> bool + val find : 'a t -> key -> 'a (** 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 *) 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 *) let addr n h i = ((h land max_int) + i) mod n @@ -358,6 +369,12 @@ module Flat(X : HASH) = struct 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 a table of length [n] *) let addr h n i = ((h land max_int) + i) mod n diff --git a/fHashtbl.mli b/fHashtbl.mli index 3ef8fbc2..f90e4aa7 100644 --- a/fHashtbl.mli +++ b/fHashtbl.mli @@ -41,6 +41,8 @@ module type S = sig val empty : int -> 'a t (** The empty hashtable (with sub-hashtables of given size) *) + val is_empty : _ t -> bool + val find : 'a t -> key -> 'a (** Find the binding for this key, or raise Not_found *) diff --git a/tests/test_fHashtbl.ml b/tests/test_fHashtbl.ml index 8d521ae6..4eced8ec 100644 --- a/tests/test_fHashtbl.ml +++ b/tests/test_fHashtbl.ml @@ -2,7 +2,6 @@ open OUnit module Test(SomeHashtbl : FHashtbl.S with type key = int) = struct - let test_add () = let h = SomeHashtbl.empty 32 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 *) 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 = "test_FHashtbl" >::: [ "test_add" >:: test_add; @@ -88,6 +98,7 @@ module Test(SomeHashtbl : FHashtbl.S with type key = int) = struct "test_persistent" >:: test_persistent; "test_big" >:: test_big; "test_remove" >:: test_remove; + "test_size" >:: test_size; ] end