To answer this I had to remember how to use CVS again because the code was from 2004 ... It turns out that (for reasons I don't recall now) I modified the code to limit what could appear in the spreadsheet and use an alternate algorithm only when there were more than 500 lines in the spreadsheet. The final code was below. Unfortunately I lost the actual change, but you can work it out:
let max_map_regexp = 500 (* lines - see below *)
(* Format of the map_file. *)
type map_file_t =
| Map of ((Pcre.regexp * Pcre.regexp *
Pcre.regexp * Pcre.regexp) *
(float option * bool * Inp.params)) list
| Hash of (string * string * string * string,
float option * bool * Inp.params) Hashtbl.t
let run map_filename =
(* Parse the map file. *)
let csv = Csv.load map_filename in
if Csv.lines csv < 2 then
failwith (map_filename ^
": bid file should contain headings and at least one row of data");
let csv' = List.tl csv in (* Ignore headings. *)
...
(* If the map file is > max_map_regexp lines long then regular
* expressions are banned and a more efficient hash table format
* is used for lookups. Otherwise the program takes far too long
* to run.
*)
let map_file =
if List.length map_file <= max_map_regexp then (
Map (List.map (
fun ((c_name, ag_name, kw_text, kw_type), a) ->
(compile c_name, compile ag_name, compile kw_text,
compile kw_type), a
) map_file)
) else (
(* Regexps banned from large map files. *)
Hash (
let h = Hashtbl.create (List.length map_file) in
List.iter (
fun ((c_name, ag_name, kw_text, kw_type), a) ->
Hashtbl.add h (c_name, ag_name, kw_text,
String.lowercase kw_type) a
) map_file;
h
)
) in