• 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,
26  queryHeapString,
27} from '../trace/database/sql/SqlLite.sql';
28import { queryHeapFunction, queryHeapTraceNode } from '../trace/database/sql/Func.sql';
29
30export class LoadDatabase {
31  private static loadDB: LoadDatabase;
32  private fileModule!: Array<FileStruct>;
33
34  static getInstance(): LoadDatabase {
35    if (!this.loadDB) {
36      this.loadDB = new LoadDatabase();
37    }
38    return this.loadDB;
39  }
40
41  private async loadFile(listener: ParseListener): Promise<void> {
42    this.fileModule = [];
43    let results = await queryHeapFile();
44    for (let row of results) {
45      let fileStruct = new FileStruct();
46      fileStruct.id = row.id;
47      fileStruct.name = row.name;
48      fileStruct.startTs = row.startTs;
49      fileStruct.endTs = row.endTs;
50      fileStruct.pid = row.pid;
51      fileStruct.size = row.size;
52      if (fileStruct.name.startsWith('Snapshot')) {
53        fileStruct.type = FileType.SNAPSHOT;
54      } else {
55        fileStruct.type = FileType.TIMELINE;
56      }
57      info(`read ${fileStruct.name} from db  ${getTimeForLog()}`);
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): Promise<void> {
74    let result = await queryHeapInfo(file.id);
75    for (let row of result) {
76      //@ts-ignore
77      if (row.key.includes('types')) {
78        continue;
79      }
80      //@ts-ignore
81      switch (row.key) {
82        case 'node_count':
83          //@ts-ignore
84          file.snapshotStruct.nodeCount = row.intValue;
85          break;
86        case 'edge_count':
87          //@ts-ignore
88          file.snapshotStruct.edgeCount = row.intValue;
89          break;
90        case 'trace_function_count':
91          //@ts-ignore
92          file.snapshotStruct.functionCount = row.intValue;
93          break;
94      }
95    }
96  }
97
98  private async loadNode(file: FileStruct): Promise<void> {
99    let result = await queryHeapNode(file.id);
100    let heapNodes = file.snapshotStruct.nodeMap;
101    let firstEdgeIndex = 0;
102    for (let row of result) {
103      let node = new HeapNode(
104        file.id,
105        row.nodeIndex,
106        row.type,
107        file.snapshotStruct.strings[row.nameIdx],
108        row.id,
109        row.selfSize,
110        row.edgeCount,
111        row.traceNodeId,
112        row.detachedness,
113        firstEdgeIndex
114      );
115      if (file.snapshotStruct.rootNodeId === -1) {
116        file.snapshotStruct.rootNodeId = row.id;
117      }
118      heapNodes.set(node.id, node);
119      firstEdgeIndex += row.edgeCount;
120    }
121  }
122
123  private async loadEdge(file: FileStruct): Promise<void> {
124    file.snapshotStruct.edges = await queryHeapEdge(file.id);
125  }
126
127  private async loadTraceFunctionInfos(file: FileStruct): Promise<void> {
128    file.snapshotStruct.functionInfos = await queryHeapFunction(file.id);
129  }
130
131  private async loadTraceTree(file: FileStruct): Promise<void> {
132    let result = await queryHeapTraceNode(file.id);
133    let heapTraceNode = file.snapshotStruct.traceNodes;
134    let strings = file.snapshotStruct.strings;
135    for (let row of result) {
136      let traceNode = new AllocationFunction(
137        //@ts-ignore
138        row.id,
139        //@ts-ignore
140        strings[row.name],
141        //@ts-ignore
142        strings[row.scriptName],
143        //@ts-ignore
144        row.scriptId,
145        //@ts-ignore
146        row.line,
147        //@ts-ignore
148        row.column,
149        //@ts-ignore
150        row.count,
151        //@ts-ignore
152        row.size,
153        //@ts-ignore
154        row.liveCount,
155        //@ts-ignore
156        row.liveSize,
157        false
158      );
159      //@ts-ignore
160      traceNode.parentsId.push(row.parentId);
161      //@ts-ignore
162      traceNode.functionIndex = row.functionInfoIndex;
163      traceNode.fileId = file.id;
164      heapTraceNode.push(traceNode);
165    }
166  }
167
168  private async loadSamples(file: FileStruct): Promise<void> {
169    file.snapshotStruct.samples = await queryHeapSample(file.id);
170  }
171
172  private async loadStrings(file: FileStruct): Promise<void> {
173    let result = await queryHeapString(file.id);
174    for (let data of result) {
175      //@ts-ignore
176      file.snapshotStruct.strings.push(data.string);
177    }
178  }
179
180  async loadDatabase(listener: ParseListener): Promise<void> {
181    await this.loadFile(listener);
182  }
183}
184