Renamed 'mark' functions to make them more consistent.
[ocaml-ancient.git] / test_ancient_weblogs.ml
1 (* Load in large weblogs and see if they can still be used.
2  * $Id: test_ancient_weblogs.ml,v 1.4 2006-10-06 12:25:20 rich Exp $
3  *)
4
5 open Printf
6
7 open ExtList
8
9 let gc_stats = true (* If true, print GC stats before processing each day. *)
10
11 let (//) = Filename.concat
12
13 let rec range a b =
14   if a > b then []
15   else a :: range (succ a) b
16
17 (* Cartesian join of two lists. *)
18 let cartesian xs ys =
19   List.flatten (
20     List.map (
21       fun x ->
22         List.map (
23           fun y -> x, y
24         ) ys
25     ) xs
26   )
27
28 let file_readable filename =
29   try Unix.access filename [Unix.R_OK]; true
30   with Unix.Unix_error _ -> false
31
32 (* Suppress warning messages. *)
33 let () = Weblogs.quiet := true
34
35 let gc_compact () =
36   eprintf "compacting ... %!";
37   Gc.compact ();
38   if gc_stats then (
39     let stat = Gc.stat () in
40     let live_words = stat.Gc.live_words in
41     eprintf "live words = %d (%d MB)\n%!"
42       live_words (live_words * 8 / 1024 / 1024)
43   )
44
45 (* Find the list of files.  Some which should exist don't, so
46  * warnings about those so we can chase up.
47  *)
48 let files =
49   let dir = "/home/rich/oversized-logfiles/perrys" in
50   let drivers =
51     [ "burns"; "gronholm"; "rohrl"; "sainz"; "solberg"; "vatanen" ] in
52   let dates = range 1 31 in
53   let dates = List.map (fun day -> sprintf "200608%02d" day) dates in
54   let files = cartesian drivers dates in
55   let files =
56     List.map (fun (driver, date) ->
57                 sprintf "%s-perrys-access.log.%s.gz" driver date) files in
58   let files =
59     List.filter_map (
60       fun filename ->
61         let path = dir // filename in
62         if not (file_readable path) then (
63           prerr_endline ("warning: " ^ filename ^ " not found - ignored");
64           None
65         ) else (
66           Some path
67         )
68     ) files in
69
70   eprintf "number of files = %d\n%!" (List.length files);
71
72   files
73
74 (*
75 (* XXX Linux/AMD64-specific hack to avoid bad mmap(2) allocation. *)
76 let baseaddr = Nativeint.of_string "0x440000000000"
77
78 let md =
79   let fd =
80     Unix.openfile "test_ancient_weblogs.data"
81       [Unix.O_RDWR; Unix.O_CREAT; Unix.O_TRUNC] 0o644 in
82   Ancient.attach fd baseaddr
83
84 (* Load each file into memory and make it ancient. *)
85 let () =
86   List.iteri (
87     fun key filename ->
88       let () =
89         let basename = Filename.basename filename in
90         eprintf "Importing logfile %s\n%!" basename;
91         let rows = Weblogs.import_file filename in
92         ignore (Ancient.share md key rows) in
93       gc_compact ()
94   ) files;
95
96   Ancient.detach md
97 *)
98
99 let () =
100   let fd = Unix.openfile "test_ancient_weblogs.data" [Unix.O_RDWR] 0o644 in
101   let md = Ancient.attach fd 0n in
102
103   eprintf "Flattening ...\n%!";
104
105   (* Concatenate all the logs together. *)
106   let rows =
107     List.flatten (
108       List.mapi (
109         fun key _ ->
110           let rows : Weblogs.t Ancient.ancient = Ancient.get md key in
111           let rows = Ancient.follow rows in
112           rows
113       ) files
114     ) in
115
116   eprintf "After flattening: %!";
117   gc_compact ();
118
119   (* Detect visitors.  Save to key 1023 in the file.  The detect_visitors
120    * function sorts each visitor.
121    *)
122   let visitors = Weblogs.detect_visitors rows in
123   ignore (Ancient.share md 1023 visitors);
124
125   eprintf "After detecting visitors: %!";
126   gc_compact ();
127
128   Ancient.detach md