@@ -5,6 +5,7 @@ use crate::prelude::*;
55use crate :: results:: {
66 DeleteResults , EncodedLog , EncodingType , ReadResults , TestResult , WriteResults ,
77} ;
8+ use crate :: timings:: TimingInfo ;
89use crate :: toolchain:: Toolchain ;
910use base64:: Engine ;
1011use rustwide:: logging:: { self , LogStorage } ;
@@ -143,6 +144,69 @@ impl<'a> DatabaseDB<'a> {
143144 Ok ( ( ) )
144145 }
145146
147+ pub fn store_timings (
148+ & self ,
149+ ex : & Experiment ,
150+ krate : & Crate ,
151+ toolchain : & Toolchain ,
152+ timings : & [ TimingInfo ] ,
153+ ) -> Fallible < ( ) > {
154+ for timing in timings {
155+ let target_kind = timing. target . kind . join ( "," ) ;
156+ self . db . execute_cached (
157+ "INSERT INTO build_timings \
158+ (experiment, crate, toolchain, package_id, target_name, target_kind, mode, duration, rmeta_time) \
159+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9);",
160+ & [
161+ & ex. name as & dyn rusqlite:: types:: ToSql ,
162+ & krate. id ( ) ,
163+ & toolchain. to_string ( ) ,
164+ & timing. package_id ,
165+ & timing. target . name ,
166+ & target_kind,
167+ & timing. mode ,
168+ & timing. duration ,
169+ & timing. rmeta_time ,
170+ ] ,
171+ ) ?;
172+ }
173+ Ok ( ( ) )
174+ }
175+
176+ pub fn load_timings (
177+ & self ,
178+ ex : & Experiment ,
179+ krate : & Crate ,
180+ toolchain : & Toolchain ,
181+ ) -> Fallible < Vec < TimingInfo > > {
182+ self . db . query (
183+ "SELECT package_id, target_name, target_kind, mode, duration, rmeta_time \
184+ FROM build_timings \
185+ WHERE experiment = ?1 AND crate = ?2 AND toolchain = ?3;",
186+ [ & ex. name , & krate. id ( ) , & toolchain. to_string ( ) ] ,
187+ |row| {
188+ let target_kind: String = row. get ( "target_kind" ) ?;
189+ let kinds: Vec < String > = target_kind. split ( ',' ) . map ( |s| s. to_string ( ) ) . collect ( ) ;
190+ Ok ( TimingInfo {
191+ package_id : row. get ( "package_id" ) ?,
192+ target : crate :: timings:: TimingTarget {
193+ kind : kinds,
194+ crate_types : Vec :: new ( ) ,
195+ name : row. get ( "target_name" ) ?,
196+ src_path : String :: new ( ) ,
197+ edition : String :: new ( ) ,
198+ doc : false ,
199+ doctest : false ,
200+ test : false ,
201+ } ,
202+ mode : row. get ( "mode" ) ?,
203+ duration : row. get ( "duration" ) ?,
204+ rmeta_time : row. get ( "rmeta_time" ) ?,
205+ } )
206+ } ,
207+ )
208+ }
209+
146210 fn insert_into_results (
147211 & self ,
148212 ex : & Experiment ,
@@ -272,6 +336,16 @@ impl crate::runner::RecordProgress for DatabaseDB<'_> {
272336 }
273337 Ok ( ( ) )
274338 }
339+
340+ fn record_timings (
341+ & self ,
342+ ex : & Experiment ,
343+ krate : & Crate ,
344+ toolchain : & Toolchain ,
345+ timings : & [ TimingInfo ] ,
346+ ) -> Fallible < ( ) > {
347+ self . store_timings ( ex, krate, toolchain, timings)
348+ }
275349}
276350
277351impl DeleteResults for DatabaseDB < ' _ > {
@@ -468,6 +542,85 @@ mod tests {
468542 . is_none( ) ) ;
469543 }
470544
545+ #[ test]
546+ fn test_store_and_load_timings ( ) {
547+ let db = Database :: temp ( ) . unwrap ( ) ;
548+ let results = DatabaseDB :: new ( & db) ;
549+ let config = Config :: default ( ) ;
550+ let ctx = ActionsCtx :: new ( & db, & config) ;
551+
552+ crate :: crates:: lists:: setup_test_lists ( & db, & config) . unwrap ( ) ;
553+
554+ CreateExperiment :: dummy ( "dummy" ) . apply ( & ctx) . unwrap ( ) ;
555+ let ex = Experiment :: get ( & db, "dummy" ) . unwrap ( ) . unwrap ( ) ;
556+
557+ let krate = Crate :: Registry ( RegistryCrate {
558+ name : "lazy_static" . into ( ) ,
559+ version : "1" . into ( ) ,
560+ } ) ;
561+
562+ let timings = vec ! [
563+ crate :: timings:: TimingInfo {
564+ package_id: "serde 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"
565+ . to_string( ) ,
566+ target: crate :: timings:: TimingTarget {
567+ kind: vec![ "lib" . to_string( ) ] ,
568+ crate_types: vec![ "lib" . to_string( ) ] ,
569+ name: "serde" . to_string( ) ,
570+ src_path: "/path/to/src/lib.rs" . to_string( ) ,
571+ edition: "2021" . to_string( ) ,
572+ doc: true ,
573+ doctest: true ,
574+ test: true ,
575+ } ,
576+ mode: "build" . to_string( ) ,
577+ duration: 12.5 ,
578+ rmeta_time: Some ( 8.3 ) ,
579+ } ,
580+ crate :: timings:: TimingInfo {
581+ package_id: "foo 0.1.0" . to_string( ) ,
582+ target: crate :: timings:: TimingTarget {
583+ kind: vec![ "bin" . to_string( ) ] ,
584+ crate_types: vec![ "bin" . to_string( ) ] ,
585+ name: "foo" . to_string( ) ,
586+ src_path: "/path/to/main.rs" . to_string( ) ,
587+ edition: "2021" . to_string( ) ,
588+ doc: false ,
589+ doctest: false ,
590+ test: false ,
591+ } ,
592+ mode: "build" . to_string( ) ,
593+ duration: 1.0 ,
594+ rmeta_time: None ,
595+ } ,
596+ ] ;
597+
598+ results
599+ . store_timings ( & ex, & krate, & MAIN_TOOLCHAIN , & timings)
600+ . unwrap ( ) ;
601+
602+ let loaded = results. load_timings ( & ex, & krate, & MAIN_TOOLCHAIN ) . unwrap ( ) ;
603+
604+ assert_eq ! ( loaded. len( ) , 2 ) ;
605+
606+ assert_eq ! ( loaded[ 0 ] . package_id, timings[ 0 ] . package_id) ;
607+ assert_eq ! ( loaded[ 0 ] . target. name, "serde" ) ;
608+ assert_eq ! ( loaded[ 0 ] . target. kind, vec![ "lib" ] ) ;
609+ assert_eq ! ( loaded[ 0 ] . mode, "build" ) ;
610+ assert ! ( ( loaded[ 0 ] . duration - 12.5 ) . abs( ) < f64 :: EPSILON ) ;
611+ assert ! ( ( loaded[ 0 ] . rmeta_time. unwrap( ) - 8.3 ) . abs( ) < f64 :: EPSILON ) ;
612+
613+ assert_eq ! ( loaded[ 1 ] . package_id, "foo 0.1.0" ) ;
614+ assert_eq ! ( loaded[ 1 ] . target. name, "foo" ) ;
615+ assert_eq ! ( loaded[ 1 ] . target. kind, vec![ "bin" ] ) ;
616+ assert ! ( ( loaded[ 1 ] . duration - 1.0 ) . abs( ) < f64 :: EPSILON ) ;
617+ assert ! ( loaded[ 1 ] . rmeta_time. is_none( ) ) ;
618+
619+ // Different toolchain should return empty
620+ let empty = results. load_timings ( & ex, & krate, & TEST_TOOLCHAIN ) . unwrap ( ) ;
621+ assert ! ( empty. is_empty( ) ) ;
622+ }
623+
471624 #[ test]
472625 fn test_store ( ) {
473626 let db = Database :: temp ( ) . unwrap ( ) ;
0 commit comments