Skip to content

Commit ae6786c

Browse files
committed
Add function for finding computed test cases for an artifact
1 parent 5236fe9 commit ae6786c

File tree

3 files changed

+145
-7
lines changed

3 files changed

+145
-7
lines changed

database/src/pool.rs

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
use crate::selector::CompileTestCase;
12
use crate::{
23
ArtifactCollection, ArtifactId, ArtifactIdNumber, CodegenBackend, CompileBenchmark, Target,
34
};
45
use crate::{CollectionId, Index, Profile, QueuedCommit, Scenario, Step};
56
use chrono::{DateTime, Utc};
6-
use hashbrown::HashMap;
7+
use hashbrown::{HashMap, HashSet};
78
use std::sync::{Arc, Mutex};
89
use std::time::Duration;
910
use tokio::sync::{OwnedSemaphorePermit, Semaphore};
@@ -178,6 +179,17 @@ pub trait Connection: Send + Sync {
178179

179180
/// Removes all data associated with the given artifact.
180181
async fn purge_artifact(&self, aid: &ArtifactId);
182+
183+
/// Returns a set of compile-time benchmark test cases that were already computed for the
184+
/// given artifact.
185+
/// Note that for efficiency reasons, the function only checks if we have at least a single
186+
/// result for a given test case. It does not check if *all* test results from all test
187+
/// iterations were finished.
188+
/// Therefore, the result is an over-approximation.
189+
async fn get_compile_test_cases_with_measurements(
190+
&self,
191+
artifact_row_id: &ArtifactIdNumber,
192+
) -> anyhow::Result<HashSet<CompileTestCase>>;
181193
}
182194

183195
#[async_trait::async_trait]
@@ -297,11 +309,11 @@ impl Pool {
297309

298310
#[cfg(test)]
299311
mod tests {
300-
use chrono::Utc;
301-
use std::str::FromStr;
302-
303312
use super::*;
313+
use crate::metric::Metric;
304314
use crate::{tests::run_db_test, Commit, CommitType, Date};
315+
use chrono::Utc;
316+
use std::str::FromStr;
305317

306318
/// Create a Commit
307319
fn create_commit(commit_sha: &str, time: chrono::DateTime<Utc>, r#type: CommitType) -> Commit {
@@ -370,4 +382,64 @@ mod tests {
370382
})
371383
.await;
372384
}
385+
386+
#[tokio::test]
387+
async fn get_compile_test_cases_with_data() {
388+
run_db_test(|ctx| async {
389+
let db = ctx.db_client().connection().await;
390+
391+
let collection = db.collection_id("test").await;
392+
let artifact = db
393+
.artifact_id(&ArtifactId::Commit(create_commit(
394+
"abcdef",
395+
Utc::now(),
396+
CommitType::Try,
397+
)))
398+
.await;
399+
db.record_compile_benchmark("benchmark", None, "primary".to_string())
400+
.await;
401+
402+
db.record_statistic(
403+
collection,
404+
artifact,
405+
"benchmark",
406+
Profile::Check,
407+
Scenario::IncrementalFresh,
408+
CodegenBackend::Llvm,
409+
Target::X86_64UnknownLinuxGnu,
410+
Metric::CacheMisses.as_str(),
411+
1.0,
412+
)
413+
.await;
414+
415+
assert_eq!(
416+
db.get_compile_test_cases_with_measurements(&artifact)
417+
.await
418+
.unwrap(),
419+
HashSet::from([CompileTestCase {
420+
benchmark: "benchmark".into(),
421+
profile: Profile::Check,
422+
scenario: Scenario::IncrementalFresh,
423+
backend: CodegenBackend::Llvm,
424+
target: Target::X86_64UnknownLinuxGnu,
425+
}])
426+
);
427+
428+
let artifact2 = db
429+
.artifact_id(&ArtifactId::Commit(create_commit(
430+
"abcdef2",
431+
Utc::now(),
432+
CommitType::Try,
433+
)))
434+
.await;
435+
assert!(db
436+
.get_compile_test_cases_with_measurements(&artifact2)
437+
.await
438+
.unwrap()
439+
.is_empty());
440+
441+
Ok(ctx)
442+
})
443+
.await;
444+
}
373445
}

database/src/pool/postgres.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::pool::{Connection, ConnectionManager, ManagedConnection, Transaction};
2+
use crate::selector::CompileTestCase;
23
use crate::{
34
ArtifactCollection, ArtifactId, ArtifactIdNumber, Benchmark, CodegenBackend, CollectionId,
45
Commit, CommitType, CompileBenchmark, Date, Index, Profile, QueuedCommit, Scenario, Target,
56
};
67
use anyhow::Context as _;
78
use chrono::{DateTime, TimeZone, Utc};
8-
use hashbrown::HashMap;
9+
use hashbrown::{HashMap, HashSet};
910
use native_tls::{Certificate, TlsConnector};
1011
use postgres_native_tls::MakeTlsConnector;
1112
use std::str::FromStr;
@@ -366,6 +367,7 @@ pub struct CachedStatements {
366367
get_runtime_pstat: Statement,
367368
record_artifact_size: Statement,
368369
get_artifact_size: Statement,
370+
get_compile_test_cases_with_measurements: Statement,
369371
}
370372

