(* Universe *)
(* $Id: universe.ml,v 1.1 2004/07/20 14:17:04 berke Exp $ *)

(* A universe is a set of documents.  A result within a universe is a subset
 * of the universe.
 * Concretely, a document is a file, ie. a filename.
 * The Universe module provides : 1) integer <-> string bijection and 2) set operations.
*)

type 'a t = {
  table : (int,'a) Hashtbl.t;
  index : ('a,int) Hashtbl.t;
  mutable counter : int;
}

let create () = { table = Hashtbl.create 256; index = Hashtbl.create 256; counter = 0 }

let clear u =
  Hashtbl.clear u.table;
  Hashtbl.clear u.index;
  u.counter <- 0

let register u x =
  try
    Hashtbl.find u.index x
  with
  | Not_found ->
      let id = u.counter in
      Hashtbl.add u.index x id;
      Hashtbl.add u.table id x;
      u.counter <- id + 1;
      id

let lookup u i = Hashtbl.find u.table i

module S = Set.Make(struct type t = int let compare i j = compare i j end)

let iter u f =
  for i = 0 to u.counter - 1 do
    f i (Hashtbl.find u.table i)
  done

let all u =
  let rec loop i s =
    if i = u.counter then
      s
    else
      loop (i + 1) (S.add i s)
  in
  loop 0 S.empty
