673 ml_statistics = if (ml_statistics) log_file.filter_props(ML_STATISTICS_MARKER) else Nil, |
673 ml_statistics = if (ml_statistics) log_file.filter_props(ML_STATISTICS_MARKER) else Nil, |
674 task_statistics = if (task_statistics) log_file.filter_props("\ftask_statistics = ") else Nil, |
674 task_statistics = if (task_statistics) log_file.filter_props("\ftask_statistics = ") else Nil, |
675 errors = log_file.filter_lines(ERROR_MESSAGE_MARKER).map(Library.decode_lines(_))) |
675 errors = log_file.filter_lines(ERROR_MESSAGE_MARKER).map(Library.decode_lines(_))) |
676 } |
676 } |
677 |
677 |
678 def compress_errors(errors: List[String]): Option[Bytes] = |
678 def compress_errors(errors: List[String], cache: XZ.Cache = XZ.cache()): Option[Bytes] = |
679 if (errors.isEmpty) None |
679 if (errors.isEmpty) None |
680 else Some(Bytes(YXML.string_of_body(XML.Encode.list(XML.Encode.string)(errors))).compress()) |
680 else { |
681 |
681 Some(Bytes(YXML.string_of_body(XML.Encode.list(XML.Encode.string)(errors))). |
682 def uncompress_errors(bytes: Bytes): List[String] = |
682 compress(cache = cache)) |
|
683 } |
|
684 |
|
685 def uncompress_errors(bytes: Bytes, cache: XZ.Cache = XZ.cache()): List[String] = |
683 if (bytes.isEmpty) Nil |
686 if (bytes.isEmpty) Nil |
684 else XML.Decode.list(YXML.string_of_body(_))(YXML.parse_body(bytes.uncompress().text)) |
687 else { |
|
688 XML.Decode.list(YXML.string_of_body(_))(YXML.parse_body(bytes.uncompress(cache = cache).text)) |
|
689 } |
685 |
690 |
686 |
691 |
687 |
692 |
688 /** persistent store **/ |
693 /** persistent store **/ |
689 |
694 |
875 def store(options: Options): Store = new Store(options) |
880 def store(options: Options): Store = new Store(options) |
876 |
881 |
877 class Store private[Build_Log](options: Options) |
882 class Store private[Build_Log](options: Options) |
878 { |
883 { |
879 val xml_cache: XML.Cache = new XML.Cache() |
884 val xml_cache: XML.Cache = new XML.Cache() |
|
885 val xz_cache: XZ.Cache = XZ.make_cache() |
880 |
886 |
881 def open_database( |
887 def open_database( |
882 user: String = options.string("build_log_database_user"), |
888 user: String = options.string("build_log_database_user"), |
883 password: String = options.string("build_log_database_password"), |
889 password: String = options.string("build_log_database_password"), |
884 database: String = options.string("build_log_database_name"), |
890 database: String = options.string("build_log_database_name"), |
1009 stmt.long(11) = session.ml_timing.cpu.proper_ms |
1015 stmt.long(11) = session.ml_timing.cpu.proper_ms |
1010 stmt.long(12) = session.ml_timing.gc.proper_ms |
1016 stmt.long(12) = session.ml_timing.gc.proper_ms |
1011 stmt.double(13) = session.ml_timing.factor |
1017 stmt.double(13) = session.ml_timing.factor |
1012 stmt.long(14) = session.heap_size |
1018 stmt.long(14) = session.heap_size |
1013 stmt.string(15) = session.status.map(_.toString) |
1019 stmt.string(15) = session.status.map(_.toString) |
1014 stmt.bytes(16) = compress_errors(session.errors) |
1020 stmt.bytes(16) = compress_errors(session.errors, cache = xz_cache) |
1015 stmt.string(17) = session.sources |
1021 stmt.string(17) = session.sources |
1016 stmt.execute() |
1022 stmt.execute() |
1017 } |
1023 } |
1018 }) |
1024 }) |
1019 } |
1025 } |
1047 val table = Data.ml_statistics_table |
1053 val table = Data.ml_statistics_table |
1048 db.using_statement(db.insert_permissive(table))(stmt => |
1054 db.using_statement(db.insert_permissive(table))(stmt => |
1049 { |
1055 { |
1050 val ml_stats: List[(String, Option[Bytes])] = |
1056 val ml_stats: List[(String, Option[Bytes])] = |
1051 Par_List.map[(String, Session_Entry), (String, Option[Bytes])]( |
1057 Par_List.map[(String, Session_Entry), (String, Option[Bytes])]( |
1052 { case (a, b) => (a, Properties.compress(b.ml_statistics).proper) }, |
1058 { case (a, b) => (a, Properties.compress(b.ml_statistics, cache = xz_cache).proper) }, |
1053 build_info.sessions.iterator.filter(p => p._2.ml_statistics.nonEmpty).toList) |
1059 build_info.sessions.iterator.filter(p => p._2.ml_statistics.nonEmpty).toList) |
1054 val entries = if (ml_stats.nonEmpty) ml_stats else List("" -> None) |
1060 val entries = if (ml_stats.nonEmpty) ml_stats else List("" -> None) |
1055 for ((session_name, ml_statistics) <- entries) { |
1061 for ((session_name, ml_statistics) <- entries) { |
1056 stmt.string(1) = log_name |
1062 stmt.string(1) = log_name |
1057 stmt.string(2) = session_name |
1063 stmt.string(2) = session_name |
1176 ml_timing = |
1182 ml_timing = |
1177 res.timing(Data.ml_timing_elapsed, Data.ml_timing_cpu, Data.ml_timing_gc), |
1183 res.timing(Data.ml_timing_elapsed, Data.ml_timing_cpu, Data.ml_timing_gc), |
1178 sources = res.get_string(Data.sources), |
1184 sources = res.get_string(Data.sources), |
1179 heap_size = res.get_long(Data.heap_size), |
1185 heap_size = res.get_long(Data.heap_size), |
1180 status = res.get_string(Data.status).map(Session_Status.withName(_)), |
1186 status = res.get_string(Data.status).map(Session_Status.withName(_)), |
1181 errors = uncompress_errors(res.bytes(Data.errors)), |
1187 errors = uncompress_errors(res.bytes(Data.errors), cache = xz_cache), |
1182 ml_statistics = |
1188 ml_statistics = |
1183 if (ml_statistics) |
1189 if (ml_statistics) { |
1184 Properties.uncompress(res.bytes(Data.ml_statistics), Some(xml_cache)) |
1190 Properties.uncompress( |
|
1191 res.bytes(Data.ml_statistics), cache = xz_cache, Some(xml_cache)) |
|
1192 } |
1185 else Nil) |
1193 else Nil) |
1186 session_name -> session_entry |
1194 session_name -> session_entry |
1187 }).toMap |
1195 }).toMap |
1188 }) |
1196 }) |
1189 Build_Info(sessions) |
1197 Build_Info(sessions) |