Home | History | Annotate | Download | only in model
      1 <!DOCTYPE html>
      2 <!--
      3 Copyright (c) 2013 The Chromium Authors. All rights reserved.
      4 Use of this source code is governed by a BSD-style license that can be
      5 found in the LICENSE file.
      6 -->
      7 
      8 <link rel="import" href="/tracing/base/guid.html">
      9 <link rel="import" href="/tracing/base/range.html">
     10 <link rel="import" href="/tracing/model/async_slice.html">
     11 <link rel="import" href="/tracing/model/event_container.html">
     12 
     13 <script>
     14 'use strict';
     15 
     16 /**
     17  * @fileoverview Provides the AsyncSliceGroup class.
     18  */
     19 tr.exportTo('tr.model', function() {
     20   /**
     21    * A group of AsyncSlices associated with a thread.
     22    * @constructor
     23    * @extends {tr.model.EventContainer}
     24    */
     25   function AsyncSliceGroup(parentContainer, opt_name) {
     26     tr.model.EventContainer.call(this);
     27     this.parentContainer_ = parentContainer;
     28     this.slices = [];
     29     this.name_ = opt_name;
     30     this.viewSubGroups_ = undefined;
     31   }
     32 
     33   AsyncSliceGroup.prototype = {
     34     __proto__: tr.model.EventContainer.prototype,
     35 
     36     get parentContainer() {
     37       return this.parentContainer_;
     38     },
     39 
     40     get model() {
     41       return this.parentContainer_.parent.model;
     42     },
     43 
     44     get stableId() {
     45       return this.parentContainer_.stableId + '.AsyncSliceGroup';
     46     },
     47 
     48     getSettingsKey: function() {
     49       if (!this.name_)
     50         return undefined;
     51       var parentKey = this.parentContainer_.getSettingsKey();
     52       if (!parentKey)
     53         return undefined;
     54       return parentKey + '.' + this.name_;
     55     },
     56 
     57     /**
     58      * Helper function that pushes the provided slice onto the slices array.
     59      */
     60     push: function(slice) {
     61       slice.parentContainer = this.parentContainer;
     62       this.slices.push(slice);
     63       return slice;
     64     },
     65 
     66     /**
     67      * @return {Number} The number of slices in this group.
     68      */
     69     get length() {
     70       return this.slices.length;
     71     },
     72 
     73     /**
     74      * Shifts all the timestamps inside this group forward by the amount
     75      * specified, including all nested subSlices if there are any.
     76      */
     77     shiftTimestampsForward: function(amount) {
     78       for (var sI = 0; sI < this.slices.length; sI++) {
     79         var slice = this.slices[sI];
     80         slice.start = (slice.start + amount);
     81         // Shift all nested subSlices recursively.
     82         var shiftSubSlices = function(subSlices) {
     83           if (subSlices === undefined || subSlices.length === 0)
     84             return;
     85           for (var sJ = 0; sJ < subSlices.length; sJ++) {
     86             subSlices[sJ].start += amount;
     87             shiftSubSlices(subSlices[sJ].subSlices);
     88           }
     89         };
     90         shiftSubSlices(slice.subSlices);
     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      * Gets the sub-groups in this A-S-G defined by the group titles.
    107      *
    108      * @return {Array} An array of AsyncSliceGroups where each group has
    109      * slices that started on the same thread.
    110      */
    111     get viewSubGroups() {
    112       if (this.viewSubGroups_ === undefined) {
    113         var prefix = '';
    114         if (this.name !== undefined)
    115           prefix = this.name + '.';
    116         else
    117           prefix = '';
    118 
    119         var subGroupsByTitle = {};
    120         for (var i = 0; i < this.slices.length; ++i) {
    121           var slice = this.slices[i];
    122           var subGroupTitle = slice.viewSubGroupTitle;
    123           if (!subGroupsByTitle[subGroupTitle]) {
    124             subGroupsByTitle[subGroupTitle] = new AsyncSliceGroup(
    125                 this.parentContainer_, prefix + subGroupTitle);
    126           }
    127           subGroupsByTitle[subGroupTitle].push(slice);
    128         }
    129         this.viewSubGroups_ = tr.b.dictionaryValues(subGroupsByTitle);
    130         this.viewSubGroups_.sort(function(a, b) {
    131           return a.slices[0].compareTo(b.slices[0]);
    132         });
    133       }
    134       return this.viewSubGroups_;
    135     },
    136 
    137     iterateAllEventsInThisContainer: function(eventTypePredicate,
    138                                               callback, opt_this) {
    139       if (eventTypePredicate.call(opt_this, tr.model.AsyncSlice)) {
    140         for (var i = 0; i < this.slices.length; i++) {
    141           var slice = this.slices[i];
    142           callback.call(opt_this, slice);
    143           if (slice.subSlices)
    144             slice.subSlices.forEach(callback, opt_this);
    145         }
    146       }
    147     },
    148 
    149     iterateAllChildEventContainers: function(callback, opt_this) {
    150     }
    151   };
    152 
    153   return {
    154     AsyncSliceGroup: AsyncSliceGroup
    155   };
    156 });
    157 </script>
    158