: sig
(** This module maintains a global mapping from identifiers to abstract ``labels'', which are internally represented as integers, and back. *) |
type t
(** compare x y is a total ordering. It returns a negative integer
if x is less than y , 0 if x and y are equal, and a
positive integer if x is greater than y . *) |
val compare: t -> t -> int
(** import s associates a unique label with the identifier s ,
possibly extending the global mapping if s was never encountered
so far. Thus, if s and t are equal strings, possibly allocated
in different memory locations, import s and import t return
the same label. The identifier s is recorded and may be later
recovered via export . *) |
val import: lname -> t
(** export i provides access to the inverse of the global mapping,
that is, associates a unique identifier with every label. The
identifier associated with a label is the one originally supplied
to import . *) |
val export: t -> lname
end = struct
(** A row label is an object of type t , that is, an integer. *) |
type t = int
let compare = (-)
(** A hash table maps all known identifiers to integer values. It provides one direction of the global mapping. *) |
let table =
Hashtbl.create 1023
(** An infinite array maps all known integer values to identifiers. It provides the other direction of the global mapping. *) |
let array =
InfiniteArray.make "<BUG>" (* Dummy data. *)
(** A global counter contains the next available integer label. *) |
let counter =
ref 0
(** import s associates a unique label with the identifier s ,
possibly extending the global mapping if s was never encountered
so far. Thus, if s and t are equal strings, possibly allocated
in different memory locations, import s and import t return
the same label. The identifier s is recorded and may be later
recovered via export . *) |
let import (LName s) =
try
Hashtbl.find table s
with Not_found ->
let i = !counter in
Hashtbl.add table s i;
InfiniteArray.set array i s;
counter := i + 1;
i
(** export i provides access to the inverse of the global mapping,
that is, associates a unique identifier with every label. The
identifier associated with a label is the one originally supplied
to import . *) |
let export i =
assert (i < !counter);
LName (InfiniteArray.get array i)
end