Skip to content

Commit 6a5dfd0

Browse files
authored
Merge pull request #944 from rylev/simplify-query-interface
Simplify query interface
2 parents c17ff4b + dd84de4 commit 6a5dfd0

File tree

3 files changed

+57
-193
lines changed

3 files changed

+57
-193
lines changed

site/src/comparison.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ async fn compare_given_commits(
247247

248248
// `responses` contains series iterators. The first element in the iterator is the data
249249
// for `a` and the second is the data for `b`
250-
let mut responses = ctxt.query::<Option<f64>>(query.clone(), aids).await?;
250+
let mut responses = ctxt.statistic_series(query.clone(), aids).await?;
251251

252252
let conn = ctxt.conn().await;
253253
Ok(Some(Comparison {
@@ -492,7 +492,7 @@ impl BenchmarkVariances {
492492
master_commits,
493493
));
494494
let mut previous_commit_series = ctxt
495-
.query::<Option<f64>>(query, previous_commits.clone())
495+
.statistic_series(query, previous_commits.clone())
496496
.await?;
497497

498498
let mut variance_data: HashMap<String, BenchmarkVariance> = HashMap::new();

site/src/selector.rs

Lines changed: 49 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use crate::db::{ArtifactId, Profile, Scenario};
2525
use crate::interpolate::Interpolate;
2626
use crate::load::SiteCtxt;
2727

28-
use async_trait::async_trait;
2928
use collector::Bound;
3029
use database::{Benchmark, Commit, Index, Lookup, Metric, QueryLabel};
3130

@@ -268,13 +267,6 @@ impl<T> SeriesResponse<T> {
268267
}
269268
}
270269

271-
pub trait Series: Sized
272-
where
273-
Self: Iterator<Item = (ArtifactId, <Self as Series>::Element)>,
274-
{
275-
type Element: Sized;
276-
}
277-
278270
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
279271
pub struct Path {
280272
path: Vec<PathComponent>,
@@ -381,46 +373,6 @@ impl Query {
381373
}
382374
}
383375

384-
#[async_trait]
385-
pub trait SeriesElement: Sized {
386-
async fn query<'a>(
387-
ctxt: &'a SiteCtxt,
388-
artifact_ids: Arc<Vec<ArtifactId>>,
389-
query: Query,
390-
) -> Result<Vec<SeriesResponse<Box<dyn Iterator<Item = (ArtifactId, Self)> + Send + 'a>>>, String>;
391-
}
392-
393-
fn handle_results<'a, E>(
394-
results: Vec<
395-
Result<Vec<SeriesResponse<Box<dyn Iterator<Item = (ArtifactId, E)> + Send + 'a>>>, String>,
396-
>,
397-
) -> Result<Vec<SeriesResponse<Box<dyn Iterator<Item = (ArtifactId, E)> + Send + 'a>>>, String> {
398-
let mut ok = None;
399-
let mut errs = Vec::new();
400-
for res in results {
401-
match (res, ok.is_some()) {
402-
(Ok(r), false) => {
403-
ok = Some(r);
404-
}
405-
(Ok(_), true) => panic!("two series successfully expanded"),
406-
(Err(e), _) => errs.push(e),
407-
}
408-
}
409-
410-
ok.ok_or_else(|| {
411-
format!(
412-
"Failed to process query; fix one of these errors: {}",
413-
errs.into_iter().fold(String::new(), |mut acc, err| {
414-
if !acc.is_empty() {
415-
acc.push_str("; or ");
416-
}
417-
acc.push_str(&err);
418-
acc
419-
})
420-
)
421-
})
422-
}
423-
424376
#[derive(Debug, Clone)]
425377
pub struct SelfProfileData {
426378
pub query_data: Vec<QueryData>,
@@ -454,88 +406,29 @@ impl QueryData {
454406
}
455407
}
456408