371373
pub struct PostgresTransaction<'a> {
@@ -547,7 +549,16 @@ impl PostgresConnection {
547549
get_artifact_size: conn.prepare("
548550
select component, size from artifact_size
549551
where aid = $1
550-
").await.unwrap()
552+
").await.unwrap(),
553+
get_compile_test_cases_with_measurements: conn.prepare("
554+
SELECT DISTINCT crate, profile, scenario, backend, target
555+
FROM pstat_series
556+
WHERE id IN (
557+
SELECT DISTINCT series
558+
FROM pstat
559+
WHERE aid = $1
560+
)
561+
").await.unwrap(),
551562
}),
552563
conn,
553564
}
@@ -1365,6 +1376,30 @@ where
13651376
.await
13661377
.unwrap();
13671378
}
1379+
1380+
async fn get_compile_test_cases_with_measurements(
1381+
&self,
1382+
artifact_row_id: &ArtifactIdNumber,
1383+
) -> anyhow::Result<HashSet<CompileTestCase>> {
1384+
let rows = self
1385+
.conn()
1386+
.query(
1387+
&self.statements().get_compile_test_cases_with_measurements,
1388+
&[&(artifact_row_id.0 as i32)],
1389+
)
1390+
.await
1391+
.context("cannot query compile-time test cases with measurements")?;
1392+
Ok(rows
1393+
.into_iter()
1394+
.map(|row| CompileTestCase {
1395+
benchmark: Benchmark::from(row.get::<_, &str>(0)),
1396+
profile: Profile::from_str(row.get::<_, &str>(1)).unwrap(),
1397+
scenario: row.get::<_, &str>(2).parse().unwrap(),
1398+
backend: CodegenBackend::from_str(row.get::<_, &str>(3)).unwrap(),
1399+
target: Target::from_str(row.get::<_, &str>(4)).unwrap(),
1400+
})
1401+
.collect())
1402+
}
13681403
}
13691404

13701405
fn parse_artifact_id(ty: &str, sha: &str, date: Option<DateTime<Utc>>) -> ArtifactId {
@@ -1397,4 +1432,7 @@ mod tests {
13971432
let certs = make_certificates().await;
13981433
assert!(!certs.is_empty());
13991434
}
1435+
1436+
#[tokio::test]
1437+
async fn foo() {}
14001438
}

database/src/pool/sqlite.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::pool::{Connection, ConnectionManager, ManagedConnection, Transaction};
2+
use crate::selector::CompileTestCase;
23
use crate::{
34
ArtifactCollection, ArtifactId, Benchmark, CodegenBackend, CollectionId, Commit, CommitType,
45
CompileBenchmark, Date, Profile, Target,
56
};
67
use crate::{ArtifactIdNumber, Index, QueuedCommit};
78
use chrono::{DateTime, TimeZone, Utc};
8-
use hashbrown::HashMap;
9+
use hashbrown::{HashMap, HashSet};
910
use rusqlite::params;
1011
use rusqlite::OptionalExtension;
1112
use std::path::PathBuf;
@@ -1252,6 +1253,33 @@ impl Connection for SqliteConnection {
12521253
)
12531254
.unwrap();
12541255
}
1256+
1257+
async fn get_compile_test_cases_with_measurements(
1258+
&self,
1259+
artifact_row_id: &ArtifactIdNumber,
1260+
) -> anyhow::Result<HashSet<CompileTestCase>> {
1261+
Ok(self
1262+
.raw_ref()
1263+
.prepare_cached(
1264+
"SELECT DISTINCT crate, profile, scenario, backend, target
1265+
FROM pstat_series
1266+
WHERE id IN (
1267+
SELECT DISTINCT series
1268+
FROM pstat
1269+
WHERE aid = ?
1270+
);",
1271+
)?
1272+
.query_map(params![artifact_row_id.0], |row| {
1273+
Ok(CompileTestCase {
1274+
benchmark: Benchmark::from(row.get::<_, String>(0)?.as_str()),
1275+
profile: row.get::<_, String>(1)?.parse().unwrap(),
1276+
scenario: row.get::<_, String>(2)?.parse().unwrap(),
1277+
backend: row.get::<_, String>(3)?.parse().unwrap(),
1278+
target: row.get::<_, String>(4)?.parse().unwrap(),
1279+
})
1280+
})?
1281+
.collect::<Result<_, _>>()?)
1282+
}
12551283
}
12561284

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

0 commit comments

Comments
 (0)