<!DOCTYPE html>
<!--
Copyright (c) 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/tracing/metrics/metric_registry.html">
<link rel="import" href="/tracing/metrics/system_health/long_tasks_metric.html">
<link rel="import" href="/tracing/value/numeric.html">

<script>
'use strict';

tr.exportTo('tr.metrics.sh', function() {
  // The following math is easier if the units are seconds rather than ms,
  // so durations will be converted from ms to s.
  var MS_PER_S = 1000;

  // https://www.desmos.com/calculator/ysabhcc42g
  var RESPONSE_RISK =
    tr.b.Statistics.LogNormalDistribution.fromMedianAndDiminishingReturns(
      100 / MS_PER_S, 50 / MS_PER_S);

  /**
   * This helper function computes the risk that a task of the given duration
   * would impact the responsiveness of a speculative input.
   *
   * @param {number} durationMs
   * @return {number} task hazard
   */
  function computeResponsivenessRisk(durationMs) {
    // Returns 0 when the risk of impacting responsiveness is minimal.
    // Returns 1 when it is maximal.
    // durationMs is the duration of a long task.
    // It is at least LONG_TASK_MS.
    // The FAST_RESPONSE_HISTOGRAM was designed to permit both a 50ms task
    // when a Scroll Response begins, plus 16ms latency between the task
    // and the first frame of the scroll, without impacting the responsiveness
    // score.
    // Add 16ms to durationMs to simulate the standard (maximum ideal) scroll
    // response latency, and use the FAST_RESPONSE_HISTOGRAM to punish every ms
    // that the long task exceeds LONG_TASK_MS.

    durationMs += 16;

    // This returns a normalized percentage that
    // represents the fraction of users that would be satisfied with a
    // Scroll Response that takes durationMs to respond.
    // The risk of impacting responsiveness is approximated as the long task's
    // impact on a hypothetical Scroll Response that starts when the long task
    // starts, and then takes the standard 16ms to respond after the long task
    // finishes.
    // We imagine a Scroll Response instead of a Load or another type of
    // Response because the Scroll Response carries the strictest expectation.
    // The risk of impacting responsiveness is framed as the fraction of users
    // that would be *un*satisifed with the responsiveness of that hypothetical
    // Scroll Response. The fraction of users who are unsatisfied with something
    // is equal to 1 - the fraction of users who are satisfied with it.
    return RESPONSE_RISK.computePercentile(durationMs / MS_PER_S);
  }

  /**
   * This weighting function is similar to tr.metrics.sh.perceptualBlend,
   * but this version is appropriate for SmallerIsBetter metrics, whereas
   * that version is for BiggerIsBetter metrics.
   * (This would not be necessary if hazard were reframed as a BiggerIsBetter
   * metric such as "input readiness".)
   * Also, that version assumes that the 'ary' will be UserExpectations, whereas
   * this version assumes that the 'ary' will be scores.
   *
   * @param {number} hazardScore
   * @return {number} weight
   */
  function perceptualBlendSmallerIsBetter(hazardScore) {
    return Math.exp(hazardScore);
  }

  /**
   * Compute and return the normalized score for the risk that a speculative
   * input's responsiveness would have been impacted by long tasks on the given
   * thread in the given range.
   *
   * @param {tr.model.Thread} thread
   * @param {tr.b.Range=} opt_range
   * @return {number} hazard
   */
  function computeHazardForLongTasksInRangeOnThread(thread, opt_range) {
    var taskHazardScores = [];
    tr.metrics.sh.iterateLongTopLevelTasksOnThreadInRange(
        thread, opt_range, function(task) {
      taskHazardScores.push(computeResponsivenessRisk(task.duration));
    });
    return tr.b.Statistics.weightedMean(
        taskHazardScores, perceptualBlendSmallerIsBetter);
  }

  /**
   * Compute and return the normalized score for the risk that a speculative
   * input's responsiveness would have been impacted by long tasks.
   *
   * @param {tr.model.Model} model The model.
   * @return {number} hazard
   */
  function computeHazardForLongTasks(model) {
    var threadHazardScores = [];
    tr.metrics.sh.iterateRendererMainThreads(model, function(thread) {
      threadHazardScores.push(computeHazardForLongTasksInRangeOnThread(
          thread));
    });
    return tr.b.Statistics.weightedMean(
        threadHazardScores, perceptualBlendSmallerIsBetter);
  }

  /**
   * This EXPERIMENTAL metric computes a scalar normalized score that
   * represents the risk that a speculative input's responsiveness would have
   * been impacted by long tasks.
   * This metric requires only the 'toplevel' tracing category.
   */
  function hazardMetric(values, model) {
    var overallHazard = computeHazardForLongTasks(model);
    if (overallHazard === undefined)
      overallHazard = 0;

    var hist = new tr.v.Histogram('hazard',
        tr.b.Unit.byName.normalizedPercentage_smallerIsBetter);
    hist.addSample(overallHazard);
    values.addHistogram(hist);
  }

  tr.metrics.MetricRegistry.register(hazardMetric);

  return {
    hazardMetric: hazardMetric,
    computeHazardForLongTasksInRangeOnThread:
      computeHazardForLongTasksInRangeOnThread,
    computeHazardForLongTasks: computeHazardForLongTasks,
    computeResponsivenessRisk: computeResponsivenessRisk
  };
});
</script>
