Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import * as Common from '../common/common.js';
import * as DataGrid from '../data_grid/data_grid.js';
import * as HeapSnapshotModel from '../heap_snapshot_model/heap_snapshot_model.js';
import * as Platform from '../platform/platform.js';
import * as SDK from '../sdk/sdk.js';
import * as UI from '../ui/ui.js';
import {ChildrenProvider} from './ChildrenProvider.js'; // eslint-disable-line no-unused-vars
import {AllocationDataGrid, HeapSnapshotConstructorsDataGrid, HeapSnapshotDiffDataGrid, HeapSnapshotRetainmentDataGrid, HeapSnapshotSortableDataGrid,} from './HeapSnapshotDataGrids.js'; // eslint-disable-line no-unused-vars
import {HeapSnapshotProviderProxy, HeapSnapshotProxy} from './HeapSnapshotProxy.js'; // eslint-disable-line no-unused-vars
import {DataDisplayDelegate} from './ProfileHeader.js'; // eslint-disable-line no-unused-vars
/**
* @unrestricted
*/
export class HeapSnapshotGridNode extends DataGrid.DataGrid.DataGridNode {
/**
* @param {!HeapSnapshotSortableDataGrid} tree
* @param {boolean} hasChildren
*/
constructor(tree, hasChildren) {
super(null, hasChildren);
this._dataGrid = tree;
this._instanceCount = 0;
this._savedChildren = null;
/**
* List of position ranges for all visible nodes: [startPos1, endPos1),...,[startPosN, endPosN)
* Position is an item position in the provider.
*/
this._retrievedChildrenRanges = [];
/**
* @type {?ChildrenProvider}
*/
this._providerObject = null;
this._reachableFromWindow = false;
}
/**
* @param {!Array.} fieldNames
* @return {!HeapSnapshotModel.HeapSnapshotModel.ComparatorConfig}
*/
static createComparator(fieldNames) {
return /** @type {!HeapSnapshotModel.HeapSnapshotModel.ComparatorConfig} */ (
{fieldName1: fieldNames[0], ascending1: fieldNames[1], fieldName2: fieldNames[2], ascending2: fieldNames[3]});
}
/**
* @return {!HeapSnapshotSortableDataGrid}
*/
heapSnapshotDataGrid() {
return this._dataGrid;
}
/**
* @return {!ChildrenProvider}
*/
createProvider() {
throw new Error('Not implemented.');
}
/**
* @return {?{snapshot:!HeapSnapshotProxy, snapshotNodeIndex:number}}
*/
retainersDataSource() {
return null;
}
/**
* @return {!ChildrenProvider}
*/
_provider() {
if (!this._providerObject) {
this._providerObject = this.createProvider();
}
return this._providerObject;
}
/**
* @override
* @param {string} columnId
* @return {!Element}
*/
createCell(columnId) {
const cell = super.createCell(columnId);
if (this._searchMatched) {
cell.classList.add('highlight');
}
return cell;
}
/**
* @override
*/
collapse() {
super.collapse();
this._dataGrid.updateVisibleNodes(true);
}
/**
* @override
*/
expand() {
super.expand();
this._dataGrid.updateVisibleNodes(true);
}
dispose() {
if (this._providerObject) {
this._providerObject.dispose();
}
for (let node = this.children[0]; node; node = node.traverseNextNode(true, this, true)) {
if (node.dispose) {
node.dispose();
}
}
}
/**
* @param {!SDK.HeapProfilerModel.HeapProfilerModel} heapProfilerModel
* @param {string} objectGroupName
* @return {!Promise}
*/
queryObjectContent(heapProfilerModel, objectGroupName) {
}
/**
* @param {!SDK.HeapProfilerModel.HeapProfilerModel} heapProfilerModel
* @param {string} objectGroupName
* @return {!Promise}
*/
tryQueryObjectContent(heapProfilerModel, objectGroupName) {
}
/**
* @param {!UI.ContextMenu.ContextMenu} contextMenu
* @param {!DataDisplayDelegate} dataDisplayDelegate
* @param {?SDK.HeapProfilerModel.HeapProfilerModel} heapProfilerModel
*/
populateContextMenu(contextMenu, dataDisplayDelegate, heapProfilerModel) {
}
/**
* @param {number} num
* @return {string}
*/
_toPercentString(num) {
return num.toFixed(0) + '\xa0%'; // \xa0 is a non-breaking space.
}
/**
* @param {number} distance
* @return {string}
*/
_toUIDistance(distance) {
const baseSystemDistance = HeapSnapshotModel.HeapSnapshotModel.baseSystemDistance;
return distance >= 0 && distance < baseSystemDistance ? Common.UIString.UIString('%d', distance) :
Common.UIString.UIString('\u2212');
}
/**
* @return {!Array.}
*/
allChildren() {
return this._dataGrid.allChildren(this);
}
/**
* @param {number} index
*/
removeChildByIndex(index) {
this._dataGrid.removeChildByIndex(this, index);
}
/**
* @param {number} nodePosition
* @return {?DataGrid.DataGrid.DataGridNode}
*/
childForPosition(nodePosition) {
let indexOfFirstChildInRange = 0;
for (let i = 0; i < this._retrievedChildrenRanges.length; i++) {
const range = this._retrievedChildrenRanges[i];
if (range.from <= nodePosition && nodePosition < range.to) {
const childIndex = indexOfFirstChildInRange + nodePosition - range.from;
return this.allChildren()[childIndex];
}
indexOfFirstChildInRange += range.to - range.from + 1;
}
return null;
}
/**
* @param {string} columnId
* @return {!Element}
*/
_createValueCell(columnId) {
const cell = UI.Fragment.html`
`;
if (this.dataGrid.snapshot.totalSize !== 0) {
const div = createElement('div');
const valueSpan = UI.Fragment.html`${this.data[columnId]}`;
div.appendChild(valueSpan);
const percentColumn = columnId + '-percent';
if (percentColumn in this.data) {
const percentSpan = UI.Fragment.html`${this.data[percentColumn]}`;
div.appendChild(percentSpan);
div.classList.add('profile-multiple-values');
UI.ARIAUtils.markAsHidden(valueSpan);
UI.ARIAUtils.markAsHidden(percentSpan);
this.setCellAccessibleName(ls`${this.data[columnId]}, ${this.data[percentColumn]}`, cell, columnId);
}
cell.appendChild(div);
}
return cell;
}
/**
* @override
*/
populate() {
if (this._populated) {
return;
}
this._populated = true;
this._provider().sortAndRewind(this.comparator()).then(() => this._populateChildren());
}
/**
* @return {!Promise}
*/
expandWithoutPopulate() {
// Make sure default populate won't take action.
this._populated = true;
this.expand();
return this._provider().sortAndRewind(this.comparator());
}
/**
* @param {?number=} fromPosition
* @param {?number=} toPosition
* @return {!Promise}
*/
_populateChildren(fromPosition, toPosition) {
let afterPopulate;
const promise = new Promise(resolve => afterPopulate = resolve);
fromPosition = fromPosition || 0;
toPosition = toPosition || fromPosition + this._dataGrid.defaultPopulateCount();
let firstNotSerializedPosition = fromPosition;
serializeNextChunk.call(this);
return promise;
/**
* @this {HeapSnapshotGridNode}
*/
function serializeNextChunk() {
if (firstNotSerializedPosition >= toPosition) {
return;
}
const end = Math.min(firstNotSerializedPosition + this._dataGrid.defaultPopulateCount(), toPosition);
this._provider().serializeItemsRange(firstNotSerializedPosition, end).then(childrenRetrieved.bind(this));
firstNotSerializedPosition = end;
}
/**
* @this {HeapSnapshotGridNode}
*/
function insertRetrievedChild(item, insertionIndex) {
if (this._savedChildren) {
const hash = this._childHashForEntity(item);
if (hash in this._savedChildren) {
this._dataGrid.insertChild(this, this._savedChildren[hash], insertionIndex);
return;
}
}
this._dataGrid.insertChild(this, this._createChildNode(item), insertionIndex);
}
/**
* @this {HeapSnapshotGridNode}
*/
function insertShowMoreButton(from, to, insertionIndex) {
const button = new DataGrid.ShowMoreDataGridNode.ShowMoreDataGridNode(
this._populateChildren.bind(this), from, to, this._dataGrid.defaultPopulateCount());
this._dataGrid.insertChild(this, button, insertionIndex);
}
/**
* @param {!HeapSnapshotModel.HeapSnapshotModel.ItemsRange} itemsRange
* @this {HeapSnapshotGridNode}
*/
function childrenRetrieved(itemsRange) {
let itemIndex = 0;
let itemPosition = itemsRange.startPosition;
const items = itemsRange.items;
let insertionIndex = 0;
if (!this._retrievedChildrenRanges.length) {
if (itemsRange.startPosition > 0) {
this._retrievedChildrenRanges.push({from: 0, to: 0});
insertShowMoreButton.call(this, 0, itemsRange.startPosition, insertionIndex++);
}
this._retrievedChildrenRanges.push({from: itemsRange.startPosition, to: itemsRange.endPosition});
for (let i = 0, l = items.length; i < l; ++i) {
insertRetrievedChild.call(this, items[i], insertionIndex++);
}
if (itemsRange.endPosition < itemsRange.totalLength) {
insertShowMoreButton.call(this, itemsRange.endPosition, itemsRange.totalLength, insertionIndex++);
}
} else {
let rangeIndex = 0;
let found = false;
let range;
while (rangeIndex < this._retrievedChildrenRanges.length) {
range = this._retrievedChildrenRanges[rangeIndex];
if (range.to >= itemPosition) {
found = true;
break;
}
insertionIndex += range.to - range.from;
// Skip the button if there is one.
if (range.to < itemsRange.totalLength) {
insertionIndex += 1;
}
++rangeIndex;
}
if (!found || itemsRange.startPosition < range.from) {
// Update previous button.
this.allChildren()[insertionIndex - 1].setEndPosition(itemsRange.startPosition);
insertShowMoreButton.call(
this, itemsRange.startPosition, found ? range.from : itemsRange.totalLength, insertionIndex);
range = {from: itemsRange.startPosition, to: itemsRange.startPosition};
if (!found) {
rangeIndex = this._retrievedChildrenRanges.length;
}
this._retrievedChildrenRanges.splice(rangeIndex, 0, range);
} else {
insertionIndex += itemPosition - range.from;
}
// At this point insertionIndex is always an index before button or between nodes.
// Also it is always true here that range.from <= itemPosition <= range.to
// Stretch the range right bound to include all new items.
while (range.to < itemsRange.endPosition) {
// Skip already added nodes.
const skipCount = range.to - itemPosition;
insertionIndex += skipCount;
itemIndex += skipCount;
itemPosition = range.to;
// We're at the position before button: ...x