blob: 289379f4b08d3c2ecf80ce1537d9370545e2ff79 [file] [log] [blame]
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library protoc.benchmark.dashboard_model;
import 'generated/benchmark.pb.dart' as pb;
import 'benchmark.dart' show Benchmark;
import 'benchmarks/index.dart' show createBenchmark;
/// Contains the viewable state of the dashboard. (Immutable.)
class DashboardModel {
final Map<String, pb.Report> savedReports;
final Table table;
final pb.Report latest;
DashboardModel(this.savedReports, this.table, this.latest);
DashboardModel withBaseline(String name) {
var nextTable = table.withBaseline(name, savedReports[name]);
return new DashboardModel(savedReports, nextTable, latest);
DashboardModel withReport(pb.Report right) =>
new DashboardModel(savedReports, table, right);
DashboardModel withTable(Table table) =>
new DashboardModel(savedReports, table, latest);
/// Returns true if the Run button should be enabled.
bool get canRun => !latest.hasStatus() || latest.status != pb.Status.RUNNING;
/// The parts of the benchmark results table that don't change often.
class Table {
final pb.Suite suite;
final String baseline;
final pb.Report report;
final Set<pb.Request> selections;
final rows = <Row>[];
factory Table(pb.Suite suite) => new Table._raw(
suite, null, null, new Set<pb.Request>.from(suite.requests));
Table._raw(this.suite, this.baseline,, this.selections) {
Iterator it = report == null ? [].iterator : report.responses.iterator;
for (var r in suite.requests) {
var b = createBenchmark(r);
pb.Sample baseline;
if (it.moveNext()) {
baseline = b.medianSample(it.current);
rows.add(new Row(r, b, baseline, selected: this.selections.contains(r)));
Table withBaseline(String baseline, pb.Report report) =>
new Table._raw(suite, baseline, report, selections);
Table withAllSelected() {
return new Table._raw(
suite, baseline, report, new Set<pb.Request>.from(suite.requests));
Table withNoneSelected() {
return new Table._raw(suite, baseline, report, new Set<pb.Request>());
Table withSelection(pb.Request request, bool selected) {
var s = new Set<pb.Request>.from(selections);
if (selected) {
} else {
return new Table._raw(suite, baseline, report, s);
/// The parts of a row in the benchmark results table that don't change often.
class Row {
final pb.Request request;
final Benchmark benchmark;
final pb.Sample baseline;
final bool selected;
Row(this.request, this.benchmark, this.baseline, {this.selected = true});
/// Returns the response that should be displayed in this row.
pb.Response findResponse(pb.Report r) {
for (var candidate in r.responses) {
if (candidate.request == request) return candidate;
return null;
// Indicates that the given item was added or removed from a selection.
class SelectEvent<T> {
final bool selected;
final T item;
SelectEvent(this.selected, [this.item]);
toString() => "SelectEvent($selected, $item)";