summaryrefslogtreecommitdiff
path: root/chromium/third_party/catapult/tracing/tracing/value/diagnostics/related_histogram_breakdown.html
blob: fedfb1275a19db2a55757f9cb4bc50382aeef16b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<!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/value/diagnostics/related_value_map.html">

<script>
'use strict';

tr.exportTo('tr.v.d', function() {
  var COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER =
    'ChromeUserFriendlyCategory';

  /**
   * RelatedHistogramBreakdown encapsulates an additive relationship between
   * Histograms: the Histogram that contains this RelatedHistogramBreakdown
   * diagnostic is composed of the Histograms referenced by this
   * RelatedHistogramBreakdown diagnostic. RelatedHistogramBreakdown is a
   * "breakdown" of its containing Histogram into its contained Histograms. This
   * additive relationship can apply to groups of other things besides Events,
   * such as memory allocations. RelatedHistogramBreakdowns over groups of
   * Events is expected to be the most common way of building
   * RelatedHistogramBreakdowns, though it is not the only way. See
   * buildFromEvents() for an example of how to build a
   * RelatedHistogramBreakdown from an EventSet and a grouping function.
   */
  class RelatedHistogramBreakdown extends tr.v.d.RelatedValueMap {
    constructor() {
      super();
      this.colorScheme = undefined;
    }

    /**
     * Add a Histogram by an explicit name to this map.
     *
     * @param {string} name
     * @param {!(tr.v.d.ValueRef|tr.v.Histogram)} value
     */
    set(name, value) {
      if (!(value instanceof tr.v.d.ValueRef)) {
        if (!(value instanceof tr.v.Histogram)) {
          throw new Error(
              'RelatedHistogramBreakdown can only contain Histograms');
        }

        if (value.name.indexOf(name) !== (value.name.length - name.length)) {
          throw new Error(
              'RelatedHistogramBreakdown name must be a suffix of value.name');
        }

        if ((this.length > 0) &&
            (value.unit !==
             tr.b.getFirstElement(this)[1].unit)) {
          throw new Error('Units mismatch', tr.b.getFirstElement(this)[1].unit,
              value.unit);
        }
      }

      tr.v.d.RelatedValueMap.prototype.set.call(this, name, value);
    }

    asDictInto_(d) {
      tr.v.d.RelatedValueMap.prototype.asDictInto_.call(this, d);
      if (this.colorScheme)
        d.colorScheme = this.colorScheme;
    }

    static fromDict(d) {
      var diagnostic = new RelatedHistogramBreakdown();
      tr.b.iterItems(d.values, function(name, guid) {
        diagnostic.set(name, new tr.v.d.ValueRef(guid));
      });
      if (d.colorScheme)
        diagnostic.colorScheme = d.colorScheme;
      return diagnostic;
    }

    /**
    * Build a RelatedHistogramBreakdown and its Histograms from |events|.  Group
    * events using |categoryForEvent|. Add the Histograms to |values|.
    * Histograms' names are prefixed with |namePrefix|. Histograms are built
    * with |opt_binBoundaries|. The numeric sample for each Event is derived
    * from |opt_sampleForEvent|, which defaults to event.cpuSelfTime. The caller
    * must add the result RelatedHistogramBreakdown to their Histogram's
    * diagnostics.
    *
    * @param {!tr.v.ValueSet} values
    * @param {string} namePrefix
    * @param {!tr.model.EventSet} events
    * @param {!function(!tr.model.Event):string} categoryForEvent
    * @param {!tr.b.Unit} unit
    * @param {!function(!tr.model.Event):number=} opt_sampleForEvent
    * @param {!tr.v.HistogramBinBoundaries=} opt_binBoundaries
    * @param {*=} opt_this
    * @return {!RelatedHistogramBreakdown}
    */
    static buildFromEvents(values, namePrefix, events, categoryForEvent, unit,
        opt_sampleForEvent, opt_binBoundaries, opt_this) {
      var sampleForEvent = opt_sampleForEvent || ((event) => event.cpuSelfTime);

      var diagnostic = new RelatedHistogramBreakdown();
      for (var event of events) {
        var sample = sampleForEvent.call(opt_this, event);
        if (sample === undefined)
          continue;

        var eventCategory = categoryForEvent.call(opt_this, event);
        var value = diagnostic.get(eventCategory);
        if (value === undefined) {
          value = new tr.v.Histogram(
              namePrefix + eventCategory, unit, opt_binBoundaries);
          values.addHistogram(value);
          diagnostic.set(eventCategory, value);
        }

        value.addSample(sample,
            {relatedEvents: new tr.v.d.RelatedEventSet([event])});
      }
      return diagnostic;
    }
  }

  tr.v.d.Diagnostic.register(RelatedHistogramBreakdown, {
    elementName: 'tr-v-ui-breakdown-span'
  });

  return {
    COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER:
      COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER,
    RelatedHistogramBreakdown: RelatedHistogramBreakdown
  };
});
</script>