1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 'use strict'; 6 7 /** 8 * @fileoverview Provides the AsyncSliceGroup class. 9 */ 10 base.require('range'); 11 base.require('model.slice'); 12 base.exportTo('tracing.model', function() { 13 14 var Slice = tracing.model.Slice; 15 16 /** 17 * A AsyncSlice represents an interval of time during which an 18 * asynchronous operation is in progress. An AsyncSlice consumes no CPU time 19 * itself and so is only associated with Threads at its start and end point. 20 * 21 * @constructor 22 */ 23 function AsyncSlice(category, title, colorId, start, args) { 24 Slice.call(this, category, title, colorId, start, args); 25 }; 26 27 AsyncSlice.prototype = { 28 __proto__: Slice.prototype, 29 30 toJSON: function() { 31 var obj = new Object(); 32 var keys = Object.keys(this); 33 for (var i = 0; i < keys.length; i++) { 34 var key = keys[i]; 35 if (typeof this[key] == 'function') 36 continue; 37 if (key == 'startThread' || key == 'endThread') { 38 obj[key] = this[key].guid; 39 continue; 40 } 41 obj[key] = this[key]; 42 } 43 return obj; 44 }, 45 46 id: undefined, 47 48 startThread: undefined, 49 50 endThread: undefined, 51 52 subSlices: undefined 53 }; 54 55 /** 56 * A group of AsyncSlices. 57 * @constructor 58 */ 59 function AsyncSliceGroup() { 60 this.slices = []; 61 this.bounds = new base.Range(); 62 } 63 64 AsyncSliceGroup.prototype = { 65 __proto__: Object.prototype, 66 67 /** 68 * Helper function that pushes the provided slice onto the slices array. 69 */ 70 push: function(slice) { 71 this.slices.push(slice); 72 }, 73 74 /** 75 * @return {Number} The number of slices in this group. 76 */ 77 get length() { 78 return this.slices.length; 79 }, 80 81 /** 82 * Shifts all the timestamps inside this group forward by the amount 83 * specified. 84 */ 85 shiftTimestampsForward: function(amount) { 86 for (var sI = 0; sI < this.slices.length; sI++) { 87 var slice = this.slices[sI]; 88 slice.start = (slice.start + amount); 89 for (var sJ = 0; sJ < slice.subSlices.length; sJ++) 90 slice.subSlices[sJ].start += amount; 91 } 92 }, 93 94 /** 95 * Updates the bounds for this group based on the slices it contains. 96 */ 97 updateBounds: function() { 98 this.bounds.reset(); 99 for (var i = 0; i < this.slices.length; i++) { 100 this.bounds.addValue(this.slices[i].start); 101 this.bounds.addValue(this.slices[i].end); 102 } 103 }, 104 105 /** 106 * Breaks up this group into slices based on start thread. 107 * 108 * @return {Array} An array of AsyncSliceGroups where each group has 109 * slices that started on the same thread. 110 */ 111 computeSubGroups: function() { 112 var subGroupsByGUID = {}; 113 for (var i = 0; i < this.slices.length; ++i) { 114 var slice = this.slices[i]; 115 var sliceGUID = slice.startThread.guid; 116 if (!subGroupsByGUID[sliceGUID]) 117 subGroupsByGUID[sliceGUID] = new AsyncSliceGroup(); 118 subGroupsByGUID[sliceGUID].slices.push(slice); 119 } 120 var groups = []; 121 for (var guid in subGroupsByGUID) { 122 var group = subGroupsByGUID[guid]; 123 group.updateBounds(); 124 groups.push(group); 125 } 126 return groups; 127 } 128 }; 129 130 return { 131 AsyncSlice: AsyncSlice, 132 AsyncSliceGroup: AsyncSliceGroup 133 }; 134 }); 135