457-
#[async_trait]
458-
impl SeriesElement for Option<SelfProfileData> {
459-
async fn query<'a>(
460-
ctxt: &'a SiteCtxt,
461-
artifact_ids: Arc<Vec<ArtifactId>>,
409+
impl SiteCtxt {
410+
pub async fn statistic_series(
411+
&self,
462412
query: Query,
463-
) -> Result<
464-
Vec<
465-
SeriesResponse<
466-
Box<dyn Iterator<Item = (ArtifactId, Option<SelfProfileData>)> + Send + 'a>,
467-
>,
468-
>,
469-
String,
470-
> {
471-
let results = vec![SelfProfile::expand_query(artifact_ids, ctxt, query.clone())
472-
.await
473-
.map(|sr| {
474-
sr.into_iter()
475-
.map(|sr| {
476-
sr.map(|r| {
477-
Box::new(r)
478-
as Box<
479-
dyn Iterator<Item = (ArtifactId, Option<SelfProfileData>)>
480-
+ Send,
481-
>
482-
})
483-
})
484-
.collect()
485-
})];
486-
handle_results(results)
487-
}
488-
}
489-
490-
#[async_trait]
491-
impl SeriesElement for Option<f64> {
492-
async fn query<'a>(
493-
ctxt: &'a SiteCtxt,
494413
artifact_ids: Arc<Vec<ArtifactId>>,
495-
query: Query,
496-
) -> Result<
497-
Vec<SeriesResponse<Box<dyn Iterator<Item = (ArtifactId, Option<f64>)> + Send + 'a>>>,
498-
String,
499-
> {
500-
let results = vec![
501-
StatisticSeries::expand_query(artifact_ids.clone(), ctxt, query.clone())
502-
.await
503-
.map(|sr| {
504-
sr.into_iter()
505-
.map(|sr| {
506-
sr.map(|r| {
507-
Box::new(r)
508-
as Box<dyn Iterator<Item = (ArtifactId, Option<f64>)> + Send>
509-
})
510-
})
511-
.collect()
512-
}),
513-
SelfProfileQueryTime::expand_query(artifact_ids.clone(), ctxt, query.clone())
514-
.await
515-
.map(|sr| {
516-
sr.into_iter()
517-
.map(|sr| {
518-
sr.map(|r| {
519-
Box::new(r)
520-
as Box<dyn Iterator<Item = (ArtifactId, Option<f64>)> + Send>
521-
})
522-
})
523-
.collect()
524-
}),
525-
];
414+
) -> Result<Vec<SeriesResponse<StatisticSeries>>, String> {
415+
StatisticSeries::execute_query(artifact_ids.clone(), self, query.clone()).await
416+
}
526417

527-
handle_results(results)
418+
pub async fn self_profile(
419+
&self,
420+
query: Query,
421+
artifact_ids: Arc<Vec<ArtifactId>>,
422+
) -> Result<Vec<SeriesResponse<SelfProfile>>, String> {
423+
SelfProfile::execute_query(artifact_ids, self, query.clone()).await
528424
}
529-
}
530425

531-
impl SiteCtxt {
532-
pub async fn query<'a, E: SeriesElement>(
533-
&'a self,
426+
pub async fn self_profile_query_time(
427+
&self,
534428
query: Query,
535429
artifact_ids: Arc<Vec<ArtifactId>>,
536-
) -> Result<Vec<SeriesResponse<Box<dyn Iterator<Item = (ArtifactId, E)> + Send + 'a>>>, String>
537-
{
538-
E::query(self, artifact_ids, query).await
430+
) -> Result<Vec<SeriesResponse<SelfProfileQueryTime>>, String> {
431+
SelfProfileQueryTime::execute_query(artifact_ids, self, query.clone()).await
539432
}
540433
}
541434

@@ -544,12 +437,8 @@ pub struct StatisticSeries {
544437
points: std::vec::IntoIter<Option<f64>>,
545438
}
546439

