ocaml / bytecomp / dectree.ml

open Lambda


(* Input: a list of (key, action) pairs, where keys are integers. *)
(* Output: a table of (low, high, offset) triples for Ktranslate
           an array of actions for Kswitch *)

let make_decision_tree casei =
  (* Sort the cases by increasing keys *)
  let cases =
    Sort.list (fun (key1,act1) (key2,act2) -> key1 <= key2) casei in
  (* Extract the keys and the actions *)
  let keyv = Array.of_list (List.map fst cases)
  and actv = Array.of_list (List.map snd cases) in
  let n = Array.length keyv in
  (* Partition the set of keys keyv into maximal dense enough segments.
     A segment is dense enough if its span (max point - min point) is
     less than four times its size (number of points). *)
  let rec partition start =
    if start >= n then [] else
    let stop = ref (n-1) in
    while let span = keyv.(!stop) - keyv.(start) in
          span >= 256 or span > 4 * (!stop - start) do
      decr stop
    done;
    (* We've found a dense enough segment.
       In the worst case, !stop = start and the segment is a single point *)
    (* Record the segment and continue *)
    (start, !stop) :: partition (!stop + 1) in
  let part = partition 0 in
  (* Compute the length of the switch table.
     Slot 0 is reserved and always contains Lstaticfail. *)
  let switchl = ref 1 in
  List.iter
    (fun (start, stop) -> switchl := !switchl + keyv.(stop) - keyv.(start) + 1)
    part;
  (* Build the two tables *)
  let transl = Array.new (List.length part) (0, 0, 0)
  and switch = Array.new !switchl Lstaticfail in
  let tr_pos = ref 0
  and sw_ind = ref 1 in
  List.iter
    (fun (start, stop) ->
      transl.(!tr_pos) <- (keyv.(start), keyv.(stop), !sw_ind);
      for i = start to stop do
        switch.(!sw_ind + keyv.(i) - keyv.(start)) <- actv.(i)
      done;
      incr tr_pos;
      sw_ind := !sw_ind + keyv.(stop) - keyv.(start) + 1)
    part;
  (transl, switch)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.