• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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