1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ciimport { AllocationFunction } from '../model/UiStruct'; 17fb726d48Sopenharmony_ciimport { FileStruct, HeapTraceFunctionInfo } from '../model/DatabaseStruct'; 18fb726d48Sopenharmony_ci 19fb726d48Sopenharmony_ciexport class AllocationLogic { 20fb726d48Sopenharmony_ci private fileStruct: FileStruct; 21fb726d48Sopenharmony_ci private traceNodes: Array<AllocationFunction>; 22fb726d48Sopenharmony_ci private bottomUpList: Array<AllocationFunction>; 23fb726d48Sopenharmony_ci 24fb726d48Sopenharmony_ci constructor(fileStruct: FileStruct) { 25fb726d48Sopenharmony_ci this.fileStruct = fileStruct; 26fb726d48Sopenharmony_ci this.bottomUpList = []; 27fb726d48Sopenharmony_ci this.traceNodes = this.fileStruct.snapshotStruct.traceNodes; 28fb726d48Sopenharmony_ci this.setBottomUpTree(); 29fb726d48Sopenharmony_ci } 30fb726d48Sopenharmony_ci 31fb726d48Sopenharmony_ci private setBottomUpTree(): void { 32fb726d48Sopenharmony_ci let keyMap = new Map<String, AllocationFunction>(); 33fb726d48Sopenharmony_ci for (let node of this.traceNodes) { 34fb726d48Sopenharmony_ci if (node.parentsId.length > 1) { 35fb726d48Sopenharmony_ci node.hasParent = true; 36fb726d48Sopenharmony_ci } else if (node.parentsId.length === 0) { 37fb726d48Sopenharmony_ci node.hasParent = false; 38fb726d48Sopenharmony_ci } else { 39fb726d48Sopenharmony_ci if (node.parentsId[0] === -1) { 40fb726d48Sopenharmony_ci node.hasParent = false; 41fb726d48Sopenharmony_ci } else { 42fb726d48Sopenharmony_ci node.hasParent = true; 43fb726d48Sopenharmony_ci } 44fb726d48Sopenharmony_ci } 45fb726d48Sopenharmony_ci // combine node 46fb726d48Sopenharmony_ci if (keyMap.has(node.name + node.functionIndex)) { 47fb726d48Sopenharmony_ci let uniqueNode = keyMap.get(node.name + node.functionIndex); 48fb726d48Sopenharmony_ci if (!uniqueNode) { 49fb726d48Sopenharmony_ci continue; 50fb726d48Sopenharmony_ci } 51fb726d48Sopenharmony_ci uniqueNode.size += node.size; 52fb726d48Sopenharmony_ci uniqueNode.count += node.count; 53fb726d48Sopenharmony_ci uniqueNode.liveSize += node.liveSize; 54fb726d48Sopenharmony_ci uniqueNode.liveCount += node.liveCount; 55fb726d48Sopenharmony_ci uniqueNode.parentsId.push(...node.parentsId); 56fb726d48Sopenharmony_ci uniqueNode.combineId.add(uniqueNode.id); 57fb726d48Sopenharmony_ci uniqueNode.combineId.add(node.id); 58fb726d48Sopenharmony_ci } else { 59fb726d48Sopenharmony_ci keyMap.set(node.name + node.functionIndex, node); 60fb726d48Sopenharmony_ci node.combineId.add(node.id); 61fb726d48Sopenharmony_ci this.bottomUpList.push(node); 62fb726d48Sopenharmony_ci } 63fb726d48Sopenharmony_ci } 64fb726d48Sopenharmony_ci this.bottomUpList.sort(function (a, b) { 65fb726d48Sopenharmony_ci return b.size - a.size; 66fb726d48Sopenharmony_ci }); 67fb726d48Sopenharmony_ci } 68fb726d48Sopenharmony_ci 69fb726d48Sopenharmony_ci private getNodeById(id: number): AllocationFunction | null { 70fb726d48Sopenharmony_ci for (let func of this.bottomUpList) { 71fb726d48Sopenharmony_ci if (func.id === id) { 72fb726d48Sopenharmony_ci return func; 73fb726d48Sopenharmony_ci } 74fb726d48Sopenharmony_ci } 75fb726d48Sopenharmony_ci return null; 76fb726d48Sopenharmony_ci } 77fb726d48Sopenharmony_ci 78fb726d48Sopenharmony_ci private getFunctionStack(node: AllocationFunction, functionList: Array<HeapTraceFunctionInfo>): void { 79fb726d48Sopenharmony_ci functionList.push(this.fileStruct.snapshotStruct.functionInfos[node.functionIndex]); 80fb726d48Sopenharmony_ci if (node.parentsId.length > 0) { 81fb726d48Sopenharmony_ci for (let parentId of node.parentsId) { 82fb726d48Sopenharmony_ci let parentNode = this.getNodeById(parentId); 83fb726d48Sopenharmony_ci if (parentNode) { 84fb726d48Sopenharmony_ci this.getFunctionStack(parentNode, functionList); 85fb726d48Sopenharmony_ci } 86fb726d48Sopenharmony_ci } 87fb726d48Sopenharmony_ci } 88fb726d48Sopenharmony_ci } 89fb726d48Sopenharmony_ci 90fb726d48Sopenharmony_ci /** 91fb726d48Sopenharmony_ci * get Bottom Up FUnction List 92fb726d48Sopenharmony_ci * @returns bottomUpList 93fb726d48Sopenharmony_ci */ 94fb726d48Sopenharmony_ci public getFunctionList(): Array<AllocationFunction> { 95fb726d48Sopenharmony_ci return this.bottomUpList; 96fb726d48Sopenharmony_ci } 97fb726d48Sopenharmony_ci 98fb726d48Sopenharmony_ci /** 99fb726d48Sopenharmony_ci * set node parents node 100fb726d48Sopenharmony_ci * node has multi parent because bottom up combine multi node 101fb726d48Sopenharmony_ci * @param node selected node 102fb726d48Sopenharmony_ci */ 103fb726d48Sopenharmony_ci public getParent(node: AllocationFunction): void { 104fb726d48Sopenharmony_ci if (node.hasParent) { 105fb726d48Sopenharmony_ci if (node.parentsId.length > 1) { 106fb726d48Sopenharmony_ci for (let childrenId of node.parentsId) { 107fb726d48Sopenharmony_ci let children = this.traceNodes[childrenId - 1].clone(); 108fb726d48Sopenharmony_ci children.size = node.size; 109fb726d48Sopenharmony_ci children.count = node.count; 110fb726d48Sopenharmony_ci children.liveSize = node.liveSize; 111fb726d48Sopenharmony_ci children.liveCount = node.liveCount; 112fb726d48Sopenharmony_ci node.parents.push(children); 113fb726d48Sopenharmony_ci } 114fb726d48Sopenharmony_ci } else if ((node.parentsId.length = 1)) { 115fb726d48Sopenharmony_ci let childrenId = node.parentsId[0]; 116fb726d48Sopenharmony_ci if (!node.parents) { 117fb726d48Sopenharmony_ci node.parents = []; 118fb726d48Sopenharmony_ci } 119fb726d48Sopenharmony_ci let children = this.traceNodes[childrenId - 1].clone(); 120fb726d48Sopenharmony_ci children.size = node.size; 121fb726d48Sopenharmony_ci children.count = node.count; 122fb726d48Sopenharmony_ci children.liveSize = node.liveSize; 123fb726d48Sopenharmony_ci children.liveCount = node.liveCount; 124fb726d48Sopenharmony_ci node.parents.push(children); 125fb726d48Sopenharmony_ci this.getParent(children); 126fb726d48Sopenharmony_ci } else { 127fb726d48Sopenharmony_ci // no need to do anything 128fb726d48Sopenharmony_ci } 129fb726d48Sopenharmony_ci } 130fb726d48Sopenharmony_ci } 131fb726d48Sopenharmony_ci 132fb726d48Sopenharmony_ci /** 133fb726d48Sopenharmony_ci * get use bottom up method combine's node ids 134fb726d48Sopenharmony_ci * @param allocationNodeId node id 135fb726d48Sopenharmony_ci * @returns node combine id 136fb726d48Sopenharmony_ci */ 137fb726d48Sopenharmony_ci public getFunctionNodeIds(allocationNodeId: number): Array<number> { 138fb726d48Sopenharmony_ci let node = this.getNodeById(allocationNodeId); 139fb726d48Sopenharmony_ci if (node) { 140fb726d48Sopenharmony_ci return Array.from(node.combineId); 141fb726d48Sopenharmony_ci } else { 142fb726d48Sopenharmony_ci return []; 143fb726d48Sopenharmony_ci } 144fb726d48Sopenharmony_ci } 145fb726d48Sopenharmony_ci 146fb726d48Sopenharmony_ci /** 147fb726d48Sopenharmony_ci * get full stack for node 148fb726d48Sopenharmony_ci * @param allocationNodeId node.traceNodeId 149fb726d48Sopenharmony_ci * @returns stack list 150fb726d48Sopenharmony_ci */ 151fb726d48Sopenharmony_ci public getNodeStack(allocationNodeId: number): Array<HeapTraceFunctionInfo> { 152fb726d48Sopenharmony_ci let currentNode = this.getNodeById(allocationNodeId); 153fb726d48Sopenharmony_ci let functionList: HeapTraceFunctionInfo[] = []; 154fb726d48Sopenharmony_ci if (currentNode) { 155fb726d48Sopenharmony_ci this.getFunctionStack(currentNode, functionList); 156fb726d48Sopenharmony_ci } 157fb726d48Sopenharmony_ci return functionList; 158fb726d48Sopenharmony_ci } 159fb726d48Sopenharmony_ci} 160