Skip to content

Commit 0e2de9c

Browse files
committed
Implement runtime benchmark data DB querying
1 parent 2d2a206 commit 0e2de9c

File tree

1 file changed

+93
-60
lines changed

1 file changed

+93
-60
lines changed

site/src/selector.rs

Lines changed: 93 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@ use crate::interpolate::Interpolate;
2626
use crate::load::SiteCtxt;
2727

2828
use collector::Bound;
29-
use database::{Benchmark, Commit, Index, Lookup};
29+
use database::{Benchmark, Commit, Connection, Index, Lookup};
3030

3131
use crate::comparison::Metric;
32+
use async_trait::async_trait;
3233
use std::fmt::Debug;
3334
use std::hash::Hash;
3435
use std::ops::RangeInclusive;
3536
use std::sync::Arc;
37+
use std::time::Instant;
3638

3739
/// Finds the most appropriate `ArtifactId` for a given bound.
3840
///
@@ -178,15 +180,16 @@ impl<TestCase, T> SeriesResponse<TestCase, T> {
178180
}
179181
}
180182

183+
#[async_trait]
181184
pub trait BenchmarkQuery: Debug {
182185
type TestCase: TestCase;
183186

184-
/// Returns all known statistic descriptions (test cases + metrics) and their corresponding
185-
/// row IDs.
186-
fn get_statistic_descriptions(
187+
async fn execute(
187188
&self,
189+
connection: &mut dyn Connection,
188190
index: &Index,
189-
) -> Vec<(Self::TestCase, database::Metric, u32)>;
191+
artifact_ids: Arc<Vec<ArtifactId>>,
192+
) -> Result<Vec<SeriesResponse<Self::TestCase, StatisticSeries>>, String>;
190193
}
191194

192195
// Compile benchmarks querying
@@ -240,14 +243,17 @@ impl Default for CompileBenchmarkQuery {
240243
}
241244
}
242245

246+
#[async_trait]
243247
impl BenchmarkQuery for CompileBenchmarkQuery {
244248
type TestCase = CompileTestCase;
245249

246-
fn get_statistic_descriptions(
250+
async fn execute(
247251
&self,
252+
conn: &mut dyn Connection,
248253
index: &Index,
249-
) -> Vec<(Self::TestCase, database::Metric, u32)> {
250-
index
254+
artifact_ids: Arc<Vec<ArtifactId>>,
255+
) -> Result<Vec<SeriesResponse<Self::TestCase, StatisticSeries>>, String> {
256+
let mut statistic_descriptions: Vec<_> = index
251257
.compile_statistic_descriptions()
252258
.filter(|(&(b, p, s, m), _)| {
253259
self.benchmark.matches(b)
@@ -266,7 +272,46 @@ impl BenchmarkQuery for CompileBenchmarkQuery {
266272
sid,
267273
)
268274
})
269-
.collect()
275+
.collect();
276+
277+
statistic_descriptions.sort_unstable();
278+
279+
let sids: Vec<_> = statistic_descriptions
280+
.iter()
281+
.map(|(_, _, sid)| *sid)
282+
.collect();
283+
284+
let aids = artifact_ids
285+
.iter()
286+
.map(|aid| aid.lookup(&index))
287+
.collect::<Vec<_>>();
288+
289+
Ok(conn
290+
.get_pstats(&sids, &aids)
291+
.await
292+
.into_iter()
293+
.zip(statistic_descriptions)
294+
.filter(|(points, _)| points.iter().any(|value| value.is_some()))
295+
.map(|(points, (test_case, metric, _))| {
296+
SeriesResponse {
297+
series: StatisticSeries {
298+
artifact_ids: ArtifactIdIter::new(artifact_ids.clone()),
299+
points: if *metric == *"cpu-clock" || *metric == *"task-clock" {
300+
// Convert to seconds -- perf reports these measurements in
301+
// milliseconds
302+
points
303+
.into_iter()
304+
.map(|p| p.map(|v| v / 1000.0))
305+
.collect::<Vec<_>>()
306+
.into_iter()
307+
} else {
308+
points.into_iter()
309+
},
310+
},
311+
test_case,
312+
}
313+
})
314+
.collect::<Vec<_>>())
270315
}
271316
}
272317

@@ -314,18 +359,45 @@ impl Default for RuntimeBenchmarkQuery {
314359
}
315360
}
316361

