<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>R8 perf</title>
  <link rel="stylesheet" href="stylesheet.css">
</head>
<body>
  <div id="benchmark-selectors"></div>
  <div>
      <canvas id="myChart"></canvas>
  </div>
  <div>
    <div style="float: left; width: 50%">
      <button type="button" id="show-more-left" disabled>⇐</button>
      <button type="button" id="show-less-left">⇒</button>
    </div>
    <div style="float: left; text-align: right; width: 50%">
      <button type="button" id="show-less-right">⇐</button>
      <button type="button" id="show-more-right" disabled>⇒</button>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.3/dist/chart.umd.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0"></script>
  <script type="module">
    // Utility methods.
    Array.prototype.any = function(predicate) {
      for (const element of this.values()) {
        if (predicate(element)) {
          return true;
        }
      }
      return false;
    };
    Array.prototype.first = function() {
      return this[0];
    };
    Array.prototype.avg = function() {
      return this.reduce(function(x, y) { return x + y; }, 0) / this.length;
    };
    Array.prototype.min = function() {
      return this.reduce(function(x, y) { return x === null ? y : Math.min(x, y); }, null);
    };
    Array.prototype.reverseInPlace = function() {
      for (var i = 0; i < Math.floor(this.length / 2); i++) {
        var temp = this[i];
        this[i] = this[this.length - i - 1];
        this[this.length - i - 1] = temp;
      }
    };
    Number.prototype.ns_to_s = function() {
      const seconds = this/10E8;
      const seconds_with_one_decimal = Math.round(seconds*10)/10;
      return seconds;
    };

    // Import and reverse commits so that newest are last.
    import commits from "./benchmark_data.json" with { type: "json" };
    commits.reverseInPlace();

    // Amend the commits with their unique index.
    for (var i = 0; i < commits.length; i++) {
      commits[i].index = i;
    }

    // DOM references.
    const benchmarkSelectors = document.getElementById('benchmark-selectors');
    const canvas = document.getElementById('myChart');
    const showMoreLeft = document.getElementById('show-more-left');
    const showLessLeft = document.getElementById('show-less-left');
    const showLessRight = document.getElementById('show-less-right');
    const showMoreRight = document.getElementById('show-more-right');

    // Initialize benchmark selectors.
    const benchmarks = new Set();
    for (const commit of commits.values()) {
      for (const benchmark in commit.benchmarks) {
          benchmarks.add(benchmark);
      }
    }
    const selectedBenchmarks = new Set();
    const urlOptions = unescape(window.location.hash.substring(1)).split(',');
    for (const benchmark of benchmarks.values()) {
      for (const filter of urlOptions.values()) {
        if (filter) {
          const match = benchmark.match(new RegExp(filter.replace("*", ".*")));
          if (match) {
            selectedBenchmarks.add(benchmark);
            break;
          }
        }
      }
    }
    if (selectedBenchmarks.size == 0) {
      const randomBenchmarkIndex = Math.floor(Math.random() * benchmarks.size);
      const randomBenchmark = Array.from(benchmarks)[randomBenchmarkIndex];
      selectedBenchmarks.add(randomBenchmark);
    }
    for (const benchmark of benchmarks.values()) {
      const input = document.createElement('input');
      input.type = 'checkbox';
      input.name = 'benchmark';
      input.id = benchmark;
      input.value = benchmark;
      input.checked = selectedBenchmarks.has(benchmark);
      input.onchange = function (e) {
        if (e.target.checked) {
          selectedBenchmarks.add(e.target.value);
        } else {
          selectedBenchmarks.delete(e.target.value);
        }
        updateChart(true, false);
      };

      const label = document.createElement('label');
      label.id = benchmark + 'Label';
      label.htmlFor = benchmark;
      label.innerHTML = benchmark;

      benchmarkSelectors.appendChild(input);
      benchmarkSelectors.appendChild(label);
    }

    function getSingleResult(benchmark, commit, resultName, resultIteration = 0) {
      if (!(benchmark in commit.benchmarks)) {
        return NaN;
      }
      const allResults = commit.benchmarks[benchmark].results;
      const resultsForIteration = allResults[resultIteration];
      // If a given iteration does not declare a result, then the result
      // was the same as the first run.
      if (resultIteration > 0 && !(resultName in resultsForIteration)) {
        return allResults.first()[resultName];
      }
      return resultsForIteration[resultName];
    }

    function getAllResults(benchmark, commit, resultName) {
      const result = [];
      const allResults = commit.benchmarks[benchmark].results;
      for (var iteration = 0; iteration < allResults.length; iteration++) {
        result.push(getSingleResult(benchmark, commit, resultName, iteration));
      }
      return result;
    }

    // Chart data provider.
    function getData() {
      const filteredCommits = commits.slice(zoom.left, zoom.right);
      const labels = filteredCommits.map((c, i) => c.index);
      const datasets = [];
      for (const selectedBenchmark of selectedBenchmarks.values()) {
        const codeSizeData =
            filteredCommits.map(
                (c, i) => getSingleResult(selectedBenchmark, filteredCommits[i], "code_size"));
        const instructionCodeSizeData =
            filteredCommits.map(
                (c, i) => getSingleResult(selectedBenchmark, filteredCommits[i], "ins_code_size"));
        const composableInstructionCodeSizeData =
            filteredCommits.map(
                (c, i) => getSingleResult(selectedBenchmark, filteredCommits[i], "composable_code_size"));
        const oatCodeSizeData =
            filteredCommits.map(
                (c, i) => getSingleResult(selectedBenchmark, filteredCommits[i], "oat_code_size"));
        const codeSizeScatterData = [];
        for (const commit of filteredCommits.values()) {
          if (!(selectedBenchmark in commit.benchmarks)) {
            continue;
          }
          const seen = new Set();
          seen.add(getSingleResult(selectedBenchmark, commit, "code_size"));
          const codeSizes = getAllResults(selectedBenchmark, commit, "code_size")
          for (const codeSize of codeSizes.values()) {
            if (!seen.has(codeSize)) {
              codeSizeScatterData.push({ x: commit.index, y: codeSize });
              seen.add(codeSize);
            }
          }
        }
        const runtimeData =
            filteredCommits.map(
                (c, i) =>
                    selectedBenchmark in filteredCommits[i].benchmarks
                        ? getAllResults(selectedBenchmark, filteredCommits[i], "runtime")
                            .min()
                            .ns_to_s()
                        : NaN);
        const runtimeScatterData = [];
        for (const commit of filteredCommits.values()) {
          if (!(selectedBenchmark in commit.benchmarks)) {
            continue;
          }
          const runtimes = getAllResults(selectedBenchmark, commit, "runtime")
          for (const runtime of runtimes.values()) {
            runtimeScatterData.push({ x: commit.index, y: runtime.ns_to_s() });
          }
        }

        const skipped = (ctx, value) => ctx.p0.skip || ctx.p1.skip ? value : undefined;
        datasets.push(...[
          {
            benchmark: selectedBenchmark,
            type: 'line',
            label: 'Dex size',
            data: codeSizeData,
            datalabels: {
              align: 'end',
              anchor: 'end'
            },
            tension: 0.1,
            yAxisID: 'y',
            segment: {
              borderColor: ctx =>
                  skipped(
                      ctx,
                      myChart
                          ? myChart.data.datasets[ctx.datasetIndex].backgroundColor
                          : undefined),
              borderDash: ctx => skipped(ctx, [6, 6]),
            },
            spanGaps: true
          },
          {
            benchmark: selectedBenchmark,
            type: 'line',
            label: 'Instruction size',
            data: instructionCodeSizeData,
            datalabels: {
              align: 'end',
              anchor: 'end'
            },
            tension: 0.1,
            yAxisID: 'y_ins_code_size',
            segment: {
              borderColor: ctx =>
                  skipped(
                      ctx,
                      myChart
                          ? myChart.data.datasets[ctx.datasetIndex].backgroundColor
                          : undefined),
              borderDash: ctx => skipped(ctx, [6, 6]),
            },
            spanGaps: true
          },
          {
            benchmark: selectedBenchmark,
            type: 'line',
            label: 'Composable size',
            data: composableInstructionCodeSizeData,
            datalabels: {
              align: 'start',
              anchor: 'start'
            },
            tension: 0.1,
            yAxisID: 'y_ins_code_size',
            segment: {
              borderColor: ctx =>
                  skipped(
                      ctx,
                      myChart
                          ? myChart.data.datasets[ctx.datasetIndex].backgroundColor
                          : undefined),
              borderDash: ctx => skipped(ctx, [6, 6]),
            },
            spanGaps: true
          },
          {
            benchmark: selectedBenchmark,
            type: 'line',
            label: 'Oat size',
            data: oatCodeSizeData,
            datalabels: {
              align: 'start',
              anchor: 'start'
            },
            tension: 0.1,
            yAxisID: 'y_oat_code_size',
            segment: {
              borderColor: ctx =>
                  skipped(
                      ctx,
                      myChart
                          ? myChart.data.datasets[ctx.datasetIndex].backgroundColor
                          : undefined),
              borderDash: ctx => skipped(ctx, [6, 6]),
            },
            spanGaps: true
          },
          {
            benchmark: selectedBenchmark,
            type: 'scatter',
            label: 'Nondeterminism',
            data: codeSizeScatterData,
            datalabels: {
              labels: {
                value: null
              }
            },
            radius: 6,
            pointBackgroundColor: 'red'
          },
          {
            benchmark: selectedBenchmark,
            type: 'line',
            label: 'Runtime',
            data: runtimeData,
            datalabels: {
              labels: {
                value: null
              }
            },
            tension: 0.1,
            yAxisID: 'y_runtime',
            segment: {
              borderColor: ctx =>
                  skipped(
                      ctx,
                      myChart
                          ? myChart.data.datasets[ctx.datasetIndex].backgroundColor
                          : undefined),
              borderDash: ctx => skipped(ctx, [6, 6]),
            },
            spanGaps: true
          },
          {
            benchmark: selectedBenchmark,
            type: 'scatter',
            label: 'Runtime variance',
            data: runtimeScatterData,
            datalabels: {
              labels: {
                value: null
              }
            },
            yAxisID: 'y_runtime'
          }
        ]);
      }

      return {
        labels: labels,
        datasets: datasets,
      };
    }

    // Legend tracking.
    const legends =
        new Set(['Dex size', 'Instruction size', 'Composable size', 'Oat size', 'Nondeterminism', 'Runtime', 'Runtime variance']);
    const selectedLegends =
        new Set(
              unescape(window.location.hash.substring(1))
                  .split(',')
                  .filter(l => legends.has(l)));
    if (selectedLegends.size == 0) {
      legends.forEach(l => selectedLegends.add(l));
      selectedLegends.delete('Runtime variance')
    }

    function getDataPercentageChange(context) {
      var i = context.dataIndex;
      var value = context.dataset.data[i];
      var j = i;
      var previousValue;
      do {
        if (j == 0) {
          return null;
        }
        previousValue = context.dataset.data[--j];
      } while (previousValue === undefined || isNaN(previousValue));
      return (value - previousValue) / previousValue * 100;
    }

    // Chart options.
    const options = {
      onHover: (event, chartElement) =>
          event.native.target.style.cursor =
              chartElement[0] ? 'pointer' : 'default',
      plugins: {
        datalabels: {
          backgroundColor: 'rgba(255, 255, 255, 0.7)',
          borderColor: 'rgba(128, 128, 128, 0.7)',
          borderRadius: 4,
          borderWidth: 1,
          color: context => getDataPercentageChange(context) < 0 ? 'green' : 'red',
          display: context => {
            var percentageChange = getDataPercentageChange(context);
            return percentageChange !== null && Math.abs(percentageChange) >= 0.1;
          },
          font: {
            size: 20,
            weight: 'bold'
          },
          offset: 8,
          formatter: (value, context) => {
            var percentageChange = getDataPercentageChange(context);
            var percentageChangeTwoDecimals = Math.round(percentageChange * 100) / 100;
            var glyph = percentageChange < 0 ? '▼' : '▲';
            return glyph + ' ' + percentageChangeTwoDecimals + '%';
          },
          padding: 6
        },
        legend: {
          labels: {
            filter: (legendItem, data) => {
              // Only retain the legends for the first selected benchmark. If
              // multiple benchmarks are selected, then use the legends of the
              // first selected benchmark to control all selected benchmarks.
              const numUniqueLegends =
                  data.datasets.length / selectedBenchmarks.size;
              return legendItem.datasetIndex < numUniqueLegends;
            },
          },
          onClick: (e, legendItem, legend) => {
            const clickedLegend = legendItem.text;
            if (selectedLegends.has(clickedLegend)) {
              selectedLegends.delete(clickedLegend);
            } else {
              selectedLegends.add(clickedLegend);
            }
            updateChart(false, true);
          },
        },
        tooltip: {
          callbacks: {
            title: context => {
              const elementInfo = context[0];
              var commit;
              if (elementInfo.dataset.type == 'line') {
                commit = commits[zoom.left + elementInfo.dataIndex];
              } else {
                console.assert(elementInfo.dataset.type == 'scatter');
                commit = commits[elementInfo.raw.x];
              }
              return commit.title;
            },
            footer: context => {
              const elementInfo = context[0];
              var commit;
              if (elementInfo.dataset.type == 'line') {
                commit = commits[zoom.left + elementInfo.dataIndex];
              } else {
                console.assert(elementInfo.dataset.type == 'scatter');
                commit = commits[elementInfo.raw.x];
              }
              const dataset = myChart.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}`;
            }
          }
        }
      },
      responsive: true,
      scales: {
        x: {},
        y: {
          position: 'left',
          title: {
            display: true,
            text: 'Dex size (bytes)'
          }
        },
        y_runtime: {
          position: 'right',
          title: {
            display: true,
            text: 'Runtime (seconds)'
          }
        },
        y_ins_code_size: {
          position: 'left',
          title: {
            display: true,
            text: 'Instruction size (bytes)'
          }
        },
        y_oat_code_size: {
          position: 'left',
          title: {
            display: true,
            text: 'Oat size (bytes)'
          }
        }
      }
    };

    // Setup click handler.
    canvas.onclick = event => {
      const points =
          myChart.getElementsAtEventForMode(
              event, 'nearest', { intersect: true }, true);
      if (points.length > 0) {
        const point = points[0];
        const commit = commits[point.index];
        window.open('https://r8.googlesource.com/r8/+/' + commit.hash, '_blank');
      }
    };

    // Setup chart navigation.
    var zoom = { left: Math.max(0, commits.length - 75), right: commits.length };
    for (const urlOption of urlOptions.values()) {
      if (urlOption.startsWith('L')) {
        var left = parseInt(urlOption.substring(1));
        if (isNaN(left)) {
          continue;
        }
        left = left >= 0 ? left : commits.length + left;
        if (left < 0) {
          zoom.left = 0;
        } else if (left >= commits.length) {
          zoom.left = commits.length - 1;
        } else {
          zoom.left = left;
        }
      }
    }

    showMoreLeft.onclick = event => {
      if (zoom.left == 0) {
        return;
      }
      const currentSize = zoom.right - zoom.left;
      zoom.left = zoom.left - currentSize;
      if (zoom.left < 0) {
        zoom.left = 0;
      }
      updateChart(true, false);
    };

    showLessLeft.onclick = event => {
      const currentSize = zoom.right - zoom.left;
      zoom.left = zoom.left + Math.floor(currentSize / 2);
      if (zoom.left >= zoom.right) {
        zoom.left = zoom.right - 1;
      }
      updateChart(true, false);
    };

    showLessRight.onclick = event => {
      if (zoom.right == 0) {
        return;
      }
      const currentSize = zoom.right - zoom.left;
      zoom.right = zoom.right - Math.floor(currentSize / 2);
      if (zoom.right < zoom.left) {
        zoom.right = zoom.left;
      }
      updateChart(true, false);
    };

    showMoreRight.onclick = event => {
      const currentSize = zoom.right - zoom.left;
      zoom.right = zoom.right + currentSize;
      if (zoom.right > commits.length) {
        zoom.right = commits.length;
      }
      updateChart(true, false);
    };

    function updateChart(dataChanged, legendsChanged) {
      console.assert(zoom.left <= zoom.right);

      // Update datasets.
      if (dataChanged) {
        const newData = getData();
        Object.assign(myChart.data, newData);
        // Update chart.
        myChart.update();
      }

      // Update legends.
      if (legendsChanged || (dataChanged && selectedLegends.size < legends.size)) {
        for (var datasetIndex = 0;
            datasetIndex < myChart.data.datasets.length;
            datasetIndex++) {
          const datasetMeta = myChart.getDatasetMeta(datasetIndex);
          datasetMeta.hidden = !selectedLegends.has(datasetMeta.label);
        }

        // Update scales.
        options.scales.y.display = selectedLegends.has('Dex size');
        options.scales.y_ins_code_size.display =
            selectedLegends.has('Instruction size') || selectedLegends.has('Composable size');
        options.scales.y_oat_code_size.display = selectedLegends.has('Oat size');
        options.scales.y_runtime.display =
            selectedLegends.has('Runtime') || selectedLegends.has('Runtime variance');

        // Update chart.
        myChart.update();
      }


      // Update checkbox colors.
      const benchmarkColors = {};
      for (var datasetIndex = 0;
          datasetIndex < myChart.data.datasets.length;
          datasetIndex++) {
        if (myChart.getDatasetMeta(datasetIndex).hidden) {
          continue;
        }
        const dataset = myChart.data.datasets[datasetIndex];
        const benchmark = dataset.benchmark;
        const benchmarkColor = dataset.borderColor;
        if (!(benchmark in benchmarkColors)) {
          benchmarkColors[benchmark] = benchmarkColor;
        }
      }
      for (const benchmark of benchmarks.values()) {
        const benchmarkLabel = document.getElementById(benchmark + 'Label');
        const benchmarkColor = benchmarkColors[benchmark] || '#000000';
        const benchmarkFontWeight = benchmark in benchmarkColors ? 'bold' : 'normal';
        benchmarkLabel.style.color = benchmarkColor;
        benchmarkLabel.style.fontWeight = benchmarkFontWeight;
      }

      // Update navigation.
      showMoreLeft.disabled = zoom.left == 0;
      showLessLeft.disabled = zoom.left == zoom.right - 1;
      showLessRight.disabled = zoom.left == zoom.right - 1;
      showMoreRight.disabled = zoom.right == commits.length;

      // Update hash.
      window.location.hash =
          Array.from(selectedBenchmarks)
              .concat(
                  selectedLegends.size == legends.size
                      ? []
                      : Array.from(selectedLegends))
              .join(',');
    }

    // Create chart.
    const myChart = new Chart(canvas, {
      data: getData(),
      options: options,
      plugins: [ChartDataLabels]
    });

    // Hide disabled legends.
    if (selectedLegends.size < legends.size) {
      updateChart(false, true);
    } else {
      updateChart(false, false);
    }
  </script>
</body>
</html>