BottomUpProfileDataGridTree.js [plain text]
WebInspector.BottomUpProfileDataGridNode = function(profileNode, owningTree)
{
WebInspector.ProfileDataGridNode.call(this, profileNode, owningTree, this._willHaveChildren(profileNode));
this._remainingNodeInfos = [];
}
WebInspector.BottomUpProfileDataGridNode.prototype = {
_takePropertiesFromProfileDataGridNode: function(profileDataGridNode)
{
this._save();
this.selfTime = profileDataGridNode.selfTime;
this.totalTime = profileDataGridNode.totalTime;
this.numberOfCalls = profileDataGridNode.numberOfCalls;
},
_keepOnlyChild: function(child)
{
this._save();
this.removeChildren();
this.appendChild(child);
},
_exclude: function(aCallUID)
{
if (this._remainingNodeInfos)
this.populate();
this._save();
var children = this.children;
var index = this.children.length;
while (index--)
children[index]._exclude(aCallUID);
var child = this.childrenByCallUID[aCallUID];
if (child)
this._merge(child, true);
},
_restore: function()
{
WebInspector.ProfileDataGridNode.prototype._restore();
if (!this.children.length)
this.hasChildren = this._willHaveChildren(this.profileNode);
},
_merge: function(child, shouldAbsorb)
{
this.selfTime -= child.selfTime;
WebInspector.ProfileDataGridNode.prototype._merge.call(this, child, shouldAbsorb);
},
_sharedPopulate: function()
{
var remainingNodeInfos = this._remainingNodeInfos;
var count = remainingNodeInfos.length;
for (var index = 0; index < count; ++index) {
var nodeInfo = remainingNodeInfos[index];
var ancestor = nodeInfo.ancestor;
var focusNode = nodeInfo.focusNode;
var child = this.findChild(ancestor);
if (child) {
var totalTimeAccountedFor = nodeInfo.totalTimeAccountedFor;
child.selfTime += focusNode.selfTime;
child.numberOfCalls += focusNode.numberOfCalls;
if (!totalTimeAccountedFor)
child.totalTime += focusNode.totalTime;
} else {
child = new WebInspector.BottomUpProfileDataGridNode(ancestor, this.tree);
if (ancestor !== focusNode) {
child.selfTime = focusNode.selfTime;
child.totalTime = focusNode.totalTime;
child.numberOfCalls = focusNode.numberOfCalls;
}
this.appendChild(child);
}
var parent = ancestor.parent;
if (parent && parent.parent) {
nodeInfo.ancestor = parent;
child._remainingNodeInfos.push(nodeInfo);
}
}
delete this._remainingNodeInfos;
},
_willHaveChildren: function(profileNode)
{
return !!(profileNode.parent && profileNode.parent.parent);
},
__proto__: WebInspector.ProfileDataGridNode.prototype
}
WebInspector.BottomUpProfileDataGridTree = function(profileView, rootProfileNode)
{
WebInspector.ProfileDataGridTree.call(this, profileView, rootProfileNode);
var profileNodeUIDs = 0;
var profileNodeGroups = [[], [rootProfileNode]];
var visitedProfileNodesForCallUID = {};
this._remainingNodeInfos = [];
for (var profileNodeGroupIndex = 0; profileNodeGroupIndex < profileNodeGroups.length; ++profileNodeGroupIndex) {
var parentProfileNodes = profileNodeGroups[profileNodeGroupIndex];
var profileNodes = profileNodeGroups[++profileNodeGroupIndex];
var count = profileNodes.length;
for (var index = 0; index < count; ++index) {
var profileNode = profileNodes[index];
if (!profileNode.UID)
profileNode.UID = ++profileNodeUIDs;
if (profileNode.head && profileNode !== profileNode.head) {
var visitedNodes = visitedProfileNodesForCallUID[profileNode.callUID];
var totalTimeAccountedFor = false;
if (!visitedNodes) {
visitedNodes = {}
visitedProfileNodesForCallUID[profileNode.callUID] = visitedNodes;
} else {
var parentCount = parentProfileNodes.length;
for (var parentIndex = 0; parentIndex < parentCount; ++parentIndex) {
if (visitedNodes[parentProfileNodes[parentIndex].UID]) {
totalTimeAccountedFor = true;
break;
}
}
}
visitedNodes[profileNode.UID] = true;
this._remainingNodeInfos.push({ ancestor:profileNode, focusNode:profileNode, totalTimeAccountedFor:totalTimeAccountedFor });
}
var children = profileNode.children;
if (children.length) {
profileNodeGroups.push(parentProfileNodes.concat([profileNode]))
profileNodeGroups.push(children);
}
}
}
var any = (this);
var node = (any);
WebInspector.BottomUpProfileDataGridNode.prototype.populate.call(node);
return this;
}
WebInspector.BottomUpProfileDataGridTree.prototype = {
focus: function(profileDataGridNode)
{
if (!profileDataGridNode)
return;
this._save();
var currentNode = profileDataGridNode;
var focusNode = profileDataGridNode;
while (currentNode.parent && (currentNode instanceof WebInspector.ProfileDataGridNode)) {
currentNode._takePropertiesFromProfileDataGridNode(profileDataGridNode);
focusNode = currentNode;
currentNode = currentNode.parent;
if (currentNode instanceof WebInspector.ProfileDataGridNode)
currentNode._keepOnlyChild(focusNode);
}
this.children = [focusNode];
this.totalTime = profileDataGridNode.totalTime;
},
exclude: function(profileDataGridNode)
{
if (!profileDataGridNode)
return;
this._save();
var excludedCallUID = profileDataGridNode.callUID;
var excludedTopLevelChild = this.childrenByCallUID[excludedCallUID];
if (excludedTopLevelChild)
this.children.remove(excludedTopLevelChild);
var children = this.children;
var count = children.length;
for (var index = 0; index < count; ++index)
children[index]._exclude(excludedCallUID);
if (this.lastComparator)
this.sort(this.lastComparator, true);
},
_sharedPopulate: WebInspector.BottomUpProfileDataGridNode.prototype._sharedPopulate,
__proto__: WebInspector.ProfileDataGridTree.prototype
}