@@ -7,7 +7,7 @@ use crate::api::{graph, ServerResult};
7
7
use crate :: db:: { self , ArtifactId , Benchmark , Profile , Scenario } ;
8
8
use crate :: interpolate:: Interpolated ;
9
9
use crate :: load:: SiteCtxt ;
10
- use crate :: selector:: { Path , PathComponent , Query , Selector , SeriesResponse , Tag } ;
10
+ use crate :: selector:: { Query , Selector , SeriesResponse , Tag } ;
11
11
12
12
pub async fn handle_graph (
13
13
body : graph:: Request ,
@@ -30,51 +30,7 @@ pub async fn handle_graph(
30
30
}
31
31
}
32
32
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 ?;
78
34
79
35
if is_default_query {
80
36
ctxt. landing_page . store ( Arc :: new ( Some ( resp. clone ( ) ) ) ) ;
@@ -83,22 +39,16 @@ pub async fn handle_graph(
83
39
Ok ( resp)
84
40
}
85
41
86
- struct GraphPoint {
87
- value : f32 ,
88
- is_interpolated : bool ,
89
- }
90
-
91
- async fn handle_graph_impl (
42
+ async fn graph_response (
92
43
body : graph:: Request ,
93
44
ctxt : & SiteCtxt ,
94
- ) -> ServerResult < HashMap < String , HashMap < String , Vec < ( String , Vec < GraphPoint > ) > > > > {
45
+ ) -> ServerResult < Arc < graph :: Response > > {
95
46
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 ( ) ) ;
99
48
let metric_selector = Selector :: One ( body. stat . clone ( ) ) ;
49
+ let mut benchmarks = HashMap :: new ( ) ;
100
50
101
- let series = ctxt
51
+ let series_iterator = ctxt
102
52
. statistic_series (
103
53
Query :: new ( )
104
54
. set :: < String > ( Tag :: Benchmark , Selector :: All )
@@ -107,17 +57,26 @@ async fn handle_graph_impl(
107
57
. set :: < String > ( Tag :: Metric , metric_selector. clone ( ) ) ,
108
58
commits. clone ( ) ,
109
59
)
110
- . await ?;
111
-
112
- let mut series = series
60
+ . await ?
113
61
. 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
+ }
119
77
120
78
let mut baselines = HashMap :: new ( ) ;
79
+ let mut summary_benchmark = HashMap :: new ( ) ;
121
80
122
81
let summary_query_cases = iproduct ! (
123
82
ctxt. summary_scenarios( ) ,
@@ -162,53 +121,62 @@ async fn handle_graph_impl(
162
121
)
163
122
. map ( |( ( c, d) , i) | ( ( c, Some ( d. expect ( "interpolated" ) / baseline) ) , i) ) ;
164
123
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) ;
166
125
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)
182
128
. 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) ;
186
130
}
187
131
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
+ } ) )
189
145
}
190
146
191
- fn to_graph_points < ' a > (
147
+ fn graph_series (
192
148
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
+
195
156
let mut first = None ;
196
157
let mut prev = None ;
197
- points. map ( move |( ( _aid, point) , interpolated) | {
158
+
159
+ for ( idx, ( ( _aid, point) , interpolated) ) in points. enumerate ( ) {
198
160
let point = point. expect ( "interpolated" ) ;
199
161
first = Some ( first. unwrap_or ( point) ) ;
200
162
let first = first. unwrap ( ) ;
201
163
let percent_first = ( point - first) / first * 100.0 ;
202
164
let previous_point = prev. unwrap_or ( point) ;
203
165
let percent_prev = ( point - previous_point) / previous_point * 100.0 ;
204
166
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 ) ;
212
178
}
213
- } )
179
+ }
180
+
181
+ graph_series
214
182
}
0 commit comments