# Module Hashtbl2

    module Hashtbl2: sig .. end

`mem1 t key1` is true iff \exists key2 s.t. `find t key1 key2` is not None *

    module type Key = sig .. end

    type ('key1, 'key2, 'data) t

    include Invariant.S3

    val clear : ('a, 'b, 'c) t -> unit

    val add_exn : ('key1, 'key2, 'data) t -> 'key1 -> 'key2 -> 'data -> unit

    val set : ('key1, 'key2, 'data) t -> 'key1 -> 'key2 -> 'data -> unit

    val remove_exn : ('key1, 'key2, 'data) t -> 'key1 -> 'key2 -> unit

    val remove_all1 : ('key1, 'key2, 'data) t -> 'key1 -> unit

    val find : ('key1, 'key2, 'data) t -> 'key1 -> 'key2 -> 'data option

    val find1 : ('key1, 'key2, 'data) t ->
           'key1 -> ('key2, 'data) Core.Std.Hashtbl.t option

    val mem1 : ('key1, 'key2, 'data) t -> 'key1 -> bool

`mem1 t key1` is true iff \exists key2 s.t. `find t key1 key2` is not None *

    val iter : ('key1, 'key2, 'data) t ->
           f:('key1 -> 'key2 -> 'data -> unit) -> unit

    val iter_key2 : ('key1, 'key2, 'data) t ->
           'key1 -> f:('key2 -> 'data -> unit) -> unit

`iter_key2 t key1 ~f` is a no-op unless `mem1 t key1` *

    module Make: functor (Key1 : Key) -> functor (Key2 : Key) -> sig .. end

    val sexp_of_t : ('key1 -> Sexplib.Sexp.t) ->
           ('key2 -> Sexplib.Sexp.t) ->
           ('data -> Sexplib.Sexp.t) ->
           ('key1, 'key2, 'data) t -> Sexplib.Sexp.t

`mem1 t key1` is true iff \exists key2 s.t. `find t key1 key2` is not None *
`iter_key2 t key1 ~f` is a no-op unless `mem1 t key1` *