Merge branch 'local-ocamlbuild' into local-trunk
[SXSI/xpathcomp.git] / src / ocaml.ml
diff --git a/src/ocaml.ml b/src/ocaml.ml
new file mode 100644 (file)
index 0000000..b8acb29
--- /dev/null
@@ -0,0 +1,53 @@
+open Obj
+
+module H = Hashtbl.Make(
+  struct
+    type t = Obj.t
+    let equal = (==)
+    let hash o = Hashtbl.hash (magic o : int)
+  end)
+
+let node_table = (H.create 257 : unit H.t)
+
+let in_table o = try H.find node_table o; true with Not_found -> false
+
+let add_in_table o = H.add node_table o ()
+
+let reset_table () = H.clear node_table
+
+let size_of_double = size (repr 1.0)
+
+let count = ref 0
+
+let rec traverse t =
+  if not (in_table t) then begin
+    add_in_table t;
+    if is_block t then begin
+      let n = size t in
+      let tag = tag t in
+      if tag < no_scan_tag then begin
+       count := !count + 1 + n;
+       for i = 0 to n - 1 do
+         let f = field t i in
+         if is_block f then traverse f
+       done
+      end else if tag = string_tag then
+       count := !count + 1 + n
+      else if tag = double_tag then
+       count := !count + size_of_double
+      else if tag = double_array_tag then
+       count := !count + 1 + size_of_double * n
+      else
+       incr count
+    end
+  end
+
+let size_w o =
+  reset_table ();
+  count := 0;
+  traverse (repr o);
+  !count
+
+let size_b o = (size_w o) * (Sys.word_size / 8)
+
+let size_kb o = (size_w o) / (8192 / Sys.word_size)