Home | History | Annotate | Download | only in trace_model
      1 // Copyright (c) 2013 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 ObjectCollection class.
      9  */
     10 base.require('base.utils');
     11 base.require('base.range');
     12 base.require('base.sorted_array_utils');
     13 base.require('tracing.trace_model.object_instance');
     14 base.require('tracing.trace_model.time_to_object_instance_map');
     15 
     16 base.exportTo('tracing.trace_model', function() {
     17   var ObjectInstance = tracing.trace_model.ObjectInstance;
     18 
     19   /**
     20    * A collection of object instances and their snapshots, accessible by id and
     21    * time, or by object name.
     22    *
     23    * @constructor
     24    */
     25   function ObjectCollection(parent) {
     26     this.parent = parent;
     27     this.bounds = new base.Range();
     28     this.instanceMapsById_ = {}; // id -> TimeToObjectInstanceMap
     29     this.instancesByTypeName_ = {};
     30     this.createObjectInstance_ = this.createObjectInstance_.bind(this);
     31   }
     32 
     33   ObjectCollection.prototype = {
     34     __proto__: Object.prototype,
     35 
     36     createObjectInstance_: function(parent, id, category, name, creationTs) {
     37       var constructor = tracing.trace_model.ObjectInstance.getConstructor(name);
     38       var instance = new constructor(parent, id, category, name, creationTs);
     39       var typeName = instance.typeName;
     40       var instancesOfTypeName = this.instancesByTypeName_[typeName];
     41       if (!instancesOfTypeName) {
     42         instancesOfTypeName = [];
     43         this.instancesByTypeName_[typeName] = instancesOfTypeName;
     44       }
     45       instancesOfTypeName.push(instance);
     46       return instance;
     47     },
     48 
     49     getOrCreateInstanceMap_: function(id) {
     50       var instanceMap = this.instanceMapsById_[id];
     51       if (instanceMap)
     52         return instanceMap;
     53       instanceMap = new tracing.trace_model.TimeToObjectInstanceMap(
     54           this.createObjectInstance_, this.parent, id);
     55       this.instanceMapsById_[id] = instanceMap;
     56       return instanceMap;
     57     },
     58 
     59     idWasCreated: function(id, category, name, ts) {
     60       var instanceMap = this.getOrCreateInstanceMap_(id);
     61       return instanceMap.idWasCreated(category, name, ts);
     62     },
     63 
     64     addSnapshot: function(id, category, name, ts, args) {
     65       var instanceMap = this.getOrCreateInstanceMap_(id, category, name, ts);
     66       var snapshot = instanceMap.addSnapshot(category, name, ts, args);
     67       if (snapshot.objectInstance.category != category) {
     68         throw new Error('Added snapshot with different category ' +
     69                         'than when it was created');
     70       }
     71       if (snapshot.objectInstance.name != name) {
     72         throw new Error('Added snapshot with different name than ' +
     73                         'when it was created');
     74       }
     75       return snapshot;
     76     },
     77 
     78     idWasDeleted: function(id, category, name, ts) {
     79       var instanceMap = this.getOrCreateInstanceMap_(id, category, name, ts);
     80       var deletedInstance = instanceMap.idWasDeleted(category, name, ts);
     81       if (!deletedInstance)
     82         return;
     83       if (deletedInstance.category != category) {
     84         throw new Error('Deleting an object with a different category ' +
     85                         'than when it was created');
     86       }
     87       if (deletedInstance.name != name) {
     88         throw new Error('Deleting an object with a different name than ' +
     89                         'when it was created');
     90       }
     91     },
     92 
     93     autoDeleteObjects: function(maxTimestamp) {
     94       base.iterItems(this.instanceMapsById_, function(id, i2imap) {
     95         var lastInstance = i2imap.lastInstance;
     96         if (lastInstance.deletionTs != Number.MAX_VALUE)
     97           return;
     98         i2imap.idWasDeleted(
     99             lastInstance.category, lastInstance.name, maxTimestamp);
    100         // idWasDeleted will cause lastInstance.deletionTsWasExplicit to be set
    101         // to true. Unset it here.
    102         lastInstance.deletionTsWasExplicit = false;
    103       });
    104     },
    105 
    106     getObjectInstanceAt: function(id, ts) {
    107       var instanceMap = this.instanceMapsById_[id];
    108       if (!instanceMap)
    109         return undefined;
    110       return instanceMap.getInstanceAt(ts);
    111     },
    112 
    113     getSnapshotAt: function(id, ts) {
    114       var instance = this.getObjectInstanceAt(id, ts);
    115       if (!instance)
    116         return undefined;
    117       return instance.getSnapshotAt(ts);
    118     },
    119 
    120     iterObjectInstances: function(iter, opt_this) {
    121       opt_this = opt_this || this;
    122       base.iterItems(this.instanceMapsById_, function(id, i2imap) {
    123         i2imap.instances.forEach(iter, opt_this);
    124       });
    125     },
    126 
    127     getAllObjectInstances: function() {
    128       var instances = [];
    129       this.iterObjectInstances(function(i) { instances.push(i); });
    130       return instances;
    131     },
    132 
    133     getAllInstancesNamed: function(name) {
    134       return this.instancesByTypeName_[name];
    135     },
    136 
    137     getAllInstancesByTypeName: function() {
    138       return this.instancesByTypeName_;
    139     },
    140 
    141     preInitializeAllObjects: function() {
    142       this.iterObjectInstances(function(instance) {
    143         instance.preInitialize();
    144       });
    145     },
    146 
    147     initializeAllObjects: function() {
    148       this.iterObjectInstances(function(instance) {
    149         instance.initialize();
    150       });
    151     },
    152 
    153     initializeInstances: function() {
    154       this.iterObjectInstances(function(instance) {
    155         instance.initialize();
    156       });
    157     },
    158 
    159     updateBounds: function() {
    160       this.bounds.reset();
    161       this.iterObjectInstances(function(instance) {
    162         instance.updateBounds();
    163         this.bounds.addRange(instance.bounds);
    164       }, this);
    165     },
    166 
    167     shiftTimestampsForward: function(amount) {
    168       this.iterObjectInstances(function(instance) {
    169         instance.shiftTimestampsForward(amount);
    170       });
    171     },
    172 
    173     addCategoriesToDict: function(categoriesDict) {
    174       this.iterObjectInstances(function(instance) {
    175         categoriesDict[instance.category] = true;
    176       });
    177     },
    178 
    179     toJSON: function() {
    180       // TODO(nduca): Implement this if we need it.
    181       return {};
    182     }
    183   };
    184 
    185   return {
    186     ObjectCollection: ObjectCollection
    187   };
    188 });
    189