<h1>{{lang_benchmark}}</h1>
<h2>{{lang_benchmarkResult}}</h2>
{{#remaining}}
<div class="alert alert-info">
{{lang_benchmarkSecondsReminaing}}: <span id="remaining-seconds">{{remaining}}</span>
</div>
{{/remaining}}
<div id="graphs"></div>
<div id="errors"></div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var result = {{{result}}};
var clients = {{{wanted}}};
var graphs = {};
function formatBytes(val) {
return Math.floor(val / 1024 / 1024) + "\u2009MiB/s";
}
function renderX(val, index) {
return Math.floor(val / 1000) + '\u2009s';
}
function makeGraph(typeKey, resourceKey, caption) {
var uuid;
var ds = [];
var gmin = 0, rmax = 0;
var colors = [];
var cnt = 0;
for (uuid in result) {
if (!result[uuid][typeKey]) {
delete result[uuid];
continue;
}
if (gmin === 0 || result[uuid][typeKey].start < gmin) {
gmin = result[uuid][typeKey].start;
}
cnt++;
}
if (cnt === 1) {
colors.push('rgb(0, 128, 0)');
} else {
for (i = 0; i < cnt; ++i) {
colors.push('rgb(0, 128, ' + (i / (cnt - 1)) * 255 + ')');
}
}
var v, i, o, idx;
var sums = [];
for (uuid in result) {
o = result[uuid][typeKey].start - gmin; // Adjust according to earliest client
v = result[uuid][typeKey].values[resourceKey];
for (i = 0; i < v.length; ++i) {
v[i].x += o;
if (cnt > 1) {
idx = Math.round(v[i].x / 250);
if (sums[idx]) {
sums[idx] += v[i].y | 0;
} else {
sums[idx] = v[i].y | 0;
}
}
}
if (v[v.length-1].x > rmax) rmax = v[v.length-1].x; // Get max value
ds.push({data: v, label: result[uuid].name, borderColor: colors[ds.length], fill: false});
}
if (cnt > 1) {
ds.push({data: sums, label: 'Sum', borderColor: '#c00'});
}
if (!graphs[typeKey]) {
var $e = $('#graphs');
var $c = $('<canvas style="width:100%;height:250px">');
$e.append($('<h3>').text(caption));
$e.append($c);
var ls = [];
for (i = 0; i <= rmax; i += 250) ls.push(i); // Generate steps for graph
graphs[typeKey] = new Chart($c[0].getContext('2d'), {data: {datasets: ds, labels: ls}, type: 'scatter', options: {
animation: false,
responsive: true,
borderWidth: 2,
pointBorderWidth: 0,
showLine: true,
scales: { y: { ticks: { callback: formatBytes }}, x: { ticks: { callback: renderX }, max: rmax } },
plugins: {
tooltip: { callbacks: { label: function(context) {
if (context.parsed.y !== null) {
return context.dataset.label + ": " + formatBytes(context.parsed.y);
}
return context.dataset.label;
}
}},
legend: { position: 'left'}
}
}});
} else {
graphs[typeKey].data.datasets = ds;
graphs[typeKey].update();
}
}
var $err = $('#errors');
for (var uuid in result) {
if (result[uuid].stdout || result[uuid].stderr) {
var $frame = $('<div class="panel panel-body">');
$frame.append($('<h5>').text(result[uuid].name));
if (result[uuid].stdout) {
$frame.append($('<label>').text('stdout'));
$frame.append($('<pre>').text(result[uuid].stdout));
}
if (result[uuid].stderr) {
$frame.append($('<label>').text('stderr'));
$frame.append($('<pre>').text(result[uuid].stderr));
}
$err.append($frame);
}
}
makeGraph('SEQ', 'net', 'Sequential Reads');
makeGraph('RND', 'net', 'Random 1M');
{{#refresh}}
setTimeout(function() {
window.location.reload();
}, {{refresh}} * 1000);
{{#remaining}}
var remaining = {{remaining}};
function updateRemainingCounter() {
if (remaining > 0) {
setTimeout(updateRemainingCounter, 1000);
} else {
window.location.reload();
}
$('#remaining-seconds').text(remaining--);
}
updateRemainingCounter();
{{/remaining}}
{{/refresh}}
});
</script>