blob: 19213f74ba4efed1f0861f12665016e239d1359b [file] [edit]
<!DOCTYPE html>
<!--
Copyright 2017 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/timing.html">
<link rel="import" href="/tracing/value/histogram_grouping.html">
<link rel="import" href="/tracing/value/histogram_set.html">
<script>
'use strict';
tr.exportTo('tr.v', function() {
const getDisplayLabel =
tr.v.HistogramGrouping.DISPLAY_LABEL.callback;
const DEFAULT_POSSIBLE_GROUPS = [];
const EXCLUDED_GROUPING_KEYS = [
tr.v.HistogramGrouping.DISPLAY_LABEL.key,
];
// HISTOGRAM_NAME is overridden.
// DISPLAY_LABEL is used to define the columns, so don't allow grouping rows
// by it.
for (const group of tr.v.HistogramGrouping.BY_KEY.values()) {
if (EXCLUDED_GROUPING_KEYS.includes(group.key)) continue;
DEFAULT_POSSIBLE_GROUPS.push(group);
}
// This Processor collects various parameters from a set of Histograms such as
// their statistics, displayLabels, and grouping keys in a single pass.
class HistogramParameterCollector {
constructor() {
this.statisticNames_ = new Set(['avg']);
this.labelsToStartTimes_ = new Map();
// @typedef {!Map.<string,!tr.v.HistogramGrouping>}
this.keysToGroupings_ = new Map(DEFAULT_POSSIBLE_GROUPS.map(
g => [g.key, g]));
// Map from HistogramGrouping keys to Sets of return values from the
// HistogramGroupings' callbacks.
this.keysToValues_ = new Map(DEFAULT_POSSIBLE_GROUPS.map(
g => [g.key, new Set()]));
// Never remove 'name' from keysToGroupings.
this.keysToValues_.delete(
tr.v.HistogramGrouping.HISTOGRAM_NAME.key);
}
process(histograms) {
const allStoryTags = new Set();
let maxSampleCount = 0;
for (const hist of histograms) {
maxSampleCount = Math.max(maxSampleCount, hist.numValues);
for (const statName of hist.statisticsNames) {
this.statisticNames_.add(statName);
}
let startTime = hist.diagnostics.get(
tr.v.d.RESERVED_NAMES.BENCHMARK_START);
if (startTime !== undefined) startTime = startTime.minDate.getTime();
const displayLabel = getDisplayLabel(hist);
if (this.labelsToStartTimes_.has(displayLabel)) {
startTime = Math.min(startTime,
this.labelsToStartTimes_.get(displayLabel));
}
this.labelsToStartTimes_.set(displayLabel, startTime);
for (const [groupingKey, values] of this.keysToValues_) {
const grouping = this.keysToGroupings_.get(groupingKey);
const value = grouping.callback(hist);
if (!value) continue;
values.add(value);
if (values.size > 1) {
// This grouping will definitely stay in keysToGroupings_. We don't
// need to see any more values in the rest of histograms. Remove
// this groupingKey from this.keysToValues_ so that we don't compute
// it for any more histograms and so that we don't delete it from
// keysToGroupings_.
this.keysToValues_.delete(groupingKey);
}
}
const storyTags = hist.diagnostics.get(
tr.v.d.RESERVED_NAMES.STORY_TAGS);
for (const tag of (storyTags || [])) {
allStoryTags.add(tag);
}
}
tr.b.Timing.instant(
'HistogramParameterCollector', 'maxSampleCount', maxSampleCount);
for (const tagGrouping of tr.v.HistogramGrouping.buildFromTags(
allStoryTags, tr.v.d.RESERVED_NAMES.STORY_TAGS)) {
const values = new Set();
for (const hist of histograms) {
values.add(tagGrouping.callback(hist));
}
if (values.size > 1) {
this.keysToGroupings_.set(tagGrouping.key, tagGrouping);
this.keysToValues_.set(tagGrouping.key, values);
}
}
this.statisticNames_.add('pct_090');
}
get statisticNames() {
return Array.from(this.statisticNames_);
}
get labels() {
const displayLabels = Array.from(this.labelsToStartTimes_.keys());
displayLabels.sort((x, y) =>
this.labelsToStartTimes_.get(x) - this.labelsToStartTimes_.get(y));
return displayLabels;
}
get possibleGroupings() {
for (const [key, values] of this.keysToValues_) {
if (values.size >= 2) continue;
// Remove this grouping from keysToGroupings_ if there is fewer than
// 2 possible values.
this.keysToGroupings_.delete(key);
}
return Array.from(this.keysToGroupings_.values());
}
}
return {
HistogramParameterCollector,
};
});
</script>