OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright 2016 The Chromium Authors. All rights reserved. | 3 Copyright 2016 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" href="/tracing/value/diagnostics/related_value_set.html"> | 8 <link rel="import" href="/tracing/value/diagnostics/related_value_map.html"> |
9 | 9 |
10 <script> | 10 <script> |
11 'use strict'; | 11 'use strict'; |
12 | 12 |
13 tr.exportTo('tr.v.d', function() { | 13 tr.exportTo('tr.v.d', function() { |
14 /** @constructor */ | 14 /** |
15 function Composition(opt_values) { | 15 * Composition encapsulates an additive relationship between NumericValues: |
16 tr.v.d.RelatedValueSet.call(this, opt_values); | 16 * the Value that contains this Composition diagnostic is composed of the |
| 17 * Values referenced by this Composition diagnostic. Composition is a |
| 18 * "breakdown" of its containing Value into its contained Values. This |
| 19 * additive relationship can apply to groups of other things besides Events, |
| 20 * such as memory allocations. Compositions over groups of Events is expected |
| 21 * to be the most common way of building Compositions, though it is not the |
| 22 * only way. See buildFromEvents() for an example of how to build a |
| 23 * Composition from an EventSet and a grouping function. |
| 24 * |
| 25 * @constructor |
| 26 */ |
| 27 function Composition() { |
| 28 tr.v.d.RelatedValueMap.call(this); |
17 } | 29 } |
18 | 30 |
| 31 /** |
| 32 * Build a Composition and its NumericValues from |events|. Group events using |
| 33 * |categoryForEvent|. Add the NumericValues to |values|. NumericValues' names |
| 34 * are prefixed with |namePrefix|. Numerics are built by |numericBuilder|. The |
| 35 * Numeric sample for each Event is derived from |opt_sampleForEvent|, which |
| 36 * defaults to event.cpuSelfTime. The caller must add the result Composition |
| 37 * to their Value's diagnostics. |
| 38 * |
| 39 * @param {!tr.v.ValueSet} values |
| 40 * @param {string} namePrefix |
| 41 * @param {!tr.model.EventSet} events |
| 42 * @param {!tr.v.NumericBuilder} numericBuilder |
| 43 * @param {!function(!tr.model.Event):string} categoryForEvent |
| 44 * @param {!function(!tr.model.Event):number=} opt_sampleForEvent |
| 45 * @param {*=} opt_this |
| 46 * @return {!Composition} |
| 47 */ |
| 48 Composition.buildFromEvents = function( |
| 49 values, namePrefix, events, numericBuilder, categoryForEvent, |
| 50 opt_sampleForEvent, opt_this) { |
| 51 var sampleForEvent = opt_sampleForEvent || ((event) => event.cpuSelfTime); |
| 52 |
| 53 var composition = new Composition(); |
| 54 for (var event of events) { |
| 55 var sample = sampleForEvent.call(opt_this, event); |
| 56 if (sample === undefined) |
| 57 continue; |
| 58 |
| 59 var eventCategory = categoryForEvent.call(opt_this, event); |
| 60 var value = composition.get(eventCategory); |
| 61 if (value === undefined) { |
| 62 value = new tr.v.NumericValue( |
| 63 namePrefix + eventCategory, numericBuilder.build()); |
| 64 values.addValue(value); |
| 65 composition.set(eventCategory, value); |
| 66 } |
| 67 |
| 68 value.numeric.add(sample, new tr.v.d.RelatedEventSet([event])); |
| 69 } |
| 70 return composition; |
| 71 }; |
| 72 |
19 Composition.prototype = { | 73 Composition.prototype = { |
20 __proto__: tr.v.d.RelatedValueSet.prototype | 74 __proto__: tr.v.d.RelatedValueMap.prototype, |
| 75 |
| 76 /** |
| 77 * Add a Value by an explicit name to this map. |
| 78 * |
| 79 * @param {string} name |
| 80 * @param {!(tr.v.d.ValueRef|tr.v.Value)} value |
| 81 */ |
| 82 set: function(name, value) { |
| 83 if (!(value instanceof tr.v.d.ValueRef)) { |
| 84 if (!(value instanceof tr.v.NumericValue)) |
| 85 throw new Error('Composition can only contain NumericValues'); |
| 86 |
| 87 if (value.name.indexOf(name) !== (value.name.length - name.length)) |
| 88 throw new Error('Composition name must be a suffix of value.name'); |
| 89 |
| 90 var existingValues = this.values; |
| 91 if ((existingValues.length > 0) && |
| 92 (value.numeric.unit !== existingValues[0].numeric.unit)) { |
| 93 throw new Error('Units mismatch', existingValues[0].numeric.unit, |
| 94 value.numeric.unit); |
| 95 } |
| 96 } |
| 97 |
| 98 tr.v.d.RelatedValueMap.prototype.set.call(this, name, value); |
| 99 } |
21 }; | 100 }; |
22 | 101 |
23 Composition.fromDict = function(d) { | 102 Composition.fromDict = function(d) { |
24 return new Composition(d.guids.map(guid => new tr.v.d.ValueRef(guid))); | 103 var composition = new Composition(); |
| 104 tr.b.iterItems(d.values, function(name, guid) { |
| 105 composition.set(name, new tr.v.d.ValueRef(guid)); |
| 106 }); |
| 107 return composition; |
25 }; | 108 }; |
26 | 109 |
27 tr.v.d.Diagnostic.register(Composition); | 110 tr.v.d.Diagnostic.register(Composition, { |
| 111 elementName: 'tr-v-ui-composition-span' |
| 112 }); |
28 | 113 |
29 return { | 114 return { |
30 Composition: Composition | 115 Composition: Composition |
31 }; | 116 }; |
32 }); | 117 }); |
33 </script> | 118 </script> |
OLD | NEW |