1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15import { HeapDataInterface, ParseListener } from './HeapDataInterface'; 16import { AllocationFunction, FileType } from './model/UiStruct'; 17import { getTimeForLog } from './utils/Utils'; 18import { HeapNode, FileStruct } from './model/DatabaseStruct'; 19import { info } from '../log/Log'; 20import { 21 queryHeapEdge, 22 queryHeapFile, 23 queryHeapInfo, 24 queryHeapNode, 25 queryHeapSample, queryHeapString 26} from "../trace/database/sql/SqlLite.sql"; 27import {queryHeapFunction, queryHeapTraceNode} from "../trace/database/sql/Func.sql"; 28 29export class LoadDatabase { 30 private static loadDB: LoadDatabase; 31 private fileModule!: Array<FileStruct>; 32 33 static getInstance() { 34 if (!this.loadDB) { 35 this.loadDB = new LoadDatabase(); 36 } 37 return this.loadDB; 38 } 39 40 private async loadFile(listener: ParseListener) { 41 this.fileModule = new Array<FileStruct>(); 42 let results = await queryHeapFile(); 43 for (let row of results) { 44 let fileStruct = new FileStruct(); 45 fileStruct.id = row.id; 46 fileStruct.name = row.name; 47 fileStruct.startTs = row.startTs; 48 fileStruct.endTs = row.endTs; 49 fileStruct.pid = row.pid; 50 fileStruct.size = row.size; 51 if (fileStruct.name.startsWith('Snapshot')) { 52 fileStruct.type = FileType.SNAPSHOT; 53 } else { 54 fileStruct.type = FileType.TIMELINE; 55 } 56 info(`read ${fileStruct.name} from db ${getTimeForLog()}`); 57 //fileStruct.profile.root_index = 0 58 await this.loadInfo(fileStruct); 59 await this.loadStrings(fileStruct); 60 await this.loadNode(fileStruct); 61 await this.loadEdge(fileStruct); 62 await this.loadTraceFunctionInfos(fileStruct); 63 await this.loadTraceTree(fileStruct); 64 await this.loadSamples(fileStruct); 65 info(`read ${fileStruct.name} from db Success ${getTimeForLog()}`); 66 this.fileModule.push(fileStruct); 67 } 68 let dataParse = HeapDataInterface.getInstance(); 69 dataParse.setPraseListener(listener); 70 dataParse.parseData(this.fileModule); 71 } 72 73 private async loadInfo(file: FileStruct) { 74 let result = await queryHeapInfo(file.id); 75 for (let row of result) { 76 if (row.key.includes('types')) continue; 77 switch (row.key) { 78 case 'node_count': 79 file.snapshotStruct.nodeCount = row.intValue; 80 break; 81 case 'edge_count': 82 file.snapshotStruct.edgeCount = row.intValue; 83 break; 84 case 'trace_function_count': 85 file.snapshotStruct.functionCount = row.intValue; 86 break; 87 } 88 } 89 } 90 91 private async loadNode(file: FileStruct) { 92 let result = await queryHeapNode(file.id); 93 let heapNodes = file.snapshotStruct.nodeMap; 94 let firstEdgeIndex = 0; 95 for (let row of result) { 96 let node = new HeapNode( 97 file.id, 98 row.nodeIndex, 99 row.type, 100 file.snapshotStruct.strings[row.nameIdx], 101 row.id, 102 row.selfSize, 103 row.edgeCount, 104 row.traceNodeId, 105 row.detachedness, 106 firstEdgeIndex 107 ); 108 if (file.snapshotStruct.rootNodeId === -1) { 109 file.snapshotStruct.rootNodeId = row.id; 110 } 111 heapNodes.set(node.id, node); 112 firstEdgeIndex += row.edgeCount; 113 } 114 } 115 116 private async loadEdge(file: FileStruct) { 117 file.snapshotStruct.edges = await queryHeapEdge(file.id); 118 } 119 120 private async loadTraceFunctionInfos(file: FileStruct) { 121 file.snapshotStruct.functionInfos = await queryHeapFunction(file.id); 122 } 123 124 private async loadTraceTree(file: FileStruct) { 125 let result = await queryHeapTraceNode(file.id); 126 let heapTraceNode = file.snapshotStruct.traceNodes; 127 let strings = file.snapshotStruct.strings; 128 for (let row of result) { 129 let traceNode = new AllocationFunction( 130 row.id, 131 strings[row.name], 132 strings[row.scriptName], 133 row.scriptId, 134 row.line, 135 row.column, 136 row.count, 137 row.size, 138 row.liveCount, 139 row.liveSize, 140 false 141 ); 142 traceNode.parentsId.push(row.parentId); 143 traceNode.functionIndex = row.functionInfoIndex; 144 traceNode.fileId = file.id; 145 heapTraceNode.push(traceNode); 146 } 147 } 148 149 private async loadSamples(file: FileStruct) { 150 file.snapshotStruct.samples = await queryHeapSample(file.id); 151 } 152 153 private async loadStrings(file: FileStruct) { 154 let result = await queryHeapString(file.id); 155 for (let data of result) { 156 file.snapshotStruct.strings.push(data.string); 157 } 158 } 159 160 async loadDatabase(listener: ParseListener) { 161 await this.loadFile(listener); 162 } 163} 164