Source

ocaml-lib / genid.ml

Full commit

(** {1 Id Generator} *)

open Persindex

exception No_more_id

class genid (name : string) (db : database) =
  object (self)
    val cpt : (unit,int) index = new var_atom (-1) (fun () -> 0) db
    val all_free : (unit,int list) index = new var_opt_atom (fun () -> []) db

    initializer
      cpt # locate name name "cpt";
      all_free # locate name name "all_free"

    method name = name

    method sync =
      cpt # sync;
      all_free # sync

    method alloc =
      match all_free # get () with
      | [] ->
	  let c = cpt # get () in
	  if c < max_int
	  then begin cpt # set () (c+1); c+1 end
	  else raise No_more_id
      | id::l ->
	  all_free # set () l;
	  id

    method free id =
      all_free # update () (fun l -> id::l)

    method valid id =
      id > 0 && id <= cpt # get () && not (List.mem id (all_free # get ()))
  end