blob: 5dac33acfcd081ab253f22c0f76bf7369de68a24 [file] [log] [blame]
// Copyright (c) 2024, the R8 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.
import chart from "./chart.js";
import dom from "./dom.js";
import url from "./url.js";
var commits = null;
const benchmarks = new Set();
const selectedBenchmarks = new Set();
const legends = new Set();
const selectedLegends = new Set();
const zoom = { left: -1, right: -1 };
function forEachBenchmark(callback) {
for (const benchmark of benchmarks.values()) {
callback(benchmark, selectedBenchmarks.has(benchmark));
}
}
function forEachSelectedBenchmark(callback) {
forEachBenchmark((benchmark, selected) => {
if (selected) {
callback(benchmark);
}
});
}
function getCommit(index, zoom) {
return getCommits(zoom)[index];
}
function getCommitFromContext(context) {
const elementInfo = context[0];
var commit;
if (elementInfo.dataset.type == 'line') {
commit = getCommit(elementInfo.dataIndex, zoom);
} else {
console.assert(elementInfo.dataset.type == 'scatter');
commit = getCommit(elementInfo.raw.x, null);
}
return commit;
}
function getCommitDescriptionFromContext(context) {
const commit = getCommitFromContext(context);
const elementInfo = context[0];
const dataset = chart.get().data.datasets[elementInfo.datasetIndex];
return `App: ${dataset.benchmark}\n`
+ `Author: ${commit.author}\n`
+ `Submitted: ${new Date(commit.submitted * 1000).toLocaleString()}\n`
+ `Hash: ${commit.hash}\n`
+ `Index: ${commit.index}`;
}
function getCommits(zoom) {
const commitsForSelectedBranch = commits.filter(commit => dom.isCommitSelected(commit));
if (zoom) {
return commitsForSelectedBranch.slice(zoom.left, zoom.right);
}
return commitsForSelectedBranch;
}
function getTryCommitsByParentHash(loadedTryCommits) {
const result = {};
for (var i = 0; i < loadedTryCommits.length; i++) {
const commit = loadedTryCommits[i];
const parentHash = commit["parent_hash"];
if (parentHash in result) {
result[parentHash].push(commit);
} else {
result[parentHash] = [commit];
}
}
return result;
}
function hasLegend(legend) {
return legends.has(legend);
}
function importCommits(url, tryUrl = null) {
const promises = [import(url, { with: { type: "json" }})];
if (tryUrl !== null) {
promises.push(import(tryUrl, { with: { type: "json" }}));
}
return Promise.all(promises).then(values => {
const loadedCommits = values[0].default;
const loadedTryCommits = values.length > 1 ? values[1].default : [];
const loadedTryCommitsByParentHash =
getTryCommitsByParentHash(loadedTryCommits);
// Amend the commits with their unique index.
var mainIndex = 0;
var releaseIndex = 0;
const processedCommits = []
for (var i = loadedCommits.length - 1; i >= 0; i--) {
const commit = loadedCommits[i];
commit.index = commit.version ? releaseIndex++ : mainIndex++;
processedCommits.push(commit);
// Include the try commits for this commit on main.
const hash = commit["hash"];
if (hash in loadedTryCommitsByParentHash) {
console.assert(!commit.version, "Try jobs for release not supported");
const tryCommitsForCurrentCommit = loadedTryCommitsByParentHash[hash];
for (var j = 0; j < tryCommitsForCurrentCommit.length; j++) {
const tryCommitForCurrentCommit = tryCommitsForCurrentCommit[j];
tryCommitForCurrentCommit.index = mainIndex++;
}
processedCommits.push(...tryCommitsForCurrentCommit);
}
}
commits = processedCommits;
return processedCommits;
});
}
function initializeBenchmarks() {
for (const commit of commits.values()) {
for (const benchmark in commit.benchmarks) {
benchmarks.add(benchmark);
}
}
for (const benchmark of benchmarks.values()) {
if (url.matches(benchmark)) {
selectedBenchmarks.add(benchmark);
}
}
if (selectedBenchmarks.size == 0) {
const randomBenchmarkIndex = Math.floor(Math.random() * benchmarks.size);
const randomBenchmark = Array.from(benchmarks)[randomBenchmarkIndex];
selectedBenchmarks.add(randomBenchmark);
}
}
function initializeLegends(legendsInfo) {
for (var legend in legendsInfo) {
legends.add(legend);
if (url.contains(legend)) {
selectedLegends.add(legend);
}
}
if (selectedLegends.size == 0) {
for (let [legend, legendInfo] of Object.entries(legendsInfo)) {
if (legendInfo.default) {
selectedLegends.add(legend);
}
}
}
}
function initializeZoom() {
const filteredCommits = resetZoom();
for (const urlOption of url.values()) {
if (urlOption.startsWith('L')) {
var left = parseInt(urlOption.substring(1));
if (isNaN(left)) {
continue;
}
left = left >= 0 ? left : filteredCommits.length + left;
if (left < 0) {
zoom.left = 0;
} else if (left >= filteredCommits.length) {
zoom.left = filteredCommits.length - 1;
} else {
zoom.left = left;
}
}
}
}
function resetZoom() {
const filteredCommits = getCommits(null);
zoom.left = Math.max(0, filteredCommits.length - 75);
zoom.right = filteredCommits.length;
return filteredCommits;
}
function handleKeyDownEvent(e, callback) {
if (selectedBenchmarks.size != 1) {
return;
}
const [selectedBenchmark] = selectedBenchmarks;
var benchmarkToSelect = null;
var previousBenchmark = null;
for (const benchmark of benchmarks.values()) {
if (previousBenchmark != null) {
if (e.key == 'ArrowLeft' && benchmark == selectedBenchmark) {
benchmarkToSelect = previousBenchmark;
break;
} else if (e.key === 'ArrowRight' && previousBenchmark == selectedBenchmark) {
benchmarkToSelect = benchmark;
break;
}
}
previousBenchmark = benchmark;
}
if (benchmarkToSelect != null) {
selectedBenchmarks.clear();
selectedBenchmarks.add(benchmarkToSelect);
document.getElementById(selectedBenchmark).checked = false;
document.getElementById(benchmarkToSelect).checked = true;
callback();
}
}
function isLegendSelected(legend) {
return selectedLegends.has(legend);
}
export default {
benchmarks: benchmarks,
commits: getCommits,
legends: legends,
selectedBenchmarks: selectedBenchmarks,
selectedLegends: selectedLegends,
forEachBenchmark: forEachBenchmark,
forEachSelectedBenchmark: forEachSelectedBenchmark,
getCommit: getCommit,
getCommitFromContext: getCommitFromContext,
getCommitDescriptionFromContext: getCommitDescriptionFromContext,
handleKeyDownEvent: handleKeyDownEvent,
hasLegend: hasLegend,
initializeBenchmarks: initializeBenchmarks,
initializeLegends: initializeLegends,
initializeZoom: initializeZoom,
importCommits: importCommits,
isLegendSelected: isLegendSelected,
resetZoom: resetZoom,
zoom: zoom
};