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.
8 * @fileoverview Provides the ObjectSnapshot and ObjectHistory classes.
10 tvcm.require('tvcm.range');
11 tvcm.require('tvcm.sorted_array_utils');
12 tvcm.require('tracing.trace_model.event');
13 tvcm.require('tracing.trace_model.object_snapshot');
15 tvcm.exportTo('tracing.trace_model', function() {
16 var ObjectSnapshot = tracing.trace_model.ObjectSnapshot;
19 * An object with a specific id, whose state has been snapshotted several
24 function ObjectInstance(
25 parent, id, category, name, creationTs, opt_baseTypeName) {
26 tracing.trace_model.Event.call(this);
29 this.category = category;
30 this.baseTypeName = opt_baseTypeName ? opt_baseTypeName : name;
32 this.creationTs = creationTs;
33 this.creationTsWasExplicit = false;
34 this.deletionTs = Number.MAX_VALUE;
35 this.deletionTsWasExplicit = false;
37 this.bounds = new tvcm.Range();
39 this.hasImplicitSnapshots = false;
42 ObjectInstance.prototype = {
43 __proto__: tracing.trace_model.Event.prototype,
49 addBoundsToRange: function(range) {
50 range.addRange(this.bounds);
53 addSnapshot: function(ts, args, opt_name, opt_baseTypeName) {
54 if (ts < this.creationTs)
55 throw new Error('Snapshots must be >= instance.creationTs');
56 if (ts >= this.deletionTs)
57 throw new Error('Snapshots cannot be added after ' +
58 'an objects deletion timestamp.');
61 if (this.snapshots.length > 0) {
62 lastSnapshot = this.snapshots[this.snapshots.length - 1];
63 if (lastSnapshot.ts == ts)
64 throw new Error('Snapshots already exists at this time!');
65 if (ts < lastSnapshot.ts) {
67 'Snapshots must be added in increasing timestamp order');
71 // Update baseTypeName if needed.
73 (this.name != opt_name)) {
74 if (!opt_baseTypeName)
75 throw new Error('Must provide base type name for name update');
76 if (this.baseTypeName != opt_baseTypeName)
77 throw new Error('Cannot update type name: base types dont match');
81 var snapshotConstructor =
82 tracing.trace_model.ObjectSnapshot.getConstructor(this.name);
83 var snapshot = new snapshotConstructor(this, ts, args);
84 this.snapshots.push(snapshot);
88 wasDeleted: function(ts) {
90 if (this.snapshots.length > 0) {
91 lastSnapshot = this.snapshots[this.snapshots.length - 1];
92 if (lastSnapshot.ts > ts)
94 'Instance cannot be deleted at ts=' +
95 ts + '. A snapshot exists that is older.');
98 this.deletionTsWasExplicit = true;
102 * See ObjectSnapshot constructor notes on object initialization.
104 preInitialize: function() {
105 for (var i = 0; i < this.snapshots.length; i++)
106 this.snapshots[i].preInitialize();
110 * See ObjectSnapshot constructor notes on object initialization.
112 initialize: function() {
113 for (var i = 0; i < this.snapshots.length; i++)
114 this.snapshots[i].initialize();
117 getSnapshotAt: function(ts) {
118 if (ts < this.creationTs) {
119 if (this.creationTsWasExplicit)
120 throw new Error('ts must be within lifetime of this instance');
121 return this.snapshots[0];
123 if (ts > this.deletionTs)
124 throw new Error('ts must be within lifetime of this instance');
126 var snapshots = this.snapshots;
127 var i = tvcm.findLowIndexInSortedIntervals(
129 function(snapshot) { return snapshot.ts; },
130 function(snapshot, i) {
131 if (i == snapshots.length - 1)
132 return snapshots[i].objectInstance.deletionTs;
133 return snapshots[i + 1].ts - snapshots[i].ts;
137 // Note, this is a little bit sketchy: this lets early ts point at the
138 // first snapshot, even before it is taken. We do this because raster
139 // tasks usually post before their tile snapshots are dumped. This may
140 // be a good line of code to re-visit if we start seeing strange and
141 // confusing object references showing up in the traces.
142 return this.snapshots[0];
144 if (i >= this.snapshots.length)
145 return this.snapshots[this.snapshots.length - 1];
146 return this.snapshots[i];
149 updateBounds: function() {
151 this.bounds.addValue(this.creationTs);
152 if (this.deletionTs != Number.MAX_VALUE)
153 this.bounds.addValue(this.deletionTs);
154 else if (this.snapshots.length > 0)
155 this.bounds.addValue(this.snapshots[this.snapshots.length - 1].ts);
158 shiftTimestampsForward: function(amount) {
159 this.creationTs += amount;
160 if (this.deletionTs != Number.MAX_VALUE)
161 this.deletionTs += amount;
162 this.snapshots.forEach(function(snapshot) {
163 snapshot.ts += amount;
168 ObjectInstance.nameToConstructorMap_ = {};
169 ObjectInstance.register = function(name, constructor) {
170 if (ObjectInstance.nameToConstructorMap_[name])
171 throw new Error('Constructor already registerd for ' + name);
172 ObjectInstance.nameToConstructorMap_[name] = constructor;
175 ObjectInstance.unregister = function(name) {
176 delete ObjectInstance.nameToConstructorMap_[name];
179 ObjectInstance.getConstructor = function(name) {
180 if (ObjectInstance.nameToConstructorMap_[name])
181 return ObjectInstance.nameToConstructorMap_[name];
182 return ObjectInstance;
186 ObjectInstance: ObjectInstance