547-
impl Series for StatisticSeries {
548-
type Element = Option<f64>;
549-
}
550-
551440
impl StatisticSeries {
552-
async fn expand_query(
441+
async fn execute_query(
553442
artifact_ids: Arc<Vec<ArtifactId>>,
554443
ctxt: &SiteCtxt,
555444
mut query: Query,
@@ -710,25 +599,8 @@ impl SelfProfile {
710599
points: res.into_iter(),
711600
}
712601
}
713-
}
714-
715-
impl Iterator for SelfProfile {
716-
type Item = (ArtifactId, Option<SelfProfileData>);
717-
fn next(&mut self) -> Option<Self::Item> {
718-
Some((self.artifact_ids.next()?, self.points.next().unwrap()))
719-
}
720-
721-
fn size_hint(&self) -> (usize, Option<usize>) {
722-
self.artifact_ids.size_hint()
723-
}
724-
}
725-
726-
impl Series for SelfProfile {
727-
type Element = Option<SelfProfileData>;
728-
}
729602

730-
impl SelfProfile {
731-
async fn expand_query(
603+
async fn execute_query(
732604
artifact_ids: Arc<Vec<ArtifactId>>,
733605
ctxt: &SiteCtxt,
734606
mut query: Query,
@@ -765,6 +637,17 @@ impl SelfProfile {
765637
}
766638
}
767639

640+
impl Iterator for SelfProfile {
641+
type Item = (ArtifactId, Option<SelfProfileData>);
642+
fn next(&mut self) -> Option<Self::Item> {
643+
Some((self.artifact_ids.next()?, self.points.next().unwrap()))
644+
}
645+
646+
fn size_hint(&self) -> (usize, Option<usize>) {
647+
self.artifact_ids.size_hint()
648+
}
649+
}
650+
768651
pub struct SelfProfileQueryTime {
769652
artifact_ids: ArtifactIdIter,
770653
points: std::vec::IntoIter<Option<f64>>,
@@ -802,25 +685,8 @@ impl SelfProfileQueryTime {
802685
points: res.into_iter(),
803686
}
804687
}
805-
}
806-
807-
impl Iterator for SelfProfileQueryTime {
808-
type Item = (ArtifactId, Option<f64>);
809-
fn next(&mut self) -> Option<Self::Item> {
810-
Some((self.artifact_ids.next()?, self.points.next().unwrap()))
811-
}
812688

813-
fn size_hint(&self) -> (usize, Option<usize>) {
814-
self.artifact_ids.size_hint()
815-
}
816-
}
817-
818-
impl Series for SelfProfileQueryTime {
819-
type Element = Option<f64>;
820-
}
821-
822-
impl SelfProfileQueryTime {
823-
async fn expand_query(
689+
async fn execute_query(
824690
artifact_ids: Arc<Vec<ArtifactId>>,
825691
ctxt: &SiteCtxt,
826692
mut query: Query,
@@ -834,35 +700,35 @@ impl SelfProfileQueryTime {
834700
let index = ctxt.index.load();
835701
let mut series = index
836702
.all_query_series()
837-
.filter(|tup| {
838-
benchmark.matches(tup.0)
839-
&& profile.matches(tup.1)
840-
&& scenario.matches(tup.2)
841-
&& ql.matches(tup.3)
703+
.filter(|&&(b, p, s, q)| {
704+
benchmark.matches(b) && profile.matches(p) && scenario.matches(s) && ql.matches(q)
842705
})
843706
.collect::<Vec<_>>();
844707

845708
series.sort_unstable();
846709

847710
let mut res = Vec::with_capacity(series.len());
848-
for path in series {
711+
for &(b, p, s, q) in series {
849712
res.push(SeriesResponse {
850-
series: SelfProfileQueryTime::new(
851-
artifact_ids.clone(),
852-
ctxt,
853-
path.0,
854-
path.1,
855-
path.2,
856-
path.3,
857-
)
858-
.await,
713+
series: SelfProfileQueryTime::new(artifact_ids.clone(), ctxt, b, p, s, q).await,
859714
path: Path::new()
860-
.set(PathComponent::Benchmark(path.0))
861-
.set(PathComponent::Profile(path.1))
862-
.set(PathComponent::Scenario(path.2))
863-
.set(PathComponent::QueryLabel(path.3)),
715+
.set(PathComponent::Benchmark(b))
716+
.set(PathComponent::Profile(p))
717+
.set(PathComponent::Scenario(s))
718+
.set(PathComponent::QueryLabel(q)),
864719
});
865720
}
866721
Ok(res)
867722
}
868723
}
724+
725+
impl Iterator for SelfProfileQueryTime {
726+
type Item = (ArtifactId, Option<f64>);
727+
fn next(&mut self) -> Option<Self::Item> {
728+
Some((self.artifact_ids.next()?, self.points.next().unwrap()))
729+
}
730+
731+
fn size_hint(&self) -> (usize, Option<usize>) {
732+
self.artifact_ids.size_hint()
733+
}
734+
}

site/src/server.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ pub async fn handle_dashboard(ctxt: Arc<SiteCtxt>) -> ServerResult<dashboard::Re
181181
let mut cases = dashboard::Cases::default();
182182
for scenario in summary_scenarios.iter() {
183183
let responses = ctxt
184-
.query::<Option<f64>>(
184+
.statistic_series(
185185
query
186186
.clone()
187187
.set(Tag::Profile, selector::Selector::One(profile))
@@ -478,7 +478,7 @@ pub async fn handle_graph(
478478
let metric_selector = selector::Selector::One(body.stat.clone());
479479

480480
let series = ctxt
481-
.query::<Option<f64>>(
481+
.statistic_series(
482482
selector::Query::new()
483483
.set::<String>(selector::Tag::Benchmark, selector::Selector::All)
484484
.set::<String>(selector::Tag::Profile, selector::Selector::All)
@@ -543,7 +543,7 @@ pub async fn handle_graph(
543543
std::collections::hash_map::Entry::Occupied(o) => *o.get(),
544544
std::collections::hash_map::Entry::Vacant(v) => {
545545
let value = db::average(
546-
ctxt.query::<Option<f64>>(q, c.clone())
546+
ctxt.statistic_series(q, c.clone())
547547
.await?
548548
.into_iter()
549549
.map(|sr| sr.interpolate().series)
@@ -555,7 +555,7 @@ pub async fn handle_graph(
555555
}
556556
};
557557
let averaged = db::average(
558-
ctxt.query::<Option<f64>>(query.clone(), commits.clone())
558+
ctxt.statistic_series(query.clone(), commits.clone())
559559
.await?
560560
.into_iter()
561561
.map(|sr| sr.interpolate().series)
@@ -1078,9 +1078,7 @@ pub async fn handle_self_profile(
10781078
}
10791079

10801080
let commits = Arc::new(commits);
1081-
let mut sp_responses = ctxt
1082-
.query::<Option<selector::SelfProfileData>>(query.clone(), commits.clone())
1083-
.await?;
1081+
let mut sp_responses = ctxt.self_profile(query.clone(), commits.clone()).await?;
10841082

10851083
if sp_responses.is_empty() {
10861084
return Err(format!("no results found for {:?} in {:?}", query, commits));
@@ -1098,7 +1096,7 @@ pub async fn handle_self_profile(
10981096
let mut sp_response = sp_responses.remove(0).series;
10991097

11001098
let mut cpu_responses = ctxt
1101-
.query::<Option<f64>>(
1099+
.self_profile_query_time(
11021100
query.clone().set(
11031101
Tag::Metric,
11041102
selector::Selector::One("cpu-clock".to_string()),

0 commit comments

Comments
 (0)