add hmap as a depopt (#28)

if present, we use `Hmap.t` as the meta map for manual spans
This commit is contained in:
Simon Cruanes 2024-02-24 11:33:48 -05:00 committed by GitHub
parent 05be245163
commit 3c2f804716
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 111 additions and 125 deletions

View file

@ -42,3 +42,7 @@ jobs:
- run: opam install trace - run: opam install trace
- run: opam exec -- dune runtest -p trace-tef,trace-fuchsia - run: opam exec -- dune runtest -p trace-tef,trace-fuchsia
# with depopts
- run: opam install hmap
- run: opam exec -- dune build '@install' -p trace,trace-tef,trace-fuchsia

View file

@ -19,6 +19,7 @@
(ocaml (>= 4.08)) (ocaml (>= 4.08))
dune) dune)
(depopts (depopts
hmap
(mtime (>= 2.0))) (mtime (>= 2.0)))
(tags (tags
(trace tracing observability profiling))) (trace tracing observability profiling)))

View file

@ -2,6 +2,9 @@
(library (library
(name trace_core) (name trace_core)
(public_name trace.core) (public_name trace.core)
(libraries (select meta_map.ml from
(hmap -> meta_map.hmap.ml)
(-> meta_map.ourown.ml)))
(synopsis "Lightweight stub for tracing") (synopsis "Lightweight stub for tracing")
) )

View file

@ -0,0 +1,3 @@
include Hmap
let find_exn = get

View file

@ -1,83 +0,0 @@
module type KEY_IMPL = sig
type t
exception Store of t
val id : int
end
module Key = struct
type 'a t = (module KEY_IMPL with type t = 'a)
let _n = ref 0
let create (type k) () =
incr _n;
let id = !_n in
let module K = struct
type t = k
let id = id
exception Store of k
end in
(module K : KEY_IMPL with type t = k)
let id (type k) (module K : KEY_IMPL with type t = k) = K.id
let equal : type a b. a t -> b t -> bool =
fun (module K1) (module K2) -> K1.id = K2.id
end
type pair = Pair : 'a Key.t * 'a -> pair
type exn_pair = E_pair : 'a Key.t * exn -> exn_pair
let pair_of_e_pair (E_pair (k, e)) =
let module K = (val k) in
match e with
| K.Store v -> Pair (k, v)
| _ -> assert false
module M = Map.Make (struct
type t = int
let compare (i : int) j = Stdlib.compare i j
end)
type t = exn_pair M.t
let empty = M.empty
let mem k t = M.mem (Key.id k) t
let find_exn (type a) (k : a Key.t) t : a =
let module K = (val k) in
let (E_pair (_, e)) = M.find K.id t in
match e with
| K.Store v -> v
| _ -> assert false
let find k t = try Some (find_exn k t) with Not_found -> None
let add_e_pair_ p t =
let (E_pair ((module K), _)) = p in
M.add K.id p t
let add_pair_ p t =
let (Pair (((module K) as k), v)) = p in
let p = E_pair (k, K.Store v) in
M.add K.id p t
let add (type a) (k : a Key.t) v t =
let module K = (val k) in
add_e_pair_ (E_pair (k, K.Store v)) t
let remove (type a) (k : a Key.t) t =
let module K = (val k) in
M.remove K.id t
let cardinal t = M.cardinal t
let length = cardinal
let iter f t = M.iter (fun _ p -> f (pair_of_e_pair p)) t
let to_list t = M.fold (fun _ p l -> pair_of_e_pair p :: l) t []
let add_list t l = List.fold_right add_pair_ l t
let of_list l = add_list empty l

View file

