Skip to content

Commit 14e9091

Browse files
Merge pull request #1610 from Kobzol/runtime-site-backend
Generalize site `pstat` querying for runtime benchmarks
2 parents e2fc392 + d447376 commit 14e9091

File tree

12 files changed

+883
-541
lines changed

12 files changed

+883
-541
lines changed

collector/src/runtime/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ pub async fn bench_runtime(
2626
filter: BenchmarkFilter,
2727
iterations: u32,
2828
) -> anyhow::Result<()> {
29-
for benchmark in suite.benchmark_names() {
30-
conn.record_runtime_benchmark(benchmark).await;
31-
}
32-
3329
let total_benchmark_count = suite.total_benchmark_count();
3430
let filtered = suite.filtered_benchmark_count(&filter);
3531
println!(

database/src/bin/import-sqlite.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use database::{CompileBenchmark, Lookup, Pool};
1+
use database::{CompileBenchmark, Pool};
22
use hashbrown::HashMap;
33
use std::collections::HashSet;
44

@@ -45,7 +45,9 @@ async fn main() {
4545
let sqlite_aid = sqlite_conn.artifact_id(&aid).await;
4646
let postgres_aid = postgres_conn.artifact_id(&aid).await;
4747

48-
for &(benchmark, profile, scenario, metric) in sqlite_idx.all_statistic_descriptions() {
48+
for (&(benchmark, profile, scenario, metric), id) in
49+
sqlite_idx.compile_statistic_descriptions()
50+
{
4951
if benchmarks.insert(benchmark) {
5052
postgres_conn
5153
.record_compile_benchmark(
@@ -56,15 +58,6 @@ async fn main() {
5658
.await;
5759
}
5860

59-
let id = database::DbLabel::StatisticDescription {
60-
benchmark,
61-
profile,
62-
scenario,
63-
metric,
64-
}
65-
.lookup(&sqlite_idx)
66-
.unwrap();
67-
6861
let stat = sqlite_conn
6962
.get_pstats(&[id], &[Some(sqlite_aid)])
7063
.await
@@ -86,5 +79,20 @@ async fn main() {
8679
.await;
8780
}
8881
}
82+
83+
for (&(benchmark, metric), id) in sqlite_idx.runtime_statistic_descriptions() {
84+
let stat = sqlite_conn
85+
.get_runtime_pstats(&[id], &[Some(sqlite_aid)])
86+
.await
87+
.pop()
88+
.unwrap()
89+
.pop()
90+
.unwrap();
91+
if let Some(stat) = stat {
92+
postgres_conn
93+
.record_runtime_statistic(cid, postgres_aid, &benchmark, metric.as_str(), stat)
94+
.await;
95+
}
96+
}
8997
}
9098
}

database/src/lib.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -406,11 +406,11 @@ pub struct Index {
406406
commits: Indexed<Commit>,
407407
/// Id lookup of published release artifacts
408408
artifacts: Indexed<Box<str>>,
409-
/// Id lookup of the errors for a crate
410-
errors: Indexed<Benchmark>,
411-
/// Id lookup of stat description ids
409+
/// Id lookup of compile stat description ids
412410
/// For legacy reasons called `pstat_series` in the database, and so the name is kept here.
413411
pstat_series: Indexed<(Benchmark, Profile, Scenario, Metric)>,
412+
/// Id lookup of runtime stat description ids
413+
runtime_pstat_series: Indexed<(Benchmark, Metric)>,
414414
}
415415

416416
/// An index lookup
@@ -524,9 +524,6 @@ mod index_serde {
524524

525525
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
526526
pub enum DbLabel {
527-
Errors {
528-
benchmark: Benchmark,
529-
},
530527
StatisticDescription {
531528
benchmark: Benchmark,
532529
profile: Profile,
@@ -544,7 +541,6 @@ impl Lookup for DbLabel {
544541
type Id = u32;
545542
fn lookup(&self, index: &Index) -> Option<Self::Id> {
546543
match self {
547-
DbLabel::Errors { benchmark } => index.errors.get(benchmark),
548544
DbLabel::StatisticDescription {
549545
benchmark,
550546
profile,
@@ -567,6 +563,8 @@ impl Lookup for ArtifactId {
567563
}
568564
}
569565

566+
pub type StatisticalDescriptionId = u32;
567+
570568
impl Index {
571569
pub async fn load(conn: &mut dyn pool::Connection) -> Index {
572570
conn.load_index().await
@@ -607,18 +605,31 @@ impl Index {
607605
.collect()
608606
}
609607

610-
pub fn all_errors(&self) -> impl Iterator<Item = Benchmark> + '_ {
611-
self.errors.map.keys().copied()
612-
}
613-
614608
// FIXME: in theory this won't scale indefinitely as there's potentially
615609
// millions of queries and labels and iterating all of them is eventually
616610
// going to be impractical. But for now it performs quite well, so we'll go
617611
// for it as keeping indices around would be annoying.
618-
pub fn all_statistic_descriptions(
612+
pub fn compile_statistic_descriptions(
619613
&self,
620-
) -> impl Iterator<Item = &'_ (Benchmark, Profile, Scenario, Metric)> + '_ {
621-
self.pstat_series.map.keys()
614+
) -> impl Iterator<
615+
Item = (
616+
&(Benchmark, Profile, Scenario, Metric),
617+
StatisticalDescriptionId,
618+
),
619+
> + '_ {
620+
self.pstat_series
621+
.map
622+
.iter()
623+
.map(|(test_case, &row_id)| (test_case, row_id))
624+
}
625+
626+
pub fn runtime_statistic_descriptions(
627+
&self,
628+
) -> impl Iterator<Item = (&(Benchmark, Metric), StatisticalDescriptionId)> + '_ {
629+
self.runtime_pstat_series
630+
.map
631+
.iter()
632+
.map(|(test_case, &row_id)| (test_case, row_id))
622633
}
623634

624635
pub fn artifact_id_for_commit(&self, commit: &str) -> Option<ArtifactId> {

database/src/pool.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ pub trait Connection: Send + Sync {
2626
);
2727
async fn get_compile_benchmarks(&self) -> Vec<CompileBenchmark>;
2828

29-
async fn record_runtime_benchmark(&self, name: &str);
30-
3129
async fn artifact_by_name(&self, artifact: &str) -> Option<ArtifactId>;
3230

3331
/// This records the duration of a collection run, i.e., collecting all of
@@ -112,6 +110,11 @@ pub trait Connection: Send + Sync {
112110
pstat_series_row_ids: &[u32],
113111
artifact_row_id: &[Option<ArtifactIdNumber>],
114112
) -> Vec<Vec<Option<f64>>>;
113+
async fn get_runtime_pstats(
114+
&self,
115+
runtime_pstat_series_row_ids: &[u32],
116+
artifact_row_id: &[Option<ArtifactIdNumber>],
117+
) -> Vec<Vec<Option<f64>>>;
115118
async fn get_error(&self, artifact_row_id: ArtifactIdNumber) -> HashMap<String, String>;
116119

117120
async fn queue_pr(

database/src/pool/postgres.rs

Lines changed: 129 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,21 @@ static MIGRATIONS: &[&str] = &[
215215
r#"
216216
alter table pull_request_build add column commit_date timestamptz;
217217
"#,
218+
r#"
219+
create table runtime_pstat_series(
220+
id integer primary key generated always as identity,
221+
benchmark text not null,
222+
metric text not null,
223+
UNIQUE(benchmark, metric)
224+
);
225+
create table runtime_pstat(
226+
series integer references runtime_pstat_series(id) on delete cascade on update cascade,
227+
aid integer references artifact(id) on delete cascade on update cascade,
228+
cid integer references collection(id) on delete cascade on update cascade,
229+
value double precision not null,
230+
PRIMARY KEY(series, aid, cid)
231+
);
232+
"#,
218233
];
219234

220235
#[async_trait::async_trait]
@@ -293,6 +308,10 @@ pub struct CachedStatements {
293308
record_duration: Statement,
294309
in_progress_steps: Statement,
295310
get_benchmarks: Statement,
311+
insert_runtime_pstat_series: Statement,
312+
select_runtime_pstat_series: Statement,
313+
insert_runtime_pstat: Statement,
314+
get_runtime_pstat: Statement,
296315
}
297316

298317
pub struct PostgresTransaction<'a> {
@@ -449,7 +468,36 @@ impl PostgresConnection {
449468
get_benchmarks: conn.prepare("
450469
select name, category
451470
from benchmark
452-
").await.unwrap()
471+
").await.unwrap(),
472+
insert_runtime_pstat_series: conn.prepare("insert into runtime_pstat_series (benchmark, metric) VALUES ($1, $2) ON CONFLICT DO NOTHING RETURNING id").await.unwrap(),
473+
select_runtime_pstat_series: conn.prepare("select id from runtime_pstat_series where benchmark = $1 and metric = $2").await.unwrap(),
474+
insert_runtime_pstat: conn
475+
.prepare("insert into runtime_pstat (series, aid, cid, value) VALUES ($1, $2, $3, $4)")
476+
.await
477+
.unwrap(),
478+
get_runtime_pstat: conn
479+
.prepare("
480+
WITH aids AS (
481+
select aid, num from unnest($2::int[]) with ordinality aids(aid, num)
482+
),
483+
sids AS (
484+
select sid, idx from unnest($1::int[]) with ordinality sids(sid, idx)
485+
)
486+
select ARRAY(
487+
(
488+
select min(runtime_pstat.value) from aids
489+
left outer join runtime_pstat
490+
on (aids.aid = runtime_pstat.aid and runtime_pstat.series = sids.sid)
491+
group by aids.num
492+
order by aids.num
493+
)
494+
) from
495+
sids
496+
group by (sids.idx, sids.sid)
497+
order by sids.idx
498+
")
499+
.await
500+
.unwrap()
453501
}),
454502
conn,
455503
}
@@ -522,23 +570,31 @@ where
522570
)
523571
})
524572
.collect(),
525-
errors: self
573+
pstat_series: self
526574
.conn()
527-
.query("select id, crate from error_series", &[])
575+
.query(
576+
"select id, crate, profile, cache, statistic from pstat_series;",
577+
&[],
578+
)
528579
.await
529580
.unwrap()
530581
.into_iter()
531582
.map(|row| {
532583
(
533584
row.get::<_, i32>(0) as u32,
534-
row.get::<_, String>(1).as_str().into(),
585+
(
586+
Benchmark::from(row.get::<_, String>(1).as_str()),
587+
Profile::from_str(row.get::<_, String>(2).as_str()).unwrap(),
588+
row.get::<_, String>(3).as_str().parse().unwrap(),
589+
row.get::<_, String>(4).as_str().into(),
590+
),
535591
)
536592
})
537593
.collect(),
538-
pstat_series: self
594+
runtime_pstat_series: self
539595
.conn()
540596
.query(
541-
"select id, crate, profile, cache, statistic from pstat_series;",
597+
"select id, benchmark, metric from runtime_pstat_series;",
542598
&[],
543599
)
544600
.await
@@ -548,10 +604,8 @@ where
548604
(
549605
row.get::<_, i32>(0) as u32,
550606
(
551-
Benchmark::from(row.get::<_, String>(1).as_str()),
552-
Profile::from_str(row.get::<_, String>(2).as_str()).unwrap(),
553-
row.get::<_, String>(3).as_str().parse().unwrap(),
554-
row.get::<_, String>(4).as_str().into(),
607+
row.get::<_, String>(1).as_str().into(),
608+
row.get::<_, String>(2).as_str().into(),
555609
),
556610
)
557611
})
@@ -597,6 +651,31 @@ where
597651
.map(|row| row.get::<_, Vec<Option<f64>>>(0))
598652
.collect()
599653
}
654+
async fn get_runtime_pstats(
655+
&self,
656+
runtime_pstat_series_row_ids: &[u32],
657+
artifact_row_ids: &[Option<crate::ArtifactIdNumber>],
658+
) -> Vec<Vec<Option<f64>>> {
659+
let runtime_pstat_series_row_ids = runtime_pstat_series_row_ids
660+
.iter()
661+
.map(|sid| *sid as i32)
662+
.collect::<Vec<_>>();
663+
let artifact_row_ids = artifact_row_ids
664+
.iter()
665+
.map(|id| id.map(|id| id.0 as i32))
666+
.collect::<Vec<_>>();
667+
let rows = self
668+
.conn()
669+
.query(
670+
&self.statements().get_runtime_pstat,
671+
&[&runtime_pstat_series_row_ids, &artifact_row_ids],
672+
)
673+
.await
674+
.unwrap();
675+
rows.into_iter()
676+
.map(|row| row.get::<_, Vec<Option<f64>>>(0))
677+
.collect()
678+
}
600679
async fn get_error(&self, artifact_row_id: crate::ArtifactIdNumber) -> HashMap<String, String> {
601680
let rows = self
602681
.conn()
@@ -744,13 +823,47 @@ where
744823
}
745824
async fn record_runtime_statistic(
746825
&self,
747-
_collection: CollectionId,
748-
_artifact: ArtifactIdNumber,
749-
_benchmark: &str,
750-
_metric: &str,
751-
_value: f64,
826+
collection: CollectionId,
827+
artifact: ArtifactIdNumber,
828+
benchmark: &str,
829+
metric: &str,
830+
value: f64,
752831
) {
753-
unimplemented!()
832+
let sid = self
833+
.conn()
834+
.query_opt(
835+
&self.statements().select_runtime_pstat_series,
836+
&[&benchmark, &metric],
837+
)
838+
.await
839+
.unwrap();
840+
let sid: i32 = match sid {
841+
Some(id) => id.get(0),
842+
None => {
843+
self.conn()
844+
.query_opt(
845+
&self.statements().insert_runtime_pstat_series,
846+
&[&benchmark, &metric],
847+
)
848+
.await
849+
.unwrap();
850+
self.conn()
851+
.query_one(
852+
&self.statements().select_runtime_pstat_series,
853+
&[&benchmark, &metric],
854+
)
855+
.await
856+
.unwrap()
857+
.get(0)
858+
}
859+
};
860+
self.conn()
861+
.execute(
862+
&self.statements().insert_runtime_pstat,
863+
&[&sid, &(artifact.0 as i32), &{ collection.0 }, &value],
864+
)
865+
.await
866+
.unwrap();
754867
}
755868

756869
async fn record_rustc_crate(
@@ -935,9 +1048,6 @@ where
9351048
.unwrap();
9361049
}
9371050
}
938-
async fn record_runtime_benchmark(&self, _name: &str) {
939-
unimplemented!()
940-
}
9411051

9421052
async fn collector_start(&self, aid: ArtifactIdNumber, steps: &[String]) {
9431053
// Clean up -- we'll re-insert any missing things in the loop below.

0 commit comments

Comments
 (0)