Skip to content

Commit 5a1f928

Browse files
New graph API for #742
1 parent 0bad409 commit 5a1f928

File tree

2 files changed

+90
-2
lines changed

2 files changed

+90
-2
lines changed

site/src/api.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub mod data {
111111
pub mod graph {
112112
use collector::Bound;
113113
use serde::{Deserialize, Serialize};
114-
use std::collections::HashMap;
114+
use std::collections::{HashMap, HashSet};
115115

116116
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
117117
pub struct Request {
@@ -138,6 +138,21 @@ pub mod graph {
138138
pub colors: Vec<String>,
139139
pub commits: Vec<String>,
140140
}
141+
142+
#[derive(Debug, PartialEq, Clone, Serialize)]
143+
pub struct Series {
144+
// y-values
145+
pub points: Vec<f32>,
146+
// The index of interpolated coordinates
147+
pub is_interpolated: HashSet<u16>,
148+
}
149+
150+
#[derive(Debug, PartialEq, Clone, Serialize)]
151+
pub struct NewResponse {
152+
// (UTC timestamp in seconds, sha)
153+
pub commits: Vec<(i64, String)>,
154+
pub benchmarks: HashMap<String, HashMap<database::Profile, HashMap<String, Series>>>,
155+
}
141156
}
142157

143158
pub mod days {

site/src/server.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,58 @@ fn to_graph_data<'a>(
395395
})
396396
}
397397

398+
pub async fn handle_graph_new(
399+
body: graph::Request,
400+
data: &InputData,
401+
) -> ServerResult<Arc<graph::NewResponse>> {
402+
log::info!("handle_graph_new({:?})", body);
403+
let range = data.data_range(body.start.clone()..=body.end.clone());
404+
let commits: Arc<Vec<ArtifactId>> = Arc::new(range.iter().map(|c| c.clone().into()).collect());
405+
406+
let mut benchmarks = HashMap::new();
407+
408+
let raw = handle_graph(body, data).await?;
409+
410+
for (crate_, crate_data) in raw.benchmarks.iter() {
411+
let mut by_profile = HashMap::with_capacity(3);
412+
413+
for (profile, series) in crate_data.iter() {
414+
let mut by_run = HashMap::with_capacity(3);
415+
416+
for (name, points) in series.iter() {
417+
let mut series = graph::Series {
418+
points: Vec::new(),
419+
is_interpolated: Default::default(),
420+
};
421+
422+
for (idx, point) in points.iter().enumerate() {
423+
series.points.push(point.y);
424+
if point.is_interpolated {
425+
series.is_interpolated.insert(idx as u16);
426+
}
427+
}
428+
429+
by_run.insert(name.clone(), series);
430+
}
431+
432+
by_profile.insert(profile.parse::<Profile>().unwrap(), by_run);
433+
}
434+
435+
benchmarks.insert(crate_.clone(), by_profile);
436+
}
437+
438+
Ok(Arc::new(graph::NewResponse {
439+
commits: commits
440+
.iter()
441+
.map(|c| match c {
442+
ArtifactId::Commit(c) => (c.date.0.timestamp(), c.sha.clone()),
443+
ArtifactId::Artifact(_) => unreachable!(),
444+
})
445+
.collect(),
446+
benchmarks,
447+
}))
448+
}
449+
398450
pub async fn handle_graph(
399451
body: graph::Request,
400452
data: &InputData,
@@ -1405,7 +1457,6 @@ async fn serve_req(ctx: Arc<Server>, req: Request) -> Result<Response, ServerErr
14051457
Err(e) => return Ok(e),
14061458
}
14071459
}
1408-
14091460
let (req, mut body_stream) = req.into_parts();
14101461
let p = req.uri.path();
14111462
check_http_method!(req.method, http::Method::POST);
@@ -1489,6 +1540,28 @@ async fn serve_req(ctx: Arc<Server>, req: Request) -> Result<Response, ServerErr
14891540
Ok(to_response(
14901541
handle_self_profile_raw(body!(parse_body(&body)), &data, true).await,
14911542
))
1543+
} else if p == "/perf/graph-new" {
1544+
Ok(
1545+
match handle_graph_new(body!(parse_body(&body)), &data).await {
1546+
Ok(result) => {
1547+
let mut response = http::Response::builder()
1548+
.header_typed(ContentType::json())
1549+
.header_typed(CacheControl::new().with_no_cache().with_no_store());
1550+
response.headers_mut().unwrap().insert(
1551+
hyper::header::ACCESS_CONTROL_ALLOW_ORIGIN,
1552+
hyper::header::HeaderValue::from_static("*"),
1553+
);
1554+
let body = serde_json::to_vec(&result).unwrap();
1555+
response.body(hyper::Body::from(body)).unwrap()
1556+
}
1557+
Err(err) => http::Response::builder()
1558+
.status(StatusCode::INTERNAL_SERVER_ERROR)
1559+
.header_typed(ContentType::text_utf8())
1560+
.header_typed(CacheControl::new().with_no_cache().with_no_store())
1561+
.body(hyper::Body::from(err))
1562+
.unwrap(),
1563+
},
1564+
)
14921565
} else {
14931566
return Ok(http::Response::builder()
14941567
.header_typed(ContentType::html())

0 commit comments

Comments
 (0)