@ -1,37 +0,0 @@
(** Associative containers with Heterogeneous Values *)
(** Keys with a type witness. *)
module Key : sig
type 'a t
(** A key of type ['a t] is used to access the portion of the
map or table that associates keys of type ['a] to values. *)
val create : unit -> 'a t
(** Make a new key. This is generative, so calling [create ()] twice with the
same return type will produce incompatible keys that cannot see each
other's bindings. *)
val equal : 'a t -> 'a t -> bool
(** Compare two keys that have compatible types. *)
end
type pair = Pair : 'a Key.t * 'a -> pair
type t
(** Immutable map from {!Key.t} to values *)
val empty : t
val mem : _ Key.t -> t -> bool
val add : 'a Key.t -> 'a -> t -> t
val remove : _ Key.t -> t -> t
val length : t -> int
val cardinal : t -> int
val find : 'a Key.t -> t -> 'a option
val find_exn : 'a Key.t -> t -> 'a
(** @raise Not_found if the key is not in the table. *)
val iter : (pair -> unit) -> t -> unit
val add_list : t -> pair list -> t
val of_list : pair list -> t
val to_list : t -> pair list

View file

@ -0,0 +1,91 @@
module type KEY_IMPL = sig
type t
exception Store of t
val id : int
end
module Key = struct
type 'a t = (module KEY_IMPL with type t = 'a)
let _n = ref 0
let create (type k) () =
incr _n;
let id = !_n in
let module K = struct
type t = k
let id = id
exception Store of k
end in
(module K : KEY_IMPL with type t = k)
let[@inline] id (type k) (module K : KEY_IMPL with type t = k) = K.id
let equal : type a b. a t -> b t -> bool =
fun (module K1) (module K2) -> K1.id = K2.id
end
type 'a key = 'a Key.t
type binding = B : 'a Key.t * 'a -> binding
open struct
type exn_pair = E_pair : 'a Key.t * exn -> exn_pair
let pair_of_e_pair (E_pair (k, e)) =
let module K = (val k) in
match e with
| K.Store v -> B (k, v)
| _ -> assert false
end
module M = Map.Make (struct
type t = int
let compare (i : int) j = Stdlib.compare i j
end)
type t = { m: exn_pair M.t } [@@unboxed]
let empty : t = { m = M.empty }
let[@inline] mem k (self : t) = M.mem (Key.id k) self.m
let find_exn (type a) (k : a Key.t) (self : t) : a =
let module K = (val k) in
let (E_pair (_, e)) = M.find K.id self.m in
match e with
| K.Store v -> v
| _ -> assert false
let find k (self : t) = try Some (find_exn k self) with Not_found -> None
open struct
let add_e_pair_ p self =
let (E_pair ((module K), _)) = p in
{ m = M.add K.id p self.m }
let add_pair_ p (self : t) : t =
let (B (((module K) as k), v)) = p in
let p = E_pair (k, K.Store v) in
{ m = M.add K.id p self.m }
end
let add (type a) (k : a Key.t) v (self : t) : t =
let module K = (val k) in
add_e_pair_ (E_pair (k, K.Store v)) self
let remove (type a) (k : a Key.t) (self : t) : t =
let module K = (val k) in
{ m = M.remove K.id self.m }
let[@inline] cardinal (self : t) = M.cardinal self.m
let length = cardinal
let iter f (self : t) = M.iter (fun _ p -> f (pair_of_e_pair p)) self.m
let to_list (self : t) : binding list =
M.fold (fun _ p l -> pair_of_e_pair p :: l) self.m []
let add_list (self : t) l = List.fold_right add_pair_ l self

View file

@ -17,6 +17,9 @@ type explicit_span = {
span: span; span: span;
(** Identifier for this span. Several explicit spans might share the same (** Identifier for this span. Several explicit spans might share the same
identifier since we can differentiate between them via [meta]. *) identifier since we can differentiate between them via [meta]. *)
mutable meta: Meta_map.t; (** Metadata for this span (and its context) *) mutable meta: Meta_map.t;
(** Metadata for this span (and its context). This can be used by collectors to
carry collector-specific information from the beginning
of the span, to the end of the span. *)
} }
(** Explicit span, with collector-specific metadata *) (** Explicit span, with collector-specific metadata *)

View file

@ -110,7 +110,7 @@ type async_span_info = {
mutable data: (string * user_data) list; mutable data: (string * user_data) list;
} }
let key_async_data : async_span_info Meta_map.Key.t = Meta_map.Key.create () let key_async_data : async_span_info Meta_map.key = Meta_map.Key.create ()
open struct open struct
let state_id_ = A.make 0 let state_id_ = A.make 0

View file

@ -92,12 +92,12 @@ type span_info = {
} }
(** key used to carry a unique "id" for all spans in an async context *) (** key used to carry a unique "id" for all spans in an async context *)
let key_async_id : int Meta_map.Key.t = Meta_map.Key.create () let key_async_id : int Meta_map.key = Meta_map.Key.create ()
let key_async_data : (string * [ `Sync | `Async ] option) Meta_map.Key.t = let key_async_data : (string * [ `Sync | `Async ] option) Meta_map.key =
Meta_map.Key.create () Meta_map.Key.create ()
let key_data : (string * user_data) list ref Meta_map.Key.t = let key_data : (string * user_data) list ref Meta_map.key =
Meta_map.Key.create () Meta_map.Key.create ()
(** Writer: knows how to write entries to a file in TEF format *) (** Writer: knows how to write entries to a file in TEF format *)

View file

@ -15,6 +15,7 @@ depends: [
"odoc" {with-doc} "odoc" {with-doc}
] ]
depopts: [ depopts: [
"hmap"
"mtime" {>= "2.0"} "mtime" {>= "2.0"}
] ]
build: [ build: [