<!DOCTYPE html>
<!--
Copyright 2016 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/base/iteration_helpers.html">
<link rel="import" href="/tracing/metrics/metric_registry.html">
<link rel="import" href="/tracing/value/diagnostics/diagnostic_map.html">
<link rel="import" href="/tracing/value/histogram.html">

<script>
'use strict';

tr.exportTo('tr.metrics', function() {
  var MEMORY_INFRA_TRACING_CATEGORY = 'disabled-by-default-memory-infra';

  var TIME_BOUNDARIES = tr.v.HistogramBinBoundaries.createExponential(
      1e-3, 1e5, 30);

  var BYTE_BOUNDARIES = tr.v.HistogramBinBoundaries.createExponential(
      1, 1e9, 30);

  var COUNT_BOUNDARIES = tr.v.HistogramBinBoundaries.createExponential(
      1, 1e5, 30);

  function addTimeDurationValue(valueName, duration, allValues) {
    var hist = new tr.v.Histogram(valueName,
        tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TIME_BOUNDARIES);
    hist.addSample(duration);
    allValues.addHistogram(hist);
  }

  // Adds values specific to memory-infra dumps.
  function addMemoryInfraValues(values, model, categoryNamesToTotalEventSizes) {
    var memoryDumpCount = model.globalMemoryDumps.length;
    if (memoryDumpCount === 0)
      return;

    var totalOverhead = 0;
    var nonMemoryInfraThreadOverhead = 0;
    var overheadByProvider = {};
    tr.b.iterItems(model.processes, function(pid, process) {
      tr.b.iterItems(process.threads, function(tid, thread) {
        tr.b.iterItems(thread.sliceGroup.slices, function(slice_id, slice) {
          if (slice.category !== MEMORY_INFRA_TRACING_CATEGORY)
            return;
          totalOverhead += slice.duration;
          if (thread.name !== 'MemoryInfra')
            nonMemoryInfraThreadOverhead += slice.duration;
          if (slice.args && slice.args['dump_provider.name']) {
            var providerName = slice.args['dump_provider.name'];
            var durationAndCount = overheadByProvider[providerName];
            if (durationAndCount === undefined) {
              overheadByProvider[providerName] = durationAndCount =
                  {duration: 0, count: 0};
            }
            durationAndCount.duration += slice.duration;
            durationAndCount.count++;
          }
        });
      });
    });

    addTimeDurationValue(
        'Average CPU overhead on all threads per memory-infra dump',
        totalOverhead / memoryDumpCount, values);
    addTimeDurationValue(
        'Average CPU overhead on non-memory-infra threads per memory-infra ' +
            'dump',
        nonMemoryInfraThreadOverhead / memoryDumpCount, values);
    tr.b.iterItems(overheadByProvider, function(providerName, overhead) {
      addTimeDurationValue(
          'Average CPU overhead of ' + providerName + ' per OnMemoryDump call',
          overhead.duration / overhead.count, values);
    });

    var memoryInfraEventsSize =
        categoryNamesToTotalEventSizes.get(MEMORY_INFRA_TRACING_CATEGORY);
    var memoryInfraTraceBytesValue = new tr.v.Histogram(
        'Total trace size of memory-infra dumps in bytes',
        tr.b.Unit.byName.sizeInBytes_smallerIsBetter, BYTE_BOUNDARIES);
    memoryInfraTraceBytesValue.addSample(memoryInfraEventsSize);
    values.addHistogram(memoryInfraTraceBytesValue);

    var traceBytesPerDumpValue = new tr.v.Histogram(
        'Average trace size of memory-infra dumps in bytes',
        tr.b.Unit.byName.sizeInBytes_smallerIsBetter, BYTE_BOUNDARIES);
    traceBytesPerDumpValue.addSample(memoryInfraEventsSize / memoryDumpCount);
    values.addHistogram(traceBytesPerDumpValue);
  }

  function tracingMetric(values, model) {
    if (!model.stats.hasEventSizesinBytes) {
      throw new Error('Model stats does not have event size information. ' +
                      'Please enable ImportOptions.trackDetailedModelStats.');
    }

    var eventStats = model.stats.allTraceEventStatsInTimeIntervals;
    eventStats.sort(function(a, b) {
      return a.timeInterval - b.timeInterval;
    });

    var totalTraceBytes = eventStats.reduce((a, b) =>
                                            (a + b.totalEventSizeinBytes), 0);

    // We maintain a sliding window of records [start ... end-1] where end
    // increments each time through the loop, and we move start just far enough
    // to keep the window less than 1 second wide. Note that we need to compute
    // the number of time intervals (i.e. units that timeInterval is given in)
    // in one second to know how wide the sliding window should be.
    var maxEventCountPerSec = 0;
    var maxEventBytesPerSec = 0;
    var INTERVALS_PER_SEC = Math.floor(
        1000 / model.stats.TIME_INTERVAL_SIZE_IN_MS);

    var runningEventNumPerSec = 0;
    var runningEventBytesPerSec = 0;
    var start = 0;
    var end = 0;

    while (end < eventStats.length) {
      // Slide the end marker forward. Moving the end marker from N
      // to N+1 adds eventStats[N] to the sliding window.
      runningEventNumPerSec += eventStats[end].numEvents;
      runningEventBytesPerSec += eventStats[end].totalEventSizeinBytes;
      end++;

      // Slide the start marker forward so that the time interval covered
      // by the window is less than 1 second wide.
      while ((eventStats[end - 1].timeInterval -
              eventStats[start].timeInterval) >= INTERVALS_PER_SEC) {
        runningEventNumPerSec -= eventStats[start].numEvents;
        runningEventBytesPerSec -= eventStats[start].totalEventSizeinBytes;
        start++;
      }

      // Update maximum values.
      maxEventCountPerSec = Math.max(maxEventCountPerSec,
                                     runningEventNumPerSec);
      maxEventBytesPerSec = Math.max(maxEventBytesPerSec,
                                     runningEventBytesPerSec);

    }

    var stats = model.stats.allTraceEventStats;
    var categoryNamesToTotalEventSizes = (
        stats.reduce((map, stat) => (
            map.set(stat.category,
                   ((map.get(stat.category) || 0) +
                    stat.totalEventSizeinBytes))), new Map()));

    // Determine the category with the highest total event size.
    var maxCatNameAndBytes = Array.from(
        categoryNamesToTotalEventSizes.entries()).reduce(
            (a, b) => (b[1] >= a[1]) ? b : a);
    var maxEventBytesPerCategory = maxCatNameAndBytes[1];
    var categoryWithMaxEventBytes = maxCatNameAndBytes[0];

    var maxEventCountPerSecValue = new tr.v.Histogram(
        'Max number of events per second',
      tr.b.Unit.byName.count_smallerIsBetter, COUNT_BOUNDARIES);
    maxEventCountPerSecValue.addSample(maxEventCountPerSec);

    var maxEventBytesPerSecValue = new tr.v.Histogram(
        'Max event size in bytes per second',
        tr.b.Unit.byName.sizeInBytes_smallerIsBetter, BYTE_BOUNDARIES);
    maxEventBytesPerSecValue.addSample(maxEventBytesPerSec);

    var totalTraceBytesValue = new tr.v.Histogram('Total trace size in bytes',
        tr.b.Unit.byName.sizeInBytes_smallerIsBetter, BYTE_BOUNDARIES);
    totalTraceBytesValue.addSample(totalTraceBytes);

    var biggestCategory = {
      name: categoryWithMaxEventBytes,
      size_in_bytes: maxEventBytesPerCategory
    };

    totalTraceBytesValue.diagnostics.set(
        'category_with_max_event_size', new tr.v.d.Generic(biggestCategory));
    values.addHistogram(totalTraceBytesValue);

    maxEventCountPerSecValue.diagnostics.set(
        'category_with_max_event_size', new tr.v.d.Generic(biggestCategory));
    values.addHistogram(maxEventCountPerSecValue);

    maxEventBytesPerSecValue.diagnostics.set(
        'category_with_max_event_size', new tr.v.d.Generic(biggestCategory));
    values.addHistogram(maxEventBytesPerSecValue);

    addMemoryInfraValues(values, model, categoryNamesToTotalEventSizes);
  }

  tr.metrics.MetricRegistry.register(tracingMetric);

  return {
    tracingMetric: tracingMetric,
    // For testing only:
    MEMORY_INFRA_TRACING_CATEGORY: MEMORY_INFRA_TRACING_CATEGORY
  };
});
</script>
