55 } |
55 } |
56 |
56 |
57 |
57 |
58 /* read data */ |
58 /* read data */ |
59 |
59 |
60 sealed case class Data(date: Date, entries: List[(String, List[Session])]) |
60 sealed case class Data(date: Date, entries: List[Data_Entry]) |
|
61 sealed case class Data_Entry(name: String, hosts: List[String], sessions: List[Session]) |
61 sealed case class Session(name: String, threads: Int, entries: List[Entry]) |
62 sealed case class Session(name: String, threads: Int, entries: List[Entry]) |
62 { |
63 { |
63 def timing: Timing = if (entries.isEmpty) Timing.zero else entries.head.timing |
64 def timing: Timing = if (entries.isEmpty) Timing.zero else entries.head.timing |
64 def ml_timing: Timing = if (entries.isEmpty) Timing.zero else entries.head.ml_timing |
65 def ml_timing: Timing = if (entries.isEmpty) Timing.zero else entries.head.ml_timing |
65 def order: Long = - timing.elapsed.ms |
66 def order: Long = - timing.elapsed.ms |
74 profiles: List[Profile] = default_profiles, |
75 profiles: List[Profile] = default_profiles, |
75 only_sessions: Set[String] = Set.empty, |
76 only_sessions: Set[String] = Set.empty, |
76 verbose: Boolean = false): Data = |
77 verbose: Boolean = false): Data = |
77 { |
78 { |
78 val date = Date.now() |
79 val date = Date.now() |
|
80 var data_hosts = Map.empty[String, Set[String]] |
79 var data_entries = Map.empty[String, Map[String, Session]] |
81 var data_entries = Map.empty[String, Map[String, Session]] |
|
82 |
|
83 def get_hosts(data_name: String): Set[String] = |
|
84 data_hosts.getOrElse(data_name, Set.empty) |
80 |
85 |
81 val store = Build_Log.store(options) |
86 val store = Build_Log.store(options) |
82 using(store.open_database())(db => |
87 using(store.open_database())(db => |
83 { |
88 { |
84 for (profile <- profiles.sortBy(_.description)) { |
89 for (profile <- profiles.sortBy(_.description)) { |
85 progress.echo("input " + quote(profile.description)) |
90 progress.echo("input " + quote(profile.description)) |
86 val columns = |
91 val columns = |
87 List( |
92 List( |
88 Build_Log.Data.pull_date, |
93 Build_Log.Data.pull_date, |
|
94 Build_Log.Prop.build_host, |
89 Build_Log.Settings.ISABELLE_BUILD_OPTIONS, |
95 Build_Log.Settings.ISABELLE_BUILD_OPTIONS, |
90 Build_Log.Settings.ML_PLATFORM, |
96 Build_Log.Settings.ML_PLATFORM, |
91 Build_Log.Data.session_name, |
97 Build_Log.Data.session_name, |
92 Build_Log.Data.threads, |
98 Build_Log.Data.threads, |
93 Build_Log.Data.timing_elapsed, |
99 Build_Log.Data.timing_elapsed, |
134 Build_Log.Data.ml_timing_elapsed, |
140 Build_Log.Data.ml_timing_elapsed, |
135 Build_Log.Data.ml_timing_cpu, |
141 Build_Log.Data.ml_timing_cpu, |
136 Build_Log.Data.ml_timing_gc), |
142 Build_Log.Data.ml_timing_gc), |
137 heap_size = res.long(Build_Log.Data.heap_size)) |
143 heap_size = res.long(Build_Log.Data.heap_size)) |
138 |
144 |
|
145 res.get_string(Build_Log.Prop.build_host).foreach(host => |
|
146 data_hosts += (data_name -> (get_hosts(data_name) + host))) |
|
147 |
139 val sessions = data_entries.getOrElse(data_name, Map.empty) |
148 val sessions = data_entries.getOrElse(data_name, Map.empty) |
140 val entries = sessions.get(session_name).map(_.entries) getOrElse Nil |
149 val entries = sessions.get(session_name).map(_.entries) getOrElse Nil |
141 val session = Session(session_name, threads, entry :: entries) |
150 val session = Session(session_name, threads, entry :: entries) |
142 data_entries += (data_name -> (sessions + (session_name -> session))) |
151 data_entries += (data_name -> (sessions + (session_name -> session))) |
143 } |
152 } |
144 }) |
153 }) |
145 } |
154 } |
146 }) |
155 }) |
147 |
156 |
148 Data(date, |
157 val sorted_entries = |
149 (for { |
158 (for { |
150 (data_name, sessions) <- data_entries.toList |
159 (name, sessions) <- data_entries.toList |
151 sorted_sessions <- |
160 sorted_sessions <- |
152 proper_list(sessions.toList.map(_._2).filter(_.check_timing).sortBy(_.order)) |
161 proper_list(sessions.toList.map(_._2).filter(_.check_timing).sortBy(_.order)) |
153 } yield (data_name, sorted_sessions)).sortBy(_._1)) |
162 } yield Data_Entry(name, get_hosts(name).toList.sorted, sorted_sessions)).sortBy(_.name) |
|
163 |
|
164 Data(date, sorted_entries) |
154 } |
165 } |
155 |
166 |
156 |
167 |
157 /* present data */ |
168 /* present data */ |
158 |
169 |
166 |
177 |
167 Isabelle_System.mkdirs(target_dir) |
178 Isabelle_System.mkdirs(target_dir) |
168 File.write(target_dir + Path.basic("index.html"), |
179 File.write(target_dir + Path.basic("index.html"), |
169 HTML.output_document( |
180 HTML.output_document( |
170 List(HTML.title("Isabelle build status")), |
181 List(HTML.title("Isabelle build status")), |
171 List(HTML.chapter("Isabelle build status (" + data.date + ")"), |
182 List(HTML.chapter("Isabelle build status"), |
172 HTML.itemize(data.entries.map({ case (data_name, _) => |
183 HTML.itemize(data.entries.map({ case data_entry => |
173 List(HTML.link(clean_name(data_name) + "/index.html", HTML.text(data_name))) }))))) |
184 List(HTML.link(clean_name(data_entry.name) + "/index.html", HTML.text(data_entry.name))) |
174 |
185 }))))) |
175 for ((data_name, sessions) <- data.entries) { |
186 |
|
187 for (data_entry <- data.entries) { |
|
188 val data_name = data_entry.name |
|
189 |
176 progress.echo("output " + quote(data_name)) |
190 progress.echo("output " + quote(data_name)) |
177 |
191 |
178 val dir = target_dir + Path.basic(clean_name(data_name)) |
192 val dir = target_dir + Path.basic(clean_name(data_name)) |
179 Isabelle_System.mkdirs(dir) |
193 Isabelle_System.mkdirs(dir) |
180 |
194 |
255 gnuplot(ml_timing_plots, "ml_timing", timing_range)) ::: |
269 gnuplot(ml_timing_plots, "ml_timing", timing_range)) ::: |
256 (if (session.check_heap) List(gnuplot(heap_plots, "heap", "[0:]")) else Nil) |
270 (if (session.check_heap) List(gnuplot(heap_plots, "heap", "[0:]")) else Nil) |
257 |
271 |
258 session.name -> plot_names |
272 session.name -> plot_names |
259 } |
273 } |
260 }, sessions).toMap |
274 }, data_entry.sessions).toMap |
261 |
275 |
262 File.write(dir + Path.basic("index.html"), |
276 File.write(dir + Path.basic("index.html"), |
263 HTML.output_document( |
277 HTML.output_document( |
264 List(HTML.title("Isabelle build status for " + data_name)), |
278 List(HTML.title("Isabelle build status for " + data_name)), |
265 HTML.chapter("Isabelle build status for " + data_name + " (" + data.date + ")") :: |
279 HTML.chapter("Isabelle build status for " + data_name) :: |
266 HTML.itemize( |
280 HTML.par( |
267 sessions.map(session => |
281 List(HTML.itemize( |
268 HTML.link("#session_" + session.name, HTML.text(session.name)) :: |
282 List( |
269 HTML.text(" (" + session.timing.message_resources + ")"))) :: |
283 HTML.bold(HTML.text("build host: ")) :: HTML.text(commas(data_entry.hosts)), |
270 sessions.flatMap(session => |
284 HTML.bold(HTML.text("status date: ")) :: HTML.text(data.date.toString))))) :: |
|
285 HTML.par( |
|
286 List(HTML.itemize( |
|
287 data_entry.sessions.map(session => |
|
288 HTML.link("#session_" + session.name, HTML.text(session.name)) :: |
|
289 HTML.text(" (" + session.timing.message_resources + ")"))))) :: |
|
290 data_entry.sessions.flatMap(session => |
271 List( |
291 List( |
272 HTML.section(session.name) + HTML.id("session_" + session.name), |
292 HTML.section(session.name) + HTML.id("session_" + session.name), |
273 HTML.par( |
293 HTML.par( |
274 HTML.itemize(List( |
294 HTML.itemize(List( |
275 HTML.bold(HTML.text("timing: ")) :: HTML.text(session.timing.message_resources), |
295 HTML.bold(HTML.text("timing: ")) :: HTML.text(session.timing.message_resources), |