@@ -7,7 +7,7 @@ use crate::api::{graph, ServerResult};
77use crate :: db:: { self , ArtifactId , Benchmark , Profile , Scenario } ;
88use crate :: interpolate:: Interpolated ;
99use crate :: load:: SiteCtxt ;
10- use crate :: selector:: { Path , PathComponent , Query , Selector , SeriesResponse , Tag } ;
10+ use crate :: selector:: { Query , Selector , SeriesResponse , Tag } ;
1111
1212pub async fn handle_graph (
1313 body : graph:: Request ,
@@ -30,51 +30,7 @@ pub async fn handle_graph(
3030 }
3131 }
3232
33- let range = ctxt. data_range ( body. start . clone ( ) ..=body. end . clone ( ) ) ;
34- let commits: Vec < ArtifactId > = range. iter ( ) . map ( |c| c. clone ( ) . into ( ) ) . collect ( ) ;
35-
36- let mut benchmarks = HashMap :: new ( ) ;
37-
38- let benchmarks_impl = handle_graph_impl ( body, ctxt) . await ?;
39-
40- for ( benchmark_, benchmark_data) in benchmarks_impl. iter ( ) {
41- let mut by_profile = HashMap :: with_capacity ( 3 ) ;
42-
43- for ( profile, series) in benchmark_data. iter ( ) {
44- let mut by_run = HashMap :: with_capacity ( 3 ) ;
45-
46- for ( name, points) in series. iter ( ) {
47- let mut series = graph:: Series {
48- points : Vec :: new ( ) ,
49- is_interpolated : Default :: default ( ) ,
50- } ;
51-
52- for ( idx, point) in points. iter ( ) . enumerate ( ) {
53- series. points . push ( point. value ) ;
54- if point. is_interpolated {
55- series. is_interpolated . insert ( idx as u16 ) ;
56- }
57- }
58-
59- by_run. insert ( name. clone ( ) , series) ;
60- }
61-
62- by_profile. insert ( profile. parse :: < Profile > ( ) . unwrap ( ) , by_run) ;
63- }
64-
65- benchmarks. insert ( benchmark_. clone ( ) , by_profile) ;
66- }
67-
68- let resp = Arc :: new ( graph:: Response {
69- commits : commits
70- . into_iter ( )
71- . map ( |c| match c {
72- ArtifactId :: Commit ( c) => ( c. date . 0 . timestamp ( ) , c. sha ) ,
73- ArtifactId :: Tag ( _) => unreachable ! ( ) ,
74- } )
75- . collect ( ) ,
76- benchmarks,
77- } ) ;
33+ let resp = graph_response ( body, ctxt) . await ?;
7834
7935 if is_default_query {
8036 ctxt. landing_page . store ( Arc :: new ( Some ( resp. clone ( ) ) ) ) ;
@@ -83,22 +39,16 @@ pub async fn handle_graph(
8339 Ok ( resp)
8440}
8541
86- struct GraphPoint {
87- value : f32 ,
88- is_interpolated : bool ,
89- }
90-
91- async fn handle_graph_impl (
42+ async fn graph_response (
9243 body : graph:: Request ,
9344 ctxt : & SiteCtxt ,
94- ) -> ServerResult < HashMap < String , HashMap < String , Vec < ( String , Vec < GraphPoint > ) > > > > {
45+ ) -> ServerResult < Arc < graph :: Response > > {
9546 let range = ctxt. data_range ( body. start . clone ( ) ..=body. end . clone ( ) ) ;
96- let commits: Arc < Vec < _ > > = Arc :: new ( range. iter ( ) . map ( |c| c. clone ( ) . into ( ) ) . collect ( ) ) ;
97-
98- let metric: database:: Metric = body. stat . parse ( ) . unwrap ( ) ;
47+ let commits: Arc < Vec < _ > > = Arc :: new ( range. into_iter ( ) . map ( |c| c. clone ( ) . into ( ) ) . collect ( ) ) ;
9948 let metric_selector = Selector :: One ( body. stat . clone ( ) ) ;
49+ let mut benchmarks = HashMap :: new ( ) ;
10050
101- let series = ctxt
51+ let series_iterator = ctxt
10252 . statistic_series (
10353 Query :: new ( )
10454 . set :: < String > ( Tag :: Benchmark , Selector :: All )
@@ -107,17 +57,26 @@ async fn handle_graph_impl(
10757 . set :: < String > ( Tag :: Metric , metric_selector. clone ( ) ) ,
10858 commits. clone ( ) ,
10959 )
110- . await ?;
111-
112- let mut series = series
60+ . await ?
11361 . into_iter ( )
114- . map ( |sr| {
115- sr. interpolate ( )
116- . map ( |series| to_graph_points ( body. kind , series) . collect :: < Vec < _ > > ( ) )
117- } )
118- . collect :: < Vec < _ > > ( ) ;
62+ . map ( SeriesResponse :: interpolate) ;
63+
64+ for series_response in series_iterator {
65+ let benchmark = series_response. path . get :: < Benchmark > ( ) ?. to_string ( ) ;
66+ let profile = * series_response. path . get :: < Profile > ( ) ?;
67+ let scenario = series_response. path . get :: < Scenario > ( ) ?. to_string ( ) ;
68+ let graph_series = graph_series ( body. kind , series_response. series ) ;
69+
70+ benchmarks
71+ . entry ( benchmark)
72+ . or_insert_with ( HashMap :: new)
73+ . entry ( profile)
74+ . or_insert_with ( HashMap :: new)
75+ . insert ( scenario, graph_series) ;
76+ }
11977
12078 let mut baselines = HashMap :: new ( ) ;
79+ let mut summary_benchmark = HashMap :: new ( ) ;
12180
12281 let summary_query_cases = iproduct ! (
12382 ctxt. summary_scenarios( ) ,
@@ -162,53 +121,62 @@ async fn handle_graph_impl(
162121 )
163122 . map ( |( ( c, d) , i) | ( ( c, Some ( d. expect ( "interpolated" ) / baseline) ) , i) ) ;
164123
165- let graph_data = to_graph_points ( body. kind , avg_vs_baseline) . collect :: < Vec < _ > > ( ) ;
124+ let graph_series = graph_series ( body. kind , avg_vs_baseline) ;
166125
167- series. push ( SeriesResponse {
168- path : Path :: new ( )
169- . set ( PathComponent :: Benchmark ( "Summary" . into ( ) ) )
170- . set ( PathComponent :: Profile ( profile) )
171- . set ( PathComponent :: Scenario ( scenario) )
172- . set ( PathComponent :: Metric ( metric) ) ,
173- series : graph_data,
174- } )
175- }
176-
177- let mut by_test_case = HashMap :: new ( ) ;
178- for sr in series {
179- let benchmark = sr. path . get :: < Benchmark > ( ) ?. to_string ( ) ;
180- by_test_case
181- . entry ( benchmark)
126+ summary_benchmark
127+ . entry ( profile)
182128 . or_insert_with ( HashMap :: new)
183- . entry ( sr. path . get :: < Profile > ( ) ?. to_string ( ) )
184- . or_insert_with ( Vec :: new)
185- . push ( ( sr. path . get :: < Scenario > ( ) ?. to_string ( ) , sr. series ) ) ;
129+ . insert ( scenario. to_string ( ) , graph_series) ;
186130 }
187131
188- Ok ( by_test_case)
132+ benchmarks. insert ( "Summary" . to_string ( ) , summary_benchmark) ;
133+
134+ Ok ( Arc :: new ( graph:: Response {
135+ commits : Arc :: try_unwrap ( commits)
136+ . unwrap ( )
137+ . into_iter ( )
138+ . map ( |c| match c {
139+ ArtifactId :: Commit ( c) => ( c. date . 0 . timestamp ( ) , c. sha ) ,
140+ ArtifactId :: Tag ( _) => unreachable ! ( ) ,
141+ } )
142+ . collect ( ) ,
143+ benchmarks,
144+ } ) )
189145}
190146
191- fn to_graph_points < ' a > (
147+ fn graph_series (
192148 kind : GraphKind ,
193- points : impl Iterator < Item = ( ( ArtifactId , Option < f64 > ) , Interpolated ) > + ' a ,
194- ) -> impl Iterator < Item = GraphPoint > + ' a {
149+ points : impl Iterator < Item = ( ( ArtifactId , Option < f64 > ) , Interpolated ) > ,
150+ ) -> graph:: Series {
151+ let mut graph_series = graph:: Series {
152+ points : Vec :: new ( ) ,
153+ is_interpolated : Default :: default ( ) ,
154+ } ;
155+
195156 let mut first = None ;
196157 let mut prev = None ;
197- points. map ( move |( ( _aid, point) , interpolated) | {
158+
159+ for ( idx, ( ( _aid, point) , interpolated) ) in points. enumerate ( ) {
198160 let point = point. expect ( "interpolated" ) ;
199161 first = Some ( first. unwrap_or ( point) ) ;
200162 let first = first. unwrap ( ) ;
201163 let percent_first = ( point - first) / first * 100.0 ;
202164 let previous_point = prev. unwrap_or ( point) ;
203165 let percent_prev = ( point - previous_point) / previous_point * 100.0 ;
204166 prev = Some ( point) ;
205- GraphPoint {
206- value : match kind {
207- GraphKind :: Raw => point as f32 ,
208- GraphKind :: PercentRelative => percent_prev as f32 ,
209- GraphKind :: PercentFromFirst => percent_first as f32 ,
210- } ,
211- is_interpolated : interpolated. is_interpolated ( ) ,
167+
168+ let value = match kind {
169+ GraphKind :: Raw => point as f32 ,
170+ GraphKind :: PercentRelative => percent_prev as f32 ,
171+ GraphKind :: PercentFromFirst => percent_first as f32 ,
172+ } ;
173+
174+ graph_series. points . push ( value) ;
175+
176+ if interpolated. is_interpolated ( ) {
177+ graph_series. is_interpolated . insert ( idx as u16 ) ;
212178 }
213- } )
179+ }
180+
181+ graph_series
214182}
0 commit comments