mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
added PHashtbl.get_eq/get_hash, to access the functions;
added a function to create a PHashtbl from a module; added PHashtbl.map
This commit is contained in:
parent
01e008256c
commit
25a7d33985
3 changed files with 62 additions and 2 deletions
26
pHashtbl.ml
26
pHashtbl.ml
|
|
@ -51,6 +51,17 @@ let create ?(max_load=0.8) ?(eq=fun x y -> x = y)
|
|||
eq;
|
||||
hash; }
|
||||
|
||||
module type Hashable = sig
|
||||
type t
|
||||
val equal : t -> t -> bool
|
||||
val hash : t -> int
|
||||
end
|
||||
|
||||
(** Create a hashtable from the given 'typeclass' *)
|
||||
let create_tc (type key) (h : (module Hashable with type t = key)) size =
|
||||
let module H = (val h) in
|
||||
create ~eq:H.equal ~hash:H.hash size
|
||||
|
||||
(** Copy of the hashtable *)
|
||||
let copy t = {
|
||||
eq = t.eq;
|
||||
|
|
@ -179,6 +190,17 @@ let fold f acc t =
|
|||
done;
|
||||
!acc
|
||||
|
||||
(** Map, replaces values by other values *)
|
||||
let map f t =
|
||||
let t' = create ~eq:t.eq ~hash:t.hash (Array.length t.buckets) in
|
||||
for i = 0 to Array.length t.buckets - 1 do
|
||||
match t.buckets.(i) with
|
||||
| (_, _, Empty) -> ()
|
||||
| (k, _, Deleted) -> t'.buckets.(i) <- my_deleted k
|
||||
| (k, v, Used) -> t'.buckets.(i) <- (k, f k v, Used)
|
||||
done;
|
||||
t'
|
||||
|
||||
(** Destructive filter (remove bindings that do not satisfiy predicate) *)
|
||||
let filter pred t =
|
||||
for i = 0 to Array.length t.buckets - 1 do
|
||||
|
|
@ -201,3 +223,7 @@ let to_seq t =
|
|||
|
||||
(** Statistics on the table *)
|
||||
let stats t = (Array.length t.buckets, t.size, t.size, 0, 0, 1)
|
||||
|
||||
let get_eq t = t.eq
|
||||
|
||||
let get_hash t = t.hash
|
||||
|
|
|
|||
28
pHashtbl.mli
28
pHashtbl.mli
|
|
@ -25,8 +25,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
(** {1 Open addressing hashtable, with linear probing} *)
|
||||
|
||||
type ('a, 'b) t
|
||||
(** Polymorphic hashtable *)
|
||||
type ('a, 'b) t = private {
|
||||
mutable buckets : ('a * 'b * state) array;
|
||||
mutable size : int;
|
||||
eq : 'a -> 'a -> bool;
|
||||
hash : 'a -> int;
|
||||
max_load : float;
|
||||
} (** A hashtable is an array of (key, value) buckets that have a state,
|
||||
plus the size of the table and equality/hash functions *)
|
||||
and state = Used | Empty | Deleted
|
||||
(** state of a bucket *)
|
||||
|
||||
val create : ?max_load:float -> ?eq:('a -> 'a -> bool) ->
|
||||
?hash:('a -> int) -> int -> ('a, 'b) t
|
||||
|
|
@ -34,6 +42,15 @@ val create : ?max_load:float -> ?eq:('a -> 'a -> bool) ->
|
|||
and must be in ]0, 1[. Functions for equality check and hashing
|
||||
can also be provided. *)
|
||||
|
||||
module type Hashable = sig
|
||||
type t
|
||||
val equal : t -> t -> bool
|
||||
val hash : t -> int
|
||||
end
|
||||
|
||||
val create_tc : (module Hashable with type t = 'a) -> int -> ('a, 'b) t
|
||||
(** Create a hashtable from the given 'typeclass' *)
|
||||
|
||||
val copy : ('a, 'b) t -> ('a, 'b) t
|
||||
(** Copy of the hashtable *)
|
||||
|
||||
|
|
@ -61,6 +78,9 @@ val mem : ('a,_) t -> 'a -> bool
|
|||
val iter : ('a -> 'b -> unit) -> ('a, 'b) t -> unit
|
||||
(** Iterate on bindings *)
|
||||
|
||||
val map : ('a -> 'b -> 'c) -> ('a, 'b) t -> ('a, 'c) t
|
||||
(** Map, replaces values by other values *)
|
||||
|
||||
val filter : ('a -> 'b -> bool) -> ('a, 'b) t -> unit
|
||||
(** Destructive filter (remove bindings that do not satisfiy predicate) *)
|
||||
|
||||
|
|
@ -75,3 +95,7 @@ val to_seq : ('a, 'b) t -> ('a * 'b) Sequence.t
|
|||
|
||||
val stats : (_, _) t -> int * int * int * int * int * int
|
||||
(** Cf Weak.S *)
|
||||
|
||||
val get_eq : ('v, _) t -> ('v -> 'v -> bool)
|
||||
|
||||
val get_hash : ('v, _) t -> ('v -> int)
|
||||
|
|
|
|||
|
|
@ -83,6 +83,16 @@ let test_filter () =
|
|||
OUnit.assert_bool "mem" (PHashtbl.mem h 4);
|
||||
OUnit.assert_bool "mem" (PHashtbl.mem h 2)
|
||||
|
||||
let test_map () =
|
||||
let h = PHashtbl.create 5 in
|
||||
PHashtbl.of_seq h my_seq;
|
||||
let h' = PHashtbl.map (fun k v -> String.uppercase v) h in
|
||||
OUnit.assert_equal (PHashtbl.length h') 4;
|
||||
OUnit.assert_equal (PHashtbl.find h' 1) "A";
|
||||
OUnit.assert_equal (PHashtbl.find h' 2) "B";
|
||||
OUnit.assert_equal (PHashtbl.find h' 3) "C";
|
||||
OUnit.assert_equal (PHashtbl.find h' 4) "D"
|
||||
|
||||
let suite =
|
||||
"test_pHashtbl" >:::
|
||||
[ "test_add" >:: test_add;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue