27 val job_infos = CI_API.build_job_builds(job).sortBy(_.timestamp).reverse.take(history_length) |
27 val job_infos = CI_API.build_job_builds(job).sortBy(_.timestamp).reverse.take(history_length) |
28 if (job_infos.isEmpty) error("No build infos for job " + quote(job)) |
28 if (job_infos.isEmpty) error("No build infos for job " + quote(job)) |
29 |
29 |
30 val all_infos = |
30 val all_infos = |
31 Par_List.map((job_info: CI_API.Job_Info) => |
31 Par_List.map((job_info: CI_API.Job_Info) => |
32 (job_info.timestamp / 1000, job_info.read_output.parse_info), job_infos) |
32 (job_info.timestamp / 1000, job_info.read_output.parse_build_info), job_infos) |
33 val all_sessions = |
33 val all_sessions = |
34 (Set.empty[String] /: all_infos)( |
34 (Set.empty[String] /: all_infos)( |
35 { case (s, (_, info)) => s ++ info.sessions }) |
35 { case (s, (_, info)) => s ++ info.sessions.keySet }) |
36 |
36 |
37 def check_threshold(info: Build_Log.Info, session: String): Boolean = |
37 def check_threshold(info: Build_Log.Build_Info, session: String): Boolean = |
38 info.finished.get(session) match { |
38 (for (entry <- info.get_session(session); t <- entry.timing) |
39 case Some(t) => t.elapsed >= elapsed_threshold |
39 yield t.elapsed >= elapsed_threshold) getOrElse false |
40 case None => false |
|
41 } |
|
42 |
40 |
43 val sessions = |
41 val sessions = |
44 for { |
42 for { |
45 session <- (if (only_sessions.isEmpty) all_sessions else all_sessions & only_sessions) |
43 session <- (if (only_sessions.isEmpty) all_sessions else all_sessions & only_sessions) |
46 if all_infos.filter({ case (_, info) => check_threshold(info, session) }).length >= 3 |
44 if all_infos.filter({ case (_, info) => check_threshold(info, session) }).length >= 3 |
49 Isabelle_System.mkdirs(dir) |
47 Isabelle_System.mkdirs(dir) |
50 for (session <- sessions) { |
48 for (session <- sessions) { |
51 Isabelle_System.with_tmp_file(session, "png") { data_file => |
49 Isabelle_System.with_tmp_file(session, "png") { data_file => |
52 Isabelle_System.with_tmp_file(session, "gnuplot") { plot_file => |
50 Isabelle_System.with_tmp_file(session, "gnuplot") { plot_file => |
53 val data = |
51 val data = |
54 for { (t, info) <- all_infos if info.finished.isDefinedAt(session) } |
52 for { (t, info) <- all_infos if info.finished(session) } |
55 yield { |
53 yield { |
56 val finished = info.finished.getOrElse(session, Timing.zero) |
54 val timing1 = info.timing(session) |
57 val timing = info.timing.getOrElse(session, Timing.zero) |
55 val timing2 = info.ml_timing(session) |
58 List(t.toString, finished.elapsed.minutes, finished.cpu.minutes, |
56 List(t.toString, |
59 timing.elapsed.minutes, timing.cpu.minutes, timing.gc.minutes).mkString(" ") |
57 timing1.elapsed.minutes, |
|
58 timing1.cpu.minutes, |
|
59 timing2.elapsed.minutes, |
|
60 timing2.cpu.minutes, |
|
61 timing2.gc.minutes).mkString(" ") |
60 } |
62 } |
61 File.write(data_file, cat_lines(data)) |
63 File.write(data_file, cat_lines(data)) |
62 |
64 |
63 val plots1 = |
65 val plots1 = |
64 List( |
66 List( |