Skip to content

Commit 879bd57

Browse files
committed
Add function for finding computed test cases for an artifact
1 parent f33ebea commit 879bd57

File tree

3 files changed

+140
-2
lines changed

3 files changed

+140
-2
lines changed

database/src/pool.rs

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
use crate::selector::CompileTestCase;
12
use crate::{
23
ArtifactCollection, ArtifactId, ArtifactIdNumber, BenchmarkRequest, BenchmarkRequestIndex,
34
BenchmarkRequestStatus, CodegenBackend, CompileBenchmark, Target,
45
};
56
use crate::{CollectionId, Index, Profile, QueuedCommit, Scenario, Step};
67
use chrono::{DateTime, Utc};
7-
use hashbrown::HashMap;
8+
use hashbrown::{HashMap, HashSet};
89
use std::sync::{Arc, Mutex};
910
use std::time::Duration;
1011
use tokio::sync::{OwnedSemaphorePermit, Semaphore};
@@ -220,6 +221,17 @@ pub trait Connection: Send + Sync {
220221
profile: &Profile,
221222
benchmark_set: u32,
222223
) -> anyhow::Result<()>;
224+
225+
/// Returns a set of compile-time benchmark test cases that were already computed for the
226+
/// given artifact.
227+
/// Note that for efficiency reasons, the function only checks if we have at least a single
228+
/// result for a given test case. It does not check if *all* test results from all test
229+
/// iterations were finished.
230+
/// Therefore, the result is an over-approximation.
231+
async fn get_compile_test_cases_with_measurements(
232+
&self,
233+
artifact_row_id: &ArtifactIdNumber,
234+
) -> anyhow::Result<HashSet<CompileTestCase>>;
223235
}
224236

225237
#[async_trait::async_trait]
@@ -339,6 +351,9 @@ impl Pool {
339351

340352
#[cfg(test)]
341353
mod tests {
354+
use super::*;
355+
use crate::metric::Metric;
356+
use crate::{tests::run_db_test, Commit, CommitType, Date};
342357
use chrono::Utc;
343358
use std::str::FromStr;
344359

@@ -625,4 +640,64 @@ mod tests {
625640
})
626641
.await;
627642
}
643+
644+
#[tokio::test]
645+
async fn get_compile_test_cases_with_data() {
646+
run_db_test(|ctx| async {
647+
let db = ctx.db_client().connection().await;
648+
649+
let collection = db.collection_id("test").await;
650+
let artifact = db
651+
.artifact_id(&ArtifactId::Commit(create_commit(
652+
"abcdef",
653+
Utc::now(),
654+
CommitType::Try,
655+
)))
656+
.await;
657+
db.record_compile_benchmark("benchmark", None, "primary".to_string())
658+
.await;
659+
660+
db.record_statistic(
661+
collection,
662+
artifact,
663+
"benchmark",
664+
Profile::Check,
665+
Scenario::IncrementalFresh,
666+
CodegenBackend::Llvm,
667+
Target::X86_64UnknownLinuxGnu,
668+
Metric::CacheMisses.as_str(),
669+
1.0,
670+
)
671+
.await;
672+
673+
assert_eq!(
674+
db.get_compile_test_cases_with_measurements(&artifact)
675+
.await
676+
.unwrap(),
677+
HashSet::from([CompileTestCase {
678+
benchmark: "benchmark".into(),
679+
profile: Profile::Check,
680+
scenario: Scenario::IncrementalFresh,
681+
backend: CodegenBackend::Llvm,
682+
target: Target::X86_64UnknownLinuxGnu,
683+
}])
684+
);
685+
686+
let artifact2 = db
687+
.artifact_id(&ArtifactId::Commit(create_commit(
688+
"abcdef2",
689+
Utc::now(),
690+
CommitType::Try,
691+
)))
692+
.await;
693+
assert!(db
694+
.get_compile_test_cases_with_measurements(&artifact2)
695+
.await
696+
.unwrap()
697+
.is_empty());
698+
699+
Ok(ctx)
700+
})
701+
.await;
702+
}
628703
}

