let make_indexes default =
(** A hash table maps all known identifiers to integer values. It provides one direction of the global mapping. *) |
let table =
Hashtbl.create 1023
and
(** An infinite array maps all known integer values to identifiers. It provides the other direction of the global mapping. *) |
array =
InfiniteArray.make default (* Dummy data. *)
(** A global counter contains the next available integer label. *) |
and counter =
ref 0
in
(** 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 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 . *) |
and export i =
assert (i < !counter);
InfiniteArray.get array i
and find s =
Hashtbl.find table s
in
(import, export, find)