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 */
15
16import { HeapDataInterface } from '../HeapDataInterface';
17import { EdgeType, NodeType } from './DatabaseStruct';
18const ROW_TYPE = 'js-memory';
19export enum FileType {
20  SNAPSHOT,
21  TIMELINE,
22}
23
24export enum ConstructorType {
25  ClassType,
26  InstanceType,
27  FiledType,
28  RetainersType,
29  ComparisonType,
30}
31
32export class ConstructorItem {
33  rowName = ROW_TYPE;
34  fileId = -1;
35  nodeName = '';
36  edgeName = '';
37  childCount = 1; // child count
38  distance = -1;
39  shallowSize = -1;
40  retainedSize = -1;
41  retainedPercent = ''; //retained percent
42  shallowPercent = ''; //shallow percent
43  hasNext = true;
44  status = true;
45  isSelected: boolean = false;
46  objectName = '';
47  expanded: boolean = true;
48  edgeCount = 0;
49  edgeType!: EdgeType;
50  type!: ConstructorType;
51  nodeType!: NodeType;
52  nextId: [] = [];
53  id = -1;
54  index = -1;
55  traceNodeId = -1;
56  parent!: ConstructorItem;
57  children: Array<ConstructorItem> = [];
58  retains: Array<ConstructorItem> = [];
59  classChildren: Array<ConstructorItem> = [];
60
61  getChildren(): ConstructorItem[] {
62    if (!this.hasNext) {
63      return [];
64    }
65    let data = HeapDataInterface.getInstance();
66    switch (this.type) {
67      case ConstructorType.ClassType:
68      case ConstructorType.InstanceType:
69      case ConstructorType.FiledType:
70        this.children = data.getNextForConstructor(this);
71        break;
72      case ConstructorType.RetainersType:
73        this.children = data.getRetains(this);
74        break;
75    }
76    return this.children;
77  }
78
79  isString(): boolean {
80    return [NodeType.STRING, NodeType.CONCATENATED_STRING, NodeType.SLICED_STRING].includes(this.nodeType);
81  }
82
83  clone(): ConstructorItem {
84    let copyItem = new ConstructorItem();
85    this.cloneContent(copyItem);
86    return copyItem;
87  }
88
89  protected cloneContent(copyItem: ConstructorItem): void {
90    copyItem.fileId = this.fileId;
91    copyItem.distance = this.distance;
92    copyItem.shallowSize = this.shallowSize;
93    copyItem.nodeName = this.nodeName;
94    copyItem.edgeCount = this.edgeCount;
95    copyItem.edgeType = this.edgeType;
96    copyItem.childCount = this.childCount;
97    copyItem.hasNext = this.hasNext;
98  }
99}
100
101export class ConstructorComparison extends ConstructorItem {
102  targetFileId = -1;
103  addedCount = 0;
104  removedCount = 0;
105  deltaCount = 0;
106  addedSize = 0;
107  removedSize = 0;
108  deltaSize = 0;
109  deletedIdx: Array<number> = [];
110  addedIndx: Array<number> = [];
111  isAdd = false;
112
113  getChildren(): ConstructorItem[] {
114    if (this.type !== ConstructorType.ComparisonType) {
115      return super.getChildren();
116    }
117    if (!this.hasNext) {
118      return [];
119    }
120    let data = HeapDataInterface.getInstance();
121    if (this.type === ConstructorType.ComparisonType) {
122      this.children = data.getNextForComparison(this);
123    }
124    return this.children;
125  }
126
127  clone(): ConstructorComparison {
128    let copyItem = new ConstructorComparison();
129    this.cloneContent(copyItem);
130    return copyItem;
131  }
132}
133export class AllocationFunction {
134  fileId = -1;
135  functionIndex = -1;
136  parentsId: Array<number>;
137  parents: Array<AllocationFunction>;
138  combineId: Set<number>;
139  status = true;
140  id: number;
141  name: string;
142  scriptName: string;
143  scriptId: number;
144  line: number;
145  column: number;
146  count: number;
147  size: number;
148  liveCount: number;
149  liveSize: number;
150  hasParent: boolean;
151
152  constructor(
153    nodeId: number,
154    functionName: string,
155    scriptName: string,
156    scriptId: number,
157    line: number,
158    column: number,
159    count: number,
160    size: number,
161    liveCount: number,
162    liveSize: number,
163    hasParent: boolean
164  ) {
165    this.combineId = new Set<number>();
166    this.parentsId = [];
167    this.parents = [];
168    this.id = nodeId;
169    this.name = functionName;
170    this.scriptName = scriptName;
171    this.scriptId = scriptId;
172    this.line = line;
173    this.column = column;
174    this.count = count;
175    this.size = size;
176    this.liveCount = liveCount;
177    this.liveSize = liveSize;
178    this.hasParent = hasParent;
179  }
180
181  /**
182   * bottom up next level is parent
183   * return Parents
184   */
185  getChildren(): AllocationFunction[] {
186    if (!this.hasParent) {
187      return [];
188    }
189    let data = HeapDataInterface.getInstance();
190    //bottom up next level is parent
191    data.getParentFunction(this);
192    return this.parents;
193  }
194
195  clone(): AllocationFunction {
196    let cloneItem = new AllocationFunction(
197      this.id,
198      this.name,
199      this.scriptName,
200      this.scriptId,
201      this.line,
202      this.column,
203      this.count,
204      this.size,
205      this.liveCount,
206      this.liveSize,
207      this.hasParent
208    );
209    cloneItem.parentsId = this.parentsId;
210    return cloneItem;
211  }
212}
213
214export class FileInfo {
215  id: number = -1;
216  name: string = '';
217  type!: FileType;
218  startTs: number = 0;
219  endTs: number = 0;
220  pid: number = 0;
221  size: number = 0;
222}
223