database/src/pool/postgres.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::pool::{Connection, ConnectionManager, ManagedConnection, Transaction};
2+
use crate::selector::CompileTestCase;
23
use crate::{
34
ArtifactCollection, ArtifactId, ArtifactIdNumber, Benchmark, BenchmarkJobStatus,
45
BenchmarkRequest, BenchmarkRequestIndex, BenchmarkRequestStatus, BenchmarkRequestType,
@@ -442,6 +443,7 @@ pub struct CachedStatements {
442443
record_artifact_size: Statement,
443444
get_artifact_size: Statement,
444445
load_benchmark_request_index: Statement,
446+
get_compile_test_cases_with_measurements: Statement,
445447
}
446448

447449
pub struct PostgresTransaction<'a> {
@@ -629,6 +631,15 @@ impl PostgresConnection {
629631
FROM benchmark_request
630632
WHERE tag IS NOT NULL
631633
").await.unwrap(),
634+
get_compile_test_cases_with_measurements: conn.prepare("
635+
SELECT DISTINCT crate, profile, scenario, backend, target
636+
FROM pstat_series
637+
WHERE id IN (
638+
SELECT DISTINCT series
639+
FROM pstat
640+
WHERE aid = $1
641+
)
642+
").await.unwrap(),
632643
}),
633644
conn,
634645
}
@@ -1680,6 +1691,30 @@ where
16801691
.context("failed to insert benchmark_job")?;
16811692
Ok(())
16821693
}
1694+
1695+
async fn get_compile_test_cases_with_measurements(
1696+
&self,
1697+
artifact_row_id: &ArtifactIdNumber,
1698+
) -> anyhow::Result<HashSet<CompileTestCase>> {
1699+
let rows = self
1700+
.conn()
1701+
.query(
1702+
&self.statements().get_compile_test_cases_with_measurements,
1703+
&[&(artifact_row_id.0 as i32)],
1704+
)
1705+
.await
1706+
.context("cannot query compile-time test cases with measurements")?;
1707+
Ok(rows
1708+
.into_iter()
1709+
.map(|row| CompileTestCase {
1710+
benchmark: Benchmark::from(row.get::<_, &str>(0)),
1711+
profile: Profile::from_str(row.get::<_, &str>(1)).unwrap(),
1712+
scenario: row.get::<_, &str>(2).parse().unwrap(),
1713+
backend: CodegenBackend::from_str(row.get::<_, &str>(3)).unwrap(),
1714+
target: Target::from_str(row.get::<_, &str>(4)).unwrap(),
1715+
})
1716+
.collect())
1717+
}
16831718
}
16841719

16851720
fn parse_artifact_id(ty: &str, sha: &str, date: Option<DateTime<Utc>>) -> ArtifactId {

database/src/pool/sqlite.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use crate::pool::{Connection, ConnectionManager, ManagedConnection, Transaction};
2+
use crate::selector::CompileTestCase;
23
use crate::{
34
ArtifactCollection, ArtifactId, Benchmark, BenchmarkRequest, BenchmarkRequestIndex,
45
BenchmarkRequestStatus, CodegenBackend, CollectionId, Commit, CommitType, CompileBenchmark,
56
Date, Profile, Target,
67
};
78
use crate::{ArtifactIdNumber, Index, QueuedCommit};
89
use chrono::{DateTime, TimeZone, Utc};
9-
use hashbrown::HashMap;
10+
use hashbrown::{HashMap, HashSet};
1011
use rusqlite::params;
1112
use rusqlite::OptionalExtension;
1213
use std::path::PathBuf;
@@ -1307,6 +1308,33 @@ impl Connection for SqliteConnection {
13071308
) -> anyhow::Result<()> {
13081309
no_queue_implementation_abort!()
13091310
}
1311+
1312+
async fn get_compile_test_cases_with_measurements(
1313+
&self,
1314+
artifact_row_id: &ArtifactIdNumber,
1315+
) -> anyhow::Result<HashSet<CompileTestCase>> {
1316+
Ok(self
1317+
.raw_ref()
1318+
.prepare_cached(
1319+
"SELECT DISTINCT crate, profile, scenario, backend, target
1320+
FROM pstat_series
1321+
WHERE id IN (
1322+
SELECT DISTINCT series
1323+
FROM pstat
1324+
WHERE aid = ?
1325+
);",
1326+
)?
1327+
.query_map(params![artifact_row_id.0], |row| {
1328+
Ok(CompileTestCase {
1329+
benchmark: Benchmark::from(row.get::<_, String>(0)?.as_str()),
1330+
profile: row.get::<_, String>(1)?.parse().unwrap(),
1331+
scenario: row.get::<_, String>(2)?.parse().unwrap(),
1332+
backend: row.get::<_, String>(3)?.parse().unwrap(),
1333+
target: row.get::<_, String>(4)?.parse().unwrap(),
1334+
})
1335+
})?
1336+
.collect::<Result<_, _>>()?)
1337+
}
13101338
}
13111339

13121340
fn parse_artifact_id(ty: &str, sha: &str, date: Option<i64>) -> ArtifactId {

0 commit comments

Comments
 (0)