• 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 */
15
16import { SelectionParam } from '../../../bean/BoxSelection';
17import { procedurePool } from '../../../database/Procedure';
18import { queryNativeHookResponseTypes } from '../../../database/sql/NativeHook.sql';
19import { TraceMode } from '../../../SpApplicationPublicFunc';
20
21export class Utils {
22  static isTransformed: boolean = false;
23  static currentSelectTrace: string | null | undefined;
24  static currentTraceMode: TraceMode = TraceMode.NORMAL;
25  static distributedTrace: string[] = [];
26  static DMAFENCECAT_MAP: Map<
27    number,
28    {
29      id: number;
30      cat: string;
31      seqno: number;
32      driver: string;
33      context: string
34    }> = new Map<
35      number,
36      {
37        id: number;
38        cat: string;
39        seqno: number;
40        driver: string;
41        context: string
42      }
43    >();
44  private static statusMap: Map<string, string> = new Map<string, string>();
45  private static instance: Utils | null = null;
46  private trace1CpuCount: number = 1;
47  private trace1WinCpuCount: number = 1;
48  private trace2CpuCount: number = 1;
49  private trace2WinCpuCount: number = 1;
50  trace1RecordStartNS: number = 1;
51  trace2RecordStartNS: number = 1;
52  trace1RecordEndNS: number = 1;
53  trace2RecordEndNS: number = 1;
54  totalNS: number = 1;
55  private trace1ThreadMap: Map<number, string> = new Map<number, string>();
56  private trace1ProcessMap: Map<number, string> = new Map<number, string>();
57  private trace1SchedSliceMap: Map<
58    string,
59    {
60      endState: string;
61      priority: number;
62    }
63  > = new Map<
64    string,
65    {
66      endState: string;
67      priority: number;
68    }
69  >();
70  private trace2ThreadMap: Map<number, string> = new Map<number, string>();
71  private trace2ProcessMap: Map<number, string> = new Map<number, string>();
72  private trace2SchedSliceMap: Map<
73    string,
74    {
75      endState: string;
76      priority: number;
77    }
78  > = new Map<
79    string,
80    {
81      endState: string;
82      priority: number;
83    }
84  >();
85  private callStackMap: Map<number | string, string> = new Map<number | string, string>();
86
87  constructor() {
88    Utils.statusMap.set('D', 'Uninterruptible Sleep');
89    Utils.statusMap.set('D-NIO', 'Uninterruptible Sleep(non-IO)');
90    Utils.statusMap.set('D-IO', 'Uninterruptible Sleep(IO)');
91    Utils.statusMap.set('DK', 'Uninterruptible Sleep + Wake Kill');
92    Utils.statusMap.set('DK-NIO', 'Uninterruptible Sleep(non-IO) + Wake Kill');
93    Utils.statusMap.set('DK-IO', 'Uninterruptible Sleep(IO) + Wake Kill');
94    Utils.statusMap.set('S', 'Sleeping');
95    Utils.statusMap.set('R', 'Runnable');
96    Utils.statusMap.set('Running', 'Running');
97    Utils.statusMap.set('R+', 'Runnable (Preempted)');
98    Utils.statusMap.set('R-B', 'Runnable (Binder)');
99    Utils.statusMap.set('I', 'Task Dead');
100    Utils.statusMap.set('T', 'Stopped');
101    Utils.statusMap.set('t', 'Traced');
102    Utils.statusMap.set('X', 'Exit (Dead)');
103    Utils.statusMap.set('Z', 'Exit (Zombie)');
104    Utils.statusMap.set('P', 'Parked');
105    Utils.statusMap.set('N', 'No Load');
106  }
107
108  public getProcessMap(traceId?: string | null): Map<number, string> {
109    if (traceId) {
110      return (traceId === '2' ? this.trace2ProcessMap : this.trace1ProcessMap);
111    } else {
112      return (Utils.currentSelectTrace === '2' ? this.trace2ProcessMap : this.trace1ProcessMap);
113    }
114  }
115
116  public getThreadMap(traceId?: string | null): Map<number, string> {
117    if (traceId) {
118      return (traceId === '2' ? this.trace2ThreadMap : this.trace1ThreadMap);
119    } else {
120      return (Utils.currentSelectTrace === '2' ? this.trace2ThreadMap : this.trace1ThreadMap);
121    }
122  }
123
124  public getCallStatckMap(): Map<number | string, string> {
125    return this.callStackMap;
126  }
127
128  public getSchedSliceMap(traceId?: string | null): Map<string, {
129    endState: string;
130    priority: number;
131  }> {
132    if (traceId) {
133      return (traceId === '2' ? this.trace2SchedSliceMap : this.trace1SchedSliceMap);
134    } else {
135      return (Utils.currentSelectTrace === '2' ? this.trace2SchedSliceMap : this.trace1SchedSliceMap);
136    }
137  }
138
139  public getCpuCount(traceId?: string | null): number {
140    if (traceId) {
141      return (traceId === '2' ? this.trace2CpuCount : this.trace1CpuCount);
142    } else {
143      return (Utils.currentSelectTrace === '2' ? this.trace2CpuCount : this.trace1CpuCount);
144    }
145  }
146
147  public setCpuCount(count: number, traceId?: string | null): void {
148    if (traceId) {
149      if (traceId === '2') {
150        this.trace2CpuCount = count;
151      } else {
152        this.trace1CpuCount = count;
153      }
154    } else {
155      if (Utils.currentSelectTrace === '2') {
156        this.trace2CpuCount = count;
157      } else {
158        this.trace1CpuCount = count;
159      }
160    }
161  }
162
163  public getWinCpuCount(traceId?: string | null): number {
164    if (traceId) {
165      return (traceId === '2' ? this.trace2WinCpuCount : this.trace1WinCpuCount);
166    } else {
167      return (Utils.currentSelectTrace === '2' ? this.trace2WinCpuCount : this.trace1WinCpuCount);
168    }
169  }
170
171  public setWinCpuCount(count: number, traceId?: string | null): void {
172    if (traceId) {
173      if (traceId === '2') {
174        this.trace2WinCpuCount = count;
175      } else {
176        this.trace1WinCpuCount = count;
177      }
178    } else {
179      if (Utils.currentSelectTrace === '2') {
180        this.trace2WinCpuCount = count;
181      } else {
182        this.trace1WinCpuCount = count;
183      }
184    }
185  }
186
187  public getRecordStartNS(traceId?: string | null): number {
188    if (traceId) {
189      return (traceId === '2' ? this.trace2RecordStartNS : this.trace1RecordStartNS);
190    } else {
191      return (Utils.currentSelectTrace === '2' ? this.trace2RecordStartNS : this.trace1RecordStartNS);
192    }
193  }
194
195  public getRecordEndNS(traceId?: string | null): number {
196    if (traceId) {
197      return (traceId === '2' ? this.trace2RecordEndNS : this.trace1RecordEndNS);
198    } else {
199      return (Utils.currentSelectTrace === '2' ? this.trace2RecordEndNS : this.trace1RecordEndNS);
200    }
201  }
202
203  public getTotalNS(traceId?: string | null): number {
204    return this.totalNS;
205  }
206
207  public static isDistributedMode(): boolean {
208    return Utils.currentTraceMode === TraceMode.DISTRIBUTED;
209  }
210
211  public static getInstance(): Utils {
212    if (Utils.instance === null) {
213      Utils.instance = new Utils();
214    }
215    return Utils.instance;
216  }
217
218  public clearCache(): void {
219    this.trace1ProcessMap.clear();
220    this.trace2ProcessMap.clear();
221    this.trace1ThreadMap.clear();
222    this.trace2ThreadMap.clear();
223    this.trace1SchedSliceMap.clear();
224    this.trace2SchedSliceMap.clear();
225    Utils.distributedTrace = [];
226  }
227
228  public static clearData(): void {
229    Utils.getInstance().clearCache();
230    Utils.DMAFENCECAT_MAP.clear();
231  }
232
233  public static getDistributedRowId(id: unknown): string {
234    let rowId = id;
235    if (rowId === null || rowId === undefined) {
236      rowId = '';
237    }
238    return this.currentSelectTrace ? `${rowId}-${this.currentSelectTrace}` : `${rowId}`;
239  }
240
241  public static getEndState(state: string): string {
242    if (Utils.getInstance().getStatusMap().has(state)) {
243      return Utils.getInstance().getStatusMap().get(state) || 'Unknown State';
244    } else {
245      if ('' === state || state === null) {
246        return '';
247      }
248      return 'Unknown State';
249    }
250  }
251
252  public static isBinder(data: unknown): boolean {
253    return (
254      // @ts-ignore
255      data.funName !== null && // @ts-ignore
256      (data.funName.toLowerCase().startsWith('binder transaction async') || //binder transaction
257        // @ts-ignore
258        data.funName.toLowerCase().startsWith('binder async') || // @ts-ignore
259        data.funName.toLowerCase().startsWith('binder reply'))
260    );
261  }
262
263  public static transferPTSTitle(ptsValue: unknown): string {
264    // @ts-ignore
265    if (ptsValue.startsWith('S-')) {
266      // @ts-ignore
267      return Utils.getEndState(ptsValue.replace('S-', '')); // @ts-ignore
268    } else if (ptsValue.startsWith('P-')) {
269      // @ts-ignore
270      let pid = ptsValue.replace('P-', '');
271      let process = Utils.getInstance().getProcessMap(Utils.currentSelectTrace).get(parseInt(pid)) || 'Process';
272      return `${process} [${pid}]`; // @ts-ignore
273    } else if (ptsValue.startsWith('T-')) {
274      // @ts-ignore
275      let tid = ptsValue.replace('T-', '');
276      let thread = Utils.getInstance().getThreadMap(Utils.currentSelectTrace).get(parseInt(tid)) || 'Thread';
277      return `${thread} [${tid}]`;
278    } else {
279      return '';
280    }
281  }
282
283  public static transferBinderTitle(value: unknown, traceId?: string | null): string {
284    // @ts-ignore
285    if (value.startsWith('P-')) {
286      // @ts-ignore
287      let pid = value.replace('P-', '');
288      let process = Utils.getInstance().getProcessMap(traceId).get(parseInt(pid)) || 'Process';
289      return `${process} [${pid}]`; // @ts-ignore
290    } else if (value.startsWith('T-')) {
291      // @ts-ignore
292      let tid = value.replace('T-', '');
293      let thread = Utils.getInstance().getThreadMap(traceId).get(parseInt(tid)) || 'Thread';
294      return `${thread} [${tid}]`;
295    } else {
296      return '';
297    }
298  }
299
300  public static getStateColor(state: string): string {
301    if (state === 'D-NIO' || state === 'DK-NIO') {
302      return '#795548';
303    } else if (state === 'D-IO' || state === 'DK-IO' || state === 'D' || state === 'DK') {
304      return '#f19b38';
305    } else if (state === 'R' || state === 'R+') {
306      return '#a0b84d';
307    } else if (state === 'R-B') {
308      return '#87CEFA';
309    } else if (state === 'I') {
310      return '#673ab7';
311    } else if (state === 'Running') {
312      return '#467b3b';
313    } else if (state === 'S') {
314      return '#e0e0e0';
315    } else {
316      return '#ff6e40';
317    }
318  }
319
320  public static getTimeString(ns: number): string {
321    let currentTime = ns;
322    let hour1 = 3600_000_000_000;
323    let minute1 = 60_000_000_000;
324    let second1 = 1_000_000_000;
325    let millisecond1 = 1_000_000;
326    let microsecond1 = 1_000;
327    let res = '';
328    if (currentTime >= hour1) {
329      res += `${Math.floor(currentTime / hour1)}h `;
330      currentTime = currentTime - Math.floor(currentTime / hour1) * hour1;
331    }
332    if (currentTime >= minute1) {
333      res += `${Math.floor(currentTime / minute1)}m `;
334      currentTime = currentTime - Math.floor(ns / minute1) * minute1;
335    }
336    if (currentTime >= second1) {
337      res += `${Math.floor(currentTime / second1)}s `;
338      currentTime = currentTime - Math.floor(currentTime / second1) * second1;
339    }
340    if (currentTime >= millisecond1) {
341      res += `${Math.floor(currentTime / millisecond1)}ms `;
342      currentTime = currentTime - Math.floor(currentTime / millisecond1) * millisecond1;
343    }
344    if (currentTime >= microsecond1) {
345      res += `${Math.floor(currentTime / microsecond1)}μs `;
346      currentTime = currentTime - Math.floor(currentTime / microsecond1) * microsecond1;
347    }
348    if (currentTime > 0) {
349      res += `${currentTime}ns `;
350    }
351    if (res === '') {
352      res = `${ns}`;
353    }
354    return res;
355  }
356
357  public static getProbablyTime(timeNs: number): string {
358    let currentNs = timeNs;
359    let probablyHour = 3600_000_000_000;
360    let probablyMinute1 = 60_000_000_000;
361    let probablySecond1 = 1_000_000_000;
362    let probablyMillisecond1 = 1_000_000;
363    let probablyMicrosecond1 = 1_000;
364    let res = '';
365    if (currentNs >= probablyHour) {
366      res += `${(currentNs / probablyHour).toFixed(2)}h `;
367    } else if (currentNs >= probablyMinute1) {
368      res += `${(currentNs / probablyMinute1).toFixed(2)}m `;
369    } else if (currentNs >= probablySecond1) {
370      res += `${(currentNs / probablySecond1).toFixed(2)}s `;
371    } else if (currentNs >= probablyMillisecond1) {
372      res += `${(currentNs / probablyMillisecond1).toFixed(2)}ms `;
373    } else if (currentNs >= probablyMicrosecond1) {
374      res += `${(currentNs / probablyMicrosecond1).toFixed(2)}μs `;
375    } else if (currentNs > 0) {
376      res += `${currentNs}ns `;
377    } else if (res === '') {
378      res = `${timeNs}`;
379    }
380    return res;
381  }
382
383  public static getTimeStringHMS(ns: number): string {
384    let currentNs = ns;
385    let hour1 = 3600_000_000_000;
386    let minute1 = 60_000_000_000;
387    let second1 = 1_000_000_000; // 1 second
388    let millisecond1 = 1_000_000; // 1 millisecond
389    let microsecond1 = 1_000; // 1 microsecond
390    let res = '';
391    if (currentNs >= hour1) {
392      res += `${Math.floor(currentNs / hour1)}:`;
393      currentNs = currentNs - Math.floor(currentNs / hour1) * hour1;
394    }
395    if (currentNs >= minute1) {
396      res += `${Math.floor(currentNs / minute1)}:`;
397      currentNs = currentNs - Math.floor(ns / minute1) * minute1;
398    }
399    if (currentNs >= second1) {
400      res += `${Math.floor(currentNs / second1)}:`;
401      currentNs = currentNs - Math.floor(currentNs / second1) * second1;
402    }
403    if (currentNs >= millisecond1) {
404      res += `${Math.floor(currentNs / millisecond1)}.`;
405      currentNs = currentNs - Math.floor(currentNs / millisecond1) * millisecond1;
406    }
407    if (currentNs >= microsecond1) {
408      res += `${Math.floor(currentNs / microsecond1)}.`;
409      currentNs = currentNs - Math.floor(currentNs / microsecond1) * microsecond1;
410    }
411    if (currentNs > 0) {
412      res += `${currentNs}`;
413    }
414    if (res === '') {
415      res = `${ns}`;
416    }
417    return res;
418  }
419
420  public static getByteWithUnit(bytes: number): string {
421    if (bytes < 0) {
422      return `-${this.getByteWithUnit(Math.abs(bytes))}`;
423    }
424    let currentByte = bytes;
425    let kb1 = 1 << 10;
426    let mb1 = (1 << 10) << 10;
427    let gb1 = ((1 << 10) << 10) << 10; // 1 gb
428    let res = '';
429    if (currentByte > gb1) {
430      res += `${(currentByte / gb1).toFixed(2)} GB`;
431    } else if (currentByte > mb1) {
432      res += `${(currentByte / mb1).toFixed(2)} MB`;
433    } else if (currentByte > kb1) {
434      res += `${(currentByte / kb1).toFixed(2)} KB`;
435    } else {
436      res += `${Math.round(currentByte)} byte`;
437    }
438    return res;
439  }
440
441  public static groupByMap(array: Array<unknown>, key: string): Map<unknown, unknown> {
442    let result = new Map();
443    array.forEach((item) => {
444      // @ts-ignore
445      let value = item[key];
446      if (!result.has(value)) {
447        result.set(value, []);
448      }
449      result.get(value).push(item);
450    });
451    return result;
452  }
453
454  public static groupBy(array: Array<unknown>, key: string): unknown {
455    return array.reduce((pre, current, index, arr) => {
456      // @ts-ignore
457      (pre[current[key]] = pre[current[key]] || []).push(current);
458      return pre;
459    }, {});
460  }
461
462  public static timeMsFormat2p(ms: number): string {
463    let currentNs = ms;
464    let hour1 = 3600_000;
465    let minute1 = 60_000;
466    let second1 = 1_000; // 1 second
467    let result = '';
468    if (currentNs >= hour1) {
469      result += `${Math.round(currentNs / hour1).toFixed(2)}h`;
470      return result;
471    }
472    if (currentNs >= minute1) {
473      result += `${Math.round(currentNs / minute1).toFixed(2)}min`;
474      return result;
475    }
476    if (currentNs >= second1) {
477      result += `${Math.round(currentNs / second1).toFixed(2)}s`;
478      return result;
479    }
480    if (currentNs > 0) {
481      result += `${currentNs.toFixed(2)}ms`;
482      return result;
483    }
484    if (result === '') {
485      result = '0s';
486    }
487    return result;
488  }
489
490  public static uuid(): string {
491    // @ts-ignore
492    return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
493      (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
494    );
495  }
496
497  public static getBinaryKBWithUnit(kbytes: number): string {
498    if (kbytes === 0) {
499      return '0KB';
500    }
501    let currentBytes = kbytes;
502    let mib1 = 1024;
503    let gib1 = 1024 * 1024;
504    let res = '';
505    if (currentBytes >= gib1) {
506      res += `${(currentBytes / gib1).toFixed(2)}GB`;
507    } else if (currentBytes >= mib1) {
508      res += `${(currentBytes / mib1).toFixed(2)}MB`;
509    } else {
510      res += `${currentBytes.toFixed(2)}KB`;
511    }
512    return res;
513  }
514
515  public static getBinaryByteWithUnit(bytes: number): string {
516    if (bytes === 0) {
517      return '0Bytes';
518    }
519    let currentBytes = bytes;
520    let kib1 = 1024;
521    let mib1 = 1024 * 1024;
522    let gib1 = 1024 * 1024 * 1024;
523    let res = '';
524    if (bytes < 0) {
525      res = '-';
526      currentBytes = Math.abs(currentBytes);
527    }
528    if (currentBytes >= gib1) {
529      res += `${(currentBytes / gib1).toFixed(2)}GB`;
530    } else if (currentBytes >= mib1) {
531      res += `${(currentBytes / mib1).toFixed(2)}MB`;
532    } else if (currentBytes >= kib1) {
533      res += `${(currentBytes / kib1).toFixed(2)}KB`;
534    } else {
535      res += `${currentBytes.toFixed(2)}Bytes`;
536    }
537    return res;
538  }
539
540  public static getTimeStampHMS(ns: number): string {
541    let currentNs = ns;
542    let hour1 = 3600_000_000_000;
543    let minute1 = 60_000_000_000;
544    let second1 = 1_000_000_000; // 1 second
545    let millisecond1 = 1_000_000; // 1 millisecond
546    let microsecond1 = 1_000; // 1 microsecond
547    let res = '';
548    if (currentNs >= hour1) {
549      res += `${this.getCompletionTime(Math.floor(currentNs / hour1), 2)}:`;
550      currentNs = currentNs - Math.floor(currentNs / hour1) * hour1;
551    }
552    if (currentNs >= minute1) {
553      res += `${this.getCompletionTime(Math.floor(currentNs / minute1), 2)}:`;
554      currentNs = currentNs - Math.floor(ns / minute1) * minute1;
555    }
556    if (currentNs >= second1) {
557      res += `${this.getCompletionTime(Math.floor(currentNs / second1), 2)}:`;
558      currentNs = currentNs - Math.floor(currentNs / second1) * second1;
559    } else {
560      res += '00:';
561    }
562    if (currentNs >= millisecond1) {
563      res += `${this.getCompletionTime(Math.floor(currentNs / millisecond1), 3)}.`;
564      currentNs = currentNs - Math.floor(currentNs / millisecond1) * millisecond1;
565    } else {
566      res += '000.';
567    }
568    if (currentNs >= microsecond1) {
569      res += `${this.getCompletionTime(Math.floor(currentNs / microsecond1), 3)}.`;
570      currentNs = currentNs - Math.floor(currentNs / microsecond1) * microsecond1;
571    } else {
572      res += '000';
573    }
574    if (currentNs > 0) {
575      res += this.getCompletionTime(currentNs, 3);
576    }
577    if (res === '') {
578      res = `${ns}`;
579    }
580    return res;
581  }
582
583  public static getDurString(ns: number): string {
584    let currentNs = ns;
585    let second1 = 1000000000;
586    let millisecond1 = 1000000;
587    let res = '';
588    if (currentNs >= second1) {
589      let cu = currentNs / second1;
590      res += `${cu.toFixed(3)} s `;
591      return res;
592    }
593    if (currentNs >= millisecond1) {
594      res += `${Math.floor(currentNs / millisecond1)} ms `;
595      return res;
596    }
597    if (res === '') {
598      res = `${ns}`;
599    }
600    return res;
601  }
602
603  private static getCompletionTime(time: number, maxLength: number): string {
604    if (maxLength === 2) {
605      if (time.toString().length === 2) {
606        return `${time}`;
607      } else {
608        return `0${time}`;
609      }
610    } else if (maxLength === 3) {
611      if (time.toString().length === 3) {
612        return time.toString();
613      } else if (time.toString().length === 2) {
614        return `0${time}`;
615      } else {
616        return `00${time}`;
617      }
618    } else {
619      return '0';
620    }
621  }
622
623  public getStatusMap(): Map<string, string> {
624    return Utils.statusMap;
625  }
626
627  public static removeDuplicates(array1: unknown[], array2: unknown[], key: string): unknown {
628    let obj: unknown = {};
629    return array1.concat(array2).reduce(function (total, item) {
630      // @ts-ignore
631      if (!obj[`${item[key]}-${item.pid}`]) {
632        // @ts-ignore
633        obj[`${item[key]}-${item.pid}`] = true; // @ts-ignore
634        total.push(item);
635      }
636      return total;
637    }, []);
638  }
639
640  // 线程排序去重
641  public static sortThreadRow(array1: unknown[], array2: unknown[], flag: string): unknown {
642    let total = new Array();
643    let arr2Map = new Map();
644    // 将array2转为map
645    for (let i = 0; i < array2.length; i++) {
646      // @ts-ignore
647      arr2Map.set(flag === 'thread' ? `${array2[i].pid}-${array2[i].tid}` : `${array2[i].pid}`, array2[i]);
648    }
649    for (let i = 0; i < array1.length; i++) {
650      // @ts-ignore
651      total.push(arr2Map.get(`${array1[i][0]}`));
652      // @ts-ignore
653      arr2Map.delete(`${array1[i][0]}`);
654    };
655    // 将map中剩余的循环加在total后
656    // @ts-ignore
657    arr2Map.forEach((v) => {
658      total.push(v);
659    });
660    return total;
661  }
662
663  static getFrequencyWithUnit = (
664    maxFreq: number
665  ): {
666    maxFreqName: string;
667    maxFreq: number;
668  } => {
669    let maxFreqObj = {
670      maxFreqName: ' ',
671      maxFreq: 0,
672    };
673    let units: Array<string> = ['', 'K', 'M', 'G', 'T', 'E'];
674    let sb = ' ';
675    if (maxFreq > 0) {
676      let log10: number = Math.ceil(Math.log10(maxFreq));
677      let pow10: number = Math.pow(10, log10);
678      let afterCeil: number = Math.ceil(maxFreq / (pow10 / 4)) * 1000;
679      let afterDivision: number = (afterCeil * ((pow10 / 4) * 1000)) / 1000000;
680      maxFreqObj.maxFreq = afterDivision;
681      let unitIndex: number = Math.floor(log10 / 3);
682      sb = `${afterDivision / Math.pow(10, unitIndex * 3)}${units[unitIndex + 1]}`;
683    }
684    maxFreqObj.maxFreqName = sb.toString();
685    return maxFreqObj;
686  };
687
688  public static getTimeIsCross(startTime: number, endTime: number, startTime1: number, endTime1: number): boolean {
689    return Math.max(startTime, startTime1) <= Math.min(endTime, endTime1);
690  }
691
692  initResponseTypeList(val: SelectionParam): void {
693    const isStatistic = val.nativeMemoryStatistic.length > 0;
694    const selection = isStatistic ? val.nativeMemoryStatistic : val.nativeMemory;
695    let types: Array<string | number> = [];
696    if (selection.indexOf('All Heap & Anonymous VM') !== -1) {
697      if (isStatistic) {
698        types.push(0, 1);
699      } else {
700        types.push("'AllocEvent'", "'MmapEvent'");
701      }
702    } else {
703      if (selection.indexOf('All Heap') !== -1) {
704        if (isStatistic) {
705          types.push(0);
706        } else {
707          types.push("'AllocEvent'");
708        }
709      }
710      if (selection.indexOf('All Anonymous VM') !== -1) {
711        if (isStatistic) {
712          types.push(1);
713        } else {
714          types.push("'MmapEvent'");
715        }
716      }
717    }
718    queryNativeHookResponseTypes(val.leftNs, val.rightNs, types, isStatistic).then((res): void => {
719      procedurePool.submitWithName('logic0', 'native-memory-init-responseType', res, undefined, (): void => { });
720    });
721  }
722
723  setCurrentSelectIPid(ipid: number): void {
724    procedurePool.submitWithName('logic0', 'native-memory-set-current_ipid', ipid, undefined, (): void => { });
725  }
726
727  public static convertJSON(arr: ArrayBuffer | Array<unknown>): unknown {
728    if (arr instanceof ArrayBuffer) {
729      let dec = new TextDecoder();
730      let str = dec.decode(arr);
731      let jsonArray: Array<unknown> = [];
732      str = str.substring(str.indexOf('\n') + 1);
733      if (!str) {
734      } else {
735        let parse;
736        let tansStr: string;
737        try {
738          tansStr = str.replace(/[\t\r\n]/g, '');
739          parse = JSON.parse(tansStr);
740        } catch {
741          try {
742            tansStr = tansStr!.replace(/[^\x20-\x7E]/g, '?'); //匹配乱码字 符,将其转换为?
743            parse = JSON.parse(tansStr);
744          } catch {
745            tansStr = tansStr!.replace(/\\/g, '\\\\');
746            parse = JSON.parse(tansStr);
747          }
748        }
749        let columns = parse.columns;
750        let values = parse.values;
751        for (let i = 0; i < values.length; i++) {
752          let obj: unknown = {};
753          for (let j = 0; j < columns.length; j++) {
754            //@ts-ignore
755            obj[columns[j]] = values[i][j];
756          }
757          jsonArray.push(obj);
758        }
759      }
760      return jsonArray;
761    } else {
762      return arr;
763    }
764  }
765}
766