362+
#[async_trait]
317363
impl BenchmarkQuery for RuntimeBenchmarkQuery {
318364
type TestCase = RuntimeTestCase;
319365

320-
fn get_statistic_descriptions(
366+
async fn execute(
321367
&self,
368+
conn: &mut dyn Connection,
322369
index: &Index,
323-
) -> Vec<(Self::TestCase, database::Metric, u32)> {
324-
index
370+
artifact_ids: Arc<Vec<ArtifactId>>,
371+
) -> Result<Vec<SeriesResponse<Self::TestCase, StatisticSeries>>, String> {
372+
let mut statistic_descriptions: Vec<_> = index
325373
.runtime_statistic_descriptions()
326374
.filter(|(&(b, m), _)| self.benchmark.matches(b) && self.metric.matches(m))
327-
.map(|(&(benchmark, metric), sid)| (RuntimeTestCase { benchmark }, metric, sid))
328-
.collect()
375+
.map(|(&(benchmark, _), sid)| (RuntimeTestCase { benchmark }, sid))
376+
.collect();
377+
378+
statistic_descriptions.sort_unstable();
379+
380+
let sids: Vec<_> = statistic_descriptions.iter().map(|(_, sid)| *sid).collect();
381+
382+
let aids = artifact_ids
383+
.iter()
384+
.map(|aid| aid.lookup(&index))
385+
.collect::<Vec<_>>();
386+
387+
Ok(conn
388+
.get_runtime_pstats(&sids, &aids)
389+
.await
390+
.into_iter()
391+
.zip(statistic_descriptions)
392+
.filter(|(points, _)| points.iter().any(|value| value.is_some()))
393+
.map(|(points, (test_case, _))| SeriesResponse {
394+
series: StatisticSeries {
395+
artifact_ids: ArtifactIdIter::new(artifact_ids.clone()),
396+
points: points.into_iter(),
397+
},
398+
test_case,
399+
})
400+
.collect::<Vec<_>>())
329401
}
330402
}
331403

@@ -342,7 +414,7 @@ impl SiteCtxt {
342414
query: Q,
343415
artifact_ids: Arc<Vec<ArtifactId>>,
344416
) -> Result<Vec<SeriesResponse<Q::TestCase, StatisticSeries>>, String> {
345-
StatisticSeries::execute_compile_query(artifact_ids, self, query).await
417+
StatisticSeries::execute_query(artifact_ids, self, query).await
346418
}
347419
}
348420

@@ -352,64 +424,25 @@ pub struct StatisticSeries {
352424
}
353425

354426
impl StatisticSeries {
355-
async fn execute_compile_query<Q: BenchmarkQuery>(
427+
async fn execute_query<Q: BenchmarkQuery>(
356428
artifact_ids: Arc<Vec<ArtifactId>>,
357429
ctxt: &SiteCtxt,
358430
query: Q,
359431
) -> Result<Vec<SeriesResponse<Q::TestCase, Self>>, String> {
360432
let dumped = format!("{:?}", query);
361433

362434
let index = ctxt.index.load();
363-
let mut statistic_descriptions = query.get_statistic_descriptions(&index);
435+
let mut conn = ctxt.conn().await;
364436

365-
statistic_descriptions.sort_unstable();
366-
let descriptions_count = statistic_descriptions.len();
367-
368-
let sids: Vec<_> = statistic_descriptions
369-
.iter()
370-
.map(|(_, _, sid)| *sid)
371-
.collect();
372-
let aids = artifact_ids
373-
.iter()
374-
.map(|aid| aid.lookup(&index))
375-
.collect::<Vec<_>>();
376-
377-
let conn = ctxt.conn().await;
378-
379-
let start = std::time::Instant::now();
380-
let res = conn
381-
.get_pstats(&sids, &aids)
382-
.await
383-
.into_iter()
384-
.zip(statistic_descriptions)
385-
.filter(|(points, _)| points.iter().any(|value| value.is_some()))
386-
.map(|(points, (test_case, metric, _))| {
387-
SeriesResponse {
388-
series: StatisticSeries {
389-
artifact_ids: ArtifactIdIter::new(artifact_ids.clone()),
390-
points: if *metric == *"cpu-clock" || *metric == *"task-clock" {
391-
// Convert to seconds -- perf reports these measurements in
392-
// milliseconds
393-
points
394-
.into_iter()
395-
.map(|p| p.map(|v| v / 1000.0))
396-
.collect::<Vec<_>>()
397-
.into_iter()
398-
} else {
399-
points.into_iter()
400-
},
401-
},
402-
test_case,
403-
}
404-
})
405-
.collect::<Vec<_>>();
437+
let start = Instant::now();
438+
let result = query.execute(conn.as_mut(), &index, artifact_ids).await?;
406439
log::trace!(
407440
"{:?}: run {} from {}",
408441
start.elapsed(),
409-
descriptions_count,
442+
result.len(),
410443
dumped
411444
);
412-
Ok(res)
445+
Ok(result)
413446
}
414447
}
415448

0 commit comments

Comments
 (0)