Skip to content

Commit

Permalink
Add reset, find_opt and Seq functions to BatHashtbl (#1133)
Browse files Browse the repository at this point in the history
* Add compat test for Hashtbl.Make

* Fix Hashtbl.Make compatibility with Stdlib

* Add PR #1133 to ChangeLog

* Fix BatHashtbl.Make.find_opt on OCaml < 4.05

---------

Co-authored-by: Francois Berenger <[email protected]>
  • Loading branch information
sim642 and UnixJunkie authored May 7, 2024
1 parent 87f35e1 commit d22f5ed
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 1 deletion.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Changelog

## NEXT_RELEASE

- Add reset, find_opt and Seq functions to BatHashtbl
#1133
(Simmo Saan)

- Add Stdlib type equality to Set.Make, Map.Make and Hashtbl.Make
#1132
(Simmo Saan)
Expand Down
23 changes: 23 additions & 0 deletions src/batHashtbl.ml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
type ('a, 'b) t = ('a, 'b) Hashtbl.t
let create s = Hashtbl.create s
let clear = Hashtbl.clear
let reset = Hashtbl.reset
let add = Hashtbl.add
let copy = Hashtbl.copy
let find = Hashtbl.find
Expand All @@ -43,6 +44,13 @@ let hash = Hashtbl.hash
type statistics = Hashtbl.statistics
let stats = Hashtbl.stats

##V>=4.07##let to_seq = Hashtbl.to_seq
##V>=4.07##let to_seq_keys = Hashtbl.to_seq_keys
##V>=4.07##let to_seq_values = Hashtbl.to_seq_values
##V>=4.07##let add_seq = Hashtbl.add_seq
##V>=4.07##let replace_seq = Hashtbl.replace_seq
##V>=4.07##let of_seq = Hashtbl.of_seq

type ('a, 'b) h_bucketlist =
| Empty
| Cons of 'a * 'b * ('a, 'b) h_bucketlist
Expand Down Expand Up @@ -220,6 +228,8 @@ let find_option h key =
let pos = key_index h key in
loop (Array.unsafe_get (h_conv h).data pos)

let find_opt = find_option

exception Verified

let exists p ht =
Expand Down Expand Up @@ -572,6 +582,7 @@ sig
val length : 'a t -> int
val is_empty : 'a t -> bool
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
Expand All @@ -580,6 +591,8 @@ sig
val find_all : 'a t -> key -> 'a list
val find_default : 'a t -> key -> 'a -> 'a
val find_option : 'a t -> key -> 'a option
val find_opt : 'a t -> key -> 'a option

val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
Expand All @@ -602,6 +615,14 @@ sig
val merge_all : (key -> 'a list -> 'b list -> 'c list) ->
'a t -> 'b t -> 'c t
val stats : 'a t -> statistics

##V>=4.07## val to_seq : 'a t -> (key * 'a) Seq.t
##V>=4.07## val to_seq_keys : _ t -> key Seq.t
##V>=4.07## val to_seq_values : 'a t -> 'a Seq.t
##V>=4.07## val add_seq : 'a t -> (key * 'a) Seq.t -> unit
##V>=4.07## val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
##V>=4.07## val of_seq : (key * 'a) Seq.t -> 'a t

val keys : 'a t -> key BatEnum.t
val values : 'a t -> 'a BatEnum.t
val enum : 'a t -> (key * 'a) BatEnum.t
Expand Down Expand Up @@ -812,6 +833,8 @@ struct
let pos = key_index h key in
loop (Array.unsafe_get hc.data pos)

##V<4.05## let find_opt = find_option

let find_default h key defval =
let hc = h_conv (to_hash h) in
let rec loop = function
Expand Down
56 changes: 56 additions & 0 deletions src/batHashtbl.mli
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,53 @@ val copy : ('a, 'b) t -> ('a, 'b) t
val clear : ('a, 'b) t -> unit
(** Empty a hash table. *)

val reset : ('a, 'b) t -> unit
(** Empty a hash table and shrink the size of the bucket table
to its initial size.
@since NEXT_RELEASE and OCaml 4.00 *)

val stats : ('a, 'b) t -> statistics
(** [Hashtbl.stats tbl] returns statistics about the table [tbl]:
number of buckets, size of the biggest bucket, distribution of
buckets by size.
@since 4.00.0 and batteries 3.5.1 *)

(** {1 Sequences} *)

##V>=4.07##val to_seq : ('a,'b) t -> ('a * 'b) Seq.t
##V>=4.07##(** Iterate on the whole table. The order in which the bindings
##V>=4.07## appear in the sequence is unspecified. However, if the table contains
##V>=4.07## several bindings for the same key, they appear in reversed order of
##V>=4.07## introduction, that is, the most recent binding appears first.
##V>=4.07##
##V>=4.07## The behavior is not specified if the hash table is modified
##V>=4.07## during the iteration.
##V>=4.07##
##V>=4.07## @since NEXT_RELEASE and OCaml 4.07 *)
##V>=4.07##
##V>=4.07##val to_seq_keys : ('a,_) t -> 'a Seq.t
##V>=4.07##(** Same as [Seq.map fst (to_seq m)]
##V>=4.07## @since NEXT_RELEASE and OCaml 4.07 *)
##V>=4.07##
##V>=4.07##val to_seq_values : (_,'b) t -> 'b Seq.t
##V>=4.07##(** Same as [Seq.map snd (to_seq m)]
##V>=4.07## @since NEXT_RELEASE and OCaml 4.07 *)
##V>=4.07##
##V>=4.07##val add_seq : ('a,'b) t -> ('a * 'b) Seq.t -> unit
##V>=4.07##(** Add the given bindings to the table, using {!add}
##V>=4.07## @since NEXT_RELEASE and OCaml 4.07 *)
##V>=4.07##
##V>=4.07##val replace_seq : ('a,'b) t -> ('a * 'b) Seq.t -> unit
##V>=4.07##(** Add the given bindings to the table, using {!replace}
##V>=4.07## @since NEXT_RELEASE and OCaml 4.07 *)
##V>=4.07##
##V>=4.07##val of_seq : ('a * 'b) Seq.t -> ('a, 'b) t
##V>=4.07##(** Build a table from the given bindings. The bindings are added
##V>=4.07## in the same order they appear in the sequence, using {!replace_seq},
##V>=4.07## which means that if two pairs have the same key, only the latest one
##V>=4.07## will appear in the table.
##V>=4.07## @since NEXT_RELEASE and OCaml 4.07 *)

(**{1 Enumerations}*)

val keys : ('a,'b) t -> 'a BatEnum.t
Expand Down Expand Up @@ -159,6 +200,10 @@ val find_option : ('a,'b) t -> 'a -> 'b option
(** Find a binding for the key, or return [None] if no
value is found *)

val find_opt : ('a, 'b) t -> 'a -> 'b option
(** [Stdlib]-compatible alias for {!find_option}.
@since NEXT_RELEASE *)

val exists : ('a -> 'b -> bool) -> ('a,'b) t -> bool
(** Check if at least one key-value pair satisfies [p k v] *)

Expand Down Expand Up @@ -399,6 +444,7 @@ sig
val length : 'a t -> int
val is_empty : 'a t -> bool
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
Expand All @@ -407,6 +453,8 @@ sig
val find_all : 'a t -> key -> 'a list
val find_default : 'a t -> key -> 'a -> 'a
val find_option : 'a t -> key -> 'a option
val find_opt : 'a t -> key -> 'a option

val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
Expand All @@ -429,6 +477,14 @@ sig
val merge_all : (key -> 'a list -> 'b list -> 'c list) ->
'a t -> 'b t -> 'c t
val stats : 'a t -> statistics

##V>=4.07## val to_seq : 'a t -> (key * 'a) Seq.t
##V>=4.07## val to_seq_keys : _ t -> key Seq.t
##V>=4.07## val to_seq_values : 'a t -> 'a Seq.t
##V>=4.07## val add_seq : 'a t -> (key * 'a) Seq.t -> unit
##V>=4.07## val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
##V>=4.07## val of_seq : (key * 'a) Seq.t -> 'a t

val keys : 'a t -> key BatEnum.t
val values : 'a t -> 'a BatEnum.t
val enum : 'a t -> (key * 'a) BatEnum.t
Expand Down
6 changes: 5 additions & 1 deletion src/batteries_compattest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ module Stdlib_verifications = struct
val print_stat : 'a BatInnerIO.output -> unit
end)
module Genlex = (Genlex : module type of Legacy.Genlex)
(* module Hashtbl = (Hashtbl: module type of Legacy.Hashtbl)*)
(* module Hashtbl = (Hashtbl: module type of Legacy.Hashtbl) *)
module Hashtbl =
struct
module Make = (Hashtbl.Make : module type of Legacy.Hashtbl.Make)
end
module Int32 = (Int32: module type of Legacy.Int32)
module Int64 = (Int64: module type of Legacy.Int64)
module Lexing =
Expand Down

0 comments on commit d22f5ed

Please sign in to comment.