Skip to content

Commit 1c1dab6

Browse files
committed
Improve benchmark chart virtual history warmup
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
1 parent 7fc5697 commit 1c1dab6

13 files changed

Lines changed: 453 additions & 160 deletions

File tree

benchmarks-website/server/src/api/charts.rs

Lines changed: 87 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use duckdb::Connection;
1717
use duckdb::ToSql;
1818
use duckdb::params_from_iter;
1919

20+
use super::dto::ChartHistory;
2021
use super::dto::ChartResponse;
2122
use super::dto::CommitPoint;
2223
use super::dto::GroupChartsResponse;
@@ -193,7 +194,12 @@ impl SeriesAccumulator {
193194
}
194195
}
195196

196-
fn finish(self, display_name: String, unit_kind: UnitKind) -> ChartResponse {
197+
fn finish(
198+
self,
199+
display_name: String,
200+
unit_kind: UnitKind,
201+
history: ChartHistory,
202+
) -> ChartResponse {
197203
let total = self.commits.len();
198204
let mut series_map = serde_json::Map::new();
199205
for (k, mut v) in self.series {
@@ -205,13 +211,19 @@ impl SeriesAccumulator {
205211
ChartResponse {
206212
display_name,
207213
unit_kind,
214+
history,
208215
commits: self.commits,
209216
series: series_map,
210217
series_meta: self.tags,
211218
}
212219
}
213220
}
214221

222+
struct SeededCommits {
223+
commits: Vec<CommitPoint>,
224+
history: ChartHistory,
225+
}
226+
215227
/// Resolve a chart's x-axis: every commit in the requested commit-window
216228
/// whose timestamp is at or after the earliest commit that has a row in the
217229
/// fact table for this chart. Returns the list oldest-first; an empty list
@@ -234,32 +246,65 @@ fn seeded_commits_in_window(
234246
earliest_subquery: &str,
235247
subquery_binds: Vec<Box<dyn ToSql>>,
236248
window: &CommitWindow,
237-
) -> Result<Vec<CommitPoint>> {
249+
) -> Result<SeededCommits> {
250+
let window_filter = match window {
251+
CommitWindow::All => "",
252+
CommitWindow::Last(_) => "WHERE rn > total_commits - ?",
253+
};
238254
let sql = format!(
239255
r#"
240-
SELECT c.commit_sha,
241-
CAST(c.timestamp AS VARCHAR),
242-
COALESCE(c.message, ''),
243-
c.url
244-
FROM commits c
245-
WHERE c.timestamp >= ({earliest_subquery}){window_filter}
246-
ORDER BY c.timestamp ASC
256+
WITH eligible AS (
257+
SELECT c.commit_sha,
258+
c.timestamp,
259+
COALESCE(c.message, '') AS message,
260+
c.url,
261+
row_number() OVER (ORDER BY c.timestamp ASC, c.commit_sha ASC) AS rn,
262+
count(*) OVER () AS total_commits
263+
FROM commits c
264+
WHERE c.timestamp >= ({earliest_subquery})
265+
)
266+
SELECT commit_sha,
267+
CAST(timestamp AS VARCHAR),
268+
message,
269+
url,
270+
total_commits
271+
FROM eligible
272+
{window_filter}
273+
ORDER BY timestamp ASC, commit_sha ASC
247274
"#,
248-
window_filter = window.sql_filter(),
249275
);
250276
let mut stmt = conn.prepare(&sql)?;
251277
let mut binds = subquery_binds;
252278
push_window_limit(&mut binds, window);
253279
let rows = stmt.query_map(params_from_iter(binds.iter()), |row| {
254-
Ok(CommitPoint {
255-
sha: row.get(0)?,
256-
timestamp: row.get(1)?,
257-
message: row.get(2)?,
258-
url: row.get(3)?,
259-
})
280+
Ok((
281+
CommitPoint {
282+
sha: row.get(0)?,
283+
timestamp: row.get(1)?,
284+
message: row.get(2)?,
285+
url: row.get(3)?,
286+
},
287+
row.get::<_, i64>(4)?,
288+
))
260289
})?;
261-
let out: Vec<CommitPoint> = rows.collect::<Result<_, _>>()?;
262-
Ok(out)
290+
let rows: Vec<(CommitPoint, i64)> = rows.collect::<Result<_, _>>()?;
291+
let total_commits = rows
292+
.first()
293+
.map(|(_, total)| usize::try_from(*total))
294+
.transpose()?
295+
.unwrap_or_default();
296+
let commits: Vec<CommitPoint> = rows.into_iter().map(|(commit, _)| commit).collect();
297+
let loaded_commits = commits.len();
298+
let start_index = total_commits.saturating_sub(loaded_commits);
299+
Ok(SeededCommits {
300+
commits,
301+
history: ChartHistory {
302+
total_commits,
303+
start_index,
304+
loaded_commits,
305+
complete: loaded_commits == total_commits,
306+
},
307+
})
263308
}
264309

265310
/// Append the commit-window `LIMIT` bind value to a parameter list, when the
@@ -302,11 +347,12 @@ fn collect_query_chart(
302347
],
303348
window,
304349
)?;
305-
if seeded.is_empty() {
350+
if seeded.commits.is_empty() {
306351
return Ok(None);
307352
}
353+
let history = seeded.history;
308354
let mut acc = SeriesAccumulator::new();
309-
acc.seed_commits(seeded);
355+
acc.seed_commits(seeded.commits);
310356

311357
let sql = format!(
312358
r#"
@@ -359,7 +405,7 @@ fn collect_query_chart(
359405
name.push_str(sf);
360406
}
361407
name.push_str(&format!(" Q{query_idx} [{storage}]"));
362-
Ok(Some(acc.finish(name, UnitKind::TimeNs)))
408+
Ok(Some(acc.finish(name, UnitKind::TimeNs, history)))
363409
}
364410

365411
fn collect_compression_time_chart(
@@ -381,11 +427,12 @@ fn collect_compression_time_chart(
381427
],
382428
window,
383429
)?;
384-
if seeded.is_empty() {
430+
if seeded.commits.is_empty() {
385431
return Ok(None);
386432
}
433+
let history = seeded.history;
387434
let mut acc = SeriesAccumulator::new();
388-
acc.seed_commits(seeded);
435+
acc.seed_commits(seeded.commits);
389436

390437
let sql = format!(
391438
r#"
@@ -427,7 +474,7 @@ fn collect_compression_time_chart(
427474
name.push('/');
428475
name.push_str(v);
429476
}
430-
Ok(Some(acc.finish(name, UnitKind::TimeNs)))
477+
Ok(Some(acc.finish(name, UnitKind::TimeNs, history)))
431478
}
432479

433480
fn collect_compression_size_chart(
@@ -449,11 +496,12 @@ fn collect_compression_size_chart(
449496
],
450497
window,
451498
)?;
452-
if seeded.is_empty() {
499+
if seeded.commits.is_empty() {
453500
return Ok(None);
454501
}
502+
let history = seeded.history;
455503
let mut acc = SeriesAccumulator::new();
456-
acc.seed_commits(seeded);
504+
acc.seed_commits(seeded.commits);
457505

458506
let sql = format!(
459507
r#"
@@ -493,7 +541,7 @@ fn collect_compression_size_chart(
493541
name.push('/');
494542
name.push_str(v);
495543
}
496-
Ok(Some(acc.finish(name, UnitKind::Bytes)))
544+
Ok(Some(acc.finish(name, UnitKind::Bytes, history)))
497545
}
498546

499547
fn collect_random_access_chart(
@@ -510,11 +558,12 @@ fn collect_random_access_chart(
510558
vec![Box::new(dataset.to_string())],
511559
window,
512560
)?;
513-
if seeded.is_empty() {
561+
if seeded.commits.is_empty() {
514562
return Ok(None);
515563
}
564+
let history = seeded.history;
516565
let mut acc = SeriesAccumulator::new();
517-
acc.seed_commits(seeded);
566+
acc.seed_commits(seeded.commits);
518567

519568
let sql = format!(
520569
r#"
@@ -545,7 +594,11 @@ fn collect_random_access_chart(
545594
acc.record(&format, idx, value_ns as f64);
546595
acc.tag(&format, None, Some(&format));
547596
}
548-
Ok(Some(acc.finish(dataset.to_string(), UnitKind::TimeNs)))
597+
Ok(Some(acc.finish(
598+
dataset.to_string(),
599+
UnitKind::TimeNs,
600+
history,
601+
)))
549602
}
550603

551604
fn collect_vector_search_chart(
@@ -570,11 +623,12 @@ fn collect_vector_search_chart(
570623
],
571624
window,
572625
)?;
573-
if seeded.is_empty() {
626+
if seeded.commits.is_empty() {
574627
return Ok(None);
575628
}
629+
let history = seeded.history;
576630
let mut acc = SeriesAccumulator::new();
577-
acc.seed_commits(seeded);
631+
acc.seed_commits(seeded.commits);
578632

579633
let sql = format!(
580634
r#"
@@ -613,5 +667,6 @@ fn collect_vector_search_chart(
613667
Ok(Some(acc.finish(
614668
format!("{dataset} / {layout} (threshold={threshold})"),
615669
UnitKind::TimeNs,
670+
history,
616671
)))
617672
}

benchmarks-website/server/src/api/dto.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ pub struct ChartResponse {
228228
/// time values around 1e6 ns) so the rendered axis stays readable. The
229229
/// taxonomy is small on purpose — see [`UnitKind`].
230230
pub unit_kind: UnitKind,
231-
/// Every commit that has at least one rendered data point, oldest first.
231+
/// Full-history placement of this payload's bounded `commits` window.
232+
pub history: ChartHistory,
233+
/// Every loaded commit in this payload, oldest first.
232234
pub commits: Vec<CommitPoint>,
233235
/// Per-series value arrays, indexed in lockstep with `commits`.
234236
pub series: serde_json::Map<String, JsonValue>,
@@ -241,6 +243,20 @@ pub struct ChartResponse {
241243
pub series_meta: BTreeMap<String, SeriesTag>,
242244
}
243245

246+
/// Placement metadata for a possibly bounded chart payload.
247+
#[derive(Debug, Clone, Serialize)]
248+
pub struct ChartHistory {
249+
/// Number of commits in this chart's full x-axis after the benchmark's
250+
/// first data point.
251+
pub total_commits: usize,
252+
/// Index in the full x-axis where `commits[0]` belongs.
253+
pub start_index: usize,
254+
/// Number of commits loaded into this payload.
255+
pub loaded_commits: usize,
256+
/// True when this payload covers the full x-axis.
257+
pub complete: bool,
258+
}
259+
244260
/// Structured y-axis unit taxonomy carried on every [`ChartResponse`]. The
245261
/// client uses this — together with the magnitude of the values currently in
246262
/// view — to pick a display unit (e.g. `ms` for `time_ns` values around

benchmarks-website/server/src/api/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use duckdb::Connection;
3939

4040
pub(crate) use self::charts::chart_payload;
4141
pub(crate) use self::charts::collect_group_charts;
42+
pub use self::dto::ChartHistory;
4243
pub use self::dto::ChartLink;
4344
pub use self::dto::ChartResponse;
4445
pub use self::dto::CommitPoint;

benchmarks-website/server/src/api/window.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl CommitWindow {
6565
Self::All => "",
6666
Self::Last(_) => {
6767
" AND c.commit_sha IN \
68-
(SELECT commit_sha FROM commits ORDER BY timestamp DESC LIMIT ?)"
68+
(SELECT commit_sha FROM commits ORDER BY timestamp DESC, commit_sha DESC LIMIT ?)"
6969
}
7070
}
7171
}

benchmarks-website/server/src/query_cache.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,12 @@ mod tests {
371371
ChartResponse {
372372
display_name,
373373
unit_kind: crate::api::UnitKind::TimeNs,
374+
history: crate::api::ChartHistory {
375+
total_commits: 0,
376+
start_index: 0,
377+
loaded_commits: 0,
378+
complete: true,
379+
},
374380
commits: Vec::new(),
375381
series: serde_json::Map::new(),
376382
series_meta: std::collections::BTreeMap::new(),

0 commit comments

Comments
 (0)