1fb726d48Sopenharmony_ci// Copyright (c) 2021 Huawei Device Co., Ltd.
2fb726d48Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
3fb726d48Sopenharmony_ci// you may not use this file except in compliance with the License.
4fb726d48Sopenharmony_ci// You may obtain a copy of the License at
5fb726d48Sopenharmony_ci//
6fb726d48Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
7fb726d48Sopenharmony_ci//
8fb726d48Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
9fb726d48Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
10fb726d48Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11fb726d48Sopenharmony_ci// See the License for the specific language governing permissions and
12fb726d48Sopenharmony_ci// limitations under the License.
13fb726d48Sopenharmony_ci
14fb726d48Sopenharmony_ciimport { TraficEnum } from '../utils/QueryEnum';
15fb726d48Sopenharmony_ci
16fb726d48Sopenharmony_ciinterface HiPerfSampleType {
17fb726d48Sopenharmony_ci  callchainId: number;
18fb726d48Sopenharmony_ci  startTs: number;
19fb726d48Sopenharmony_ci  eventCount: number;
20fb726d48Sopenharmony_ci  threadId: number;
21fb726d48Sopenharmony_ci  cpuId: number;
22fb726d48Sopenharmony_ci  eventTypeId: number;
23fb726d48Sopenharmony_ci}
24fb726d48Sopenharmony_ci
25fb726d48Sopenharmony_ciconst dataCache: {
26fb726d48Sopenharmony_ci  startTs: Array<number>;
27fb726d48Sopenharmony_ci  dur: Array<number>;
28fb726d48Sopenharmony_ci  depth: Array<number>;
29fb726d48Sopenharmony_ci  eventCount: Array<number>;
30fb726d48Sopenharmony_ci  symbolId: Array<number>;
31fb726d48Sopenharmony_ci  fileId: Array<number>;
32fb726d48Sopenharmony_ci  callchainId: Array<number>;
33fb726d48Sopenharmony_ci  selfDur: Array<number>;
34fb726d48Sopenharmony_ci  name: Array<number>;
35fb726d48Sopenharmony_ci  callstack: Map<string, unknown>;
36fb726d48Sopenharmony_ci  sampleList: Array<HiPerfSampleType>;
37fb726d48Sopenharmony_ci  maxDepth: number;
38fb726d48Sopenharmony_ci} = {
39fb726d48Sopenharmony_ci  callstack: new Map<string, unknown>(),
40fb726d48Sopenharmony_ci  sampleList: [],
41fb726d48Sopenharmony_ci  maxDepth: 1,
42fb726d48Sopenharmony_ci  startTs: [],
43fb726d48Sopenharmony_ci  dur: [],
44fb726d48Sopenharmony_ci  depth: [],
45fb726d48Sopenharmony_ci  eventCount: [],
46fb726d48Sopenharmony_ci  symbolId: [],
47fb726d48Sopenharmony_ci  fileId: [],
48fb726d48Sopenharmony_ci  callchainId: [],
49fb726d48Sopenharmony_ci  selfDur: [],
50fb726d48Sopenharmony_ci  name: [],
51fb726d48Sopenharmony_ci};
52fb726d48Sopenharmony_ci
53fb726d48Sopenharmony_ciexport const chartHiperfCallChartDataSql = (args: unknown): string => {
54fb726d48Sopenharmony_ci  const sql = `
55fb726d48Sopenharmony_ci    select callchain_id                             as callchainId,
56fb726d48Sopenharmony_ci           timestamp_trace - ${
57fb726d48Sopenharmony_ci    // @ts-ignore
58fb726d48Sopenharmony_ci    args.recordStartNS
59fb726d48Sopenharmony_ci    }  as startTs,
60fb726d48Sopenharmony_ci           event_count                              as eventCount,
61fb726d48Sopenharmony_ci           A.thread_id                              as threadId,
62fb726d48Sopenharmony_ci           cpu_id                                   as cpuId,
63fb726d48Sopenharmony_ci           event_type_id                            as eventTypeId
64fb726d48Sopenharmony_ci    from perf_sample A
65fb726d48Sopenharmony_ci    where callchain_id != -1 and A.thread_id != 0
66fb726d48Sopenharmony_ci    order by cpuId, startTs`;
67fb726d48Sopenharmony_ci  return sql;
68fb726d48Sopenharmony_ci};
69fb726d48Sopenharmony_ci
70fb726d48Sopenharmony_ciexport function hiPerfCallChartDataHandler(data: unknown, proc: Function): void {
71fb726d48Sopenharmony_ci  // @ts-ignore
72fb726d48Sopenharmony_ci  if (data.params.isCache) {
73fb726d48Sopenharmony_ci    // @ts-ignore
74fb726d48Sopenharmony_ci    let res: Array<unknown> = proc(chartHiperfCallChartDataSql(data.params));
75fb726d48Sopenharmony_ci    for (let i = 0; i < res.length; i++) {
76fb726d48Sopenharmony_ci      if (i > 0) {
77fb726d48Sopenharmony_ci        // @ts-ignore
78fb726d48Sopenharmony_ci        if (res[i].cpuId === res[i - 1].cpuId) {
79fb726d48Sopenharmony_ci          // @ts-ignore
80fb726d48Sopenharmony_ci          res[i - 1].dur = res[i].startTs - res[i - 1].startTs;
81fb726d48Sopenharmony_ci        } else {
82fb726d48Sopenharmony_ci          // @ts-ignore
83fb726d48Sopenharmony_ci          res[i - 1].dur = data.params.recordEndNS - data.params.recordStartNS - res[i - 1].startTs;
84fb726d48Sopenharmony_ci        }
85fb726d48Sopenharmony_ci      }
86fb726d48Sopenharmony_ci      if (i === res.length - 1) {
87fb726d48Sopenharmony_ci        // @ts-ignore
88fb726d48Sopenharmony_ci        res[i].dur = data.params.recordEndNS - data.params.recordStartNS - res[i].startTs;
89fb726d48Sopenharmony_ci      }
90fb726d48Sopenharmony_ci    }
91fb726d48Sopenharmony_ci    // @ts-ignore
92fb726d48Sopenharmony_ci    dataCache.sampleList = res;
93fb726d48Sopenharmony_ci    (self as unknown as Worker).postMessage(
94fb726d48Sopenharmony_ci      {
95fb726d48Sopenharmony_ci        len: 0,
96fb726d48Sopenharmony_ci        // @ts-ignore
97fb726d48Sopenharmony_ci        id: data.id,
98fb726d48Sopenharmony_ci        // @ts-ignore
99fb726d48Sopenharmony_ci        action: data.action,
100fb726d48Sopenharmony_ci        results: 'ok',
101fb726d48Sopenharmony_ci      },
102fb726d48Sopenharmony_ci      []
103fb726d48Sopenharmony_ci    );
104fb726d48Sopenharmony_ci  } else {
105fb726d48Sopenharmony_ci    let res: Array<unknown> = [];
106fb726d48Sopenharmony_ci    // @ts-ignore
107fb726d48Sopenharmony_ci    if (!data.params.isComplete) {
108fb726d48Sopenharmony_ci      res = dataCache.sampleList.filter((it) => {
109fb726d48Sopenharmony_ci        // @ts-ignore
110fb726d48Sopenharmony_ci        let cpuThreadFilter = data.params.type === 0 ? it.cpuId === data.params.id : it.threadId === data.params.id;
111fb726d48Sopenharmony_ci        // @ts-ignore
112fb726d48Sopenharmony_ci        let eventTypeFilter = data.params.eventTypeId === -2 ? true : it.eventTypeId === data.params.eventTypeId;
113fb726d48Sopenharmony_ci        return cpuThreadFilter && eventTypeFilter;
114fb726d48Sopenharmony_ci      });
115fb726d48Sopenharmony_ci    }
116fb726d48Sopenharmony_ci    // @ts-ignore
117fb726d48Sopenharmony_ci    arrayBufferHandler(data, res, true, !data.params.isComplete);
118fb726d48Sopenharmony_ci  }
119fb726d48Sopenharmony_ci}
120fb726d48Sopenharmony_ci
121fb726d48Sopenharmony_ciexport function hiPerfCallStackCacheHandler(data: unknown, proc: Function): void {
122fb726d48Sopenharmony_ci  // @ts-ignore
123fb726d48Sopenharmony_ci  if (data.params.isCache) {
124fb726d48Sopenharmony_ci    hiPerfCallChartClearCache(true);
125fb726d48Sopenharmony_ci    arrayBufferCallStackHandler(data, proc(hiPerfCallStackDataCacheSql()));
126fb726d48Sopenharmony_ci  }
127fb726d48Sopenharmony_ci}
128fb726d48Sopenharmony_ci
129fb726d48Sopenharmony_cifunction arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean, loadData: boolean): void {
130fb726d48Sopenharmony_ci  if (loadData) {
131fb726d48Sopenharmony_ci    // @ts-ignore
132fb726d48Sopenharmony_ci    if (data.params.type !== 0) {
133fb726d48Sopenharmony_ci      // @ts-ignore
134fb726d48Sopenharmony_ci      res.sort((a, b) => a.startTs - b.startTs);
135fb726d48Sopenharmony_ci      for (let i = 0; i < res.length; i++) {
136fb726d48Sopenharmony_ci        if (i < res.length - 1) {
137fb726d48Sopenharmony_ci          // @ts-ignore
138fb726d48Sopenharmony_ci          res[i].dur = res[i + 1].startTs - res[i].startTs;
139fb726d48Sopenharmony_ci        } else {
140fb726d48Sopenharmony_ci          // @ts-ignore
141fb726d48Sopenharmony_ci          res[i].dur = data.params.endNS - data.params.startNS - res[i].startTs;
142fb726d48Sopenharmony_ci        }
143fb726d48Sopenharmony_ci      }
144fb726d48Sopenharmony_ci    }
145fb726d48Sopenharmony_ci    // @ts-ignore
146fb726d48Sopenharmony_ci    let result = combinePerfSampleByCallChainId(res, data.params);
147fb726d48Sopenharmony_ci    hiPerfCallChartClearCache(false);
148fb726d48Sopenharmony_ci    const getArrayData = (combineData: Array<unknown>): void => {
149fb726d48Sopenharmony_ci      for (let item of combineData) {
150fb726d48Sopenharmony_ci        // @ts-ignore
151fb726d48Sopenharmony_ci        if (item.depth > -1) {
152fb726d48Sopenharmony_ci          // @ts-ignore
153fb726d48Sopenharmony_ci          dataCache.startTs.push(item.startTime);
154fb726d48Sopenharmony_ci          // @ts-ignore
155fb726d48Sopenharmony_ci          dataCache.dur.push(item.totalTime);
156fb726d48Sopenharmony_ci          // @ts-ignore
157fb726d48Sopenharmony_ci          dataCache.depth.push(item.depth);
158fb726d48Sopenharmony_ci          // @ts-ignore
159fb726d48Sopenharmony_ci          dataCache.eventCount.push(item.eventCount);
160fb726d48Sopenharmony_ci          // @ts-ignore
161fb726d48Sopenharmony_ci          dataCache.symbolId.push(item.symbolId);
162fb726d48Sopenharmony_ci          // @ts-ignore
163fb726d48Sopenharmony_ci          dataCache.fileId.push(item.fileId);
164fb726d48Sopenharmony_ci          // @ts-ignore
165fb726d48Sopenharmony_ci          dataCache.callchainId.push(item.callchainId);
166fb726d48Sopenharmony_ci          // @ts-ignore
167fb726d48Sopenharmony_ci          dataCache.name.push(item.name);
168fb726d48Sopenharmony_ci          // @ts-ignore
169fb726d48Sopenharmony_ci          let self = item.totalTime || 0;
170fb726d48Sopenharmony_ci          // @ts-ignore
171fb726d48Sopenharmony_ci          if (item.children) {
172fb726d48Sopenharmony_ci            // @ts-ignore
173fb726d48Sopenharmony_ci            (item.children as Array<unknown>).forEach((child) => {
174fb726d48Sopenharmony_ci              // @ts-ignore
175fb726d48Sopenharmony_ci              self -= child.totalTime;
176fb726d48Sopenharmony_ci            });
177fb726d48Sopenharmony_ci          }
178fb726d48Sopenharmony_ci          dataCache.selfDur.push(self);
179fb726d48Sopenharmony_ci        }
180fb726d48Sopenharmony_ci        // @ts-ignore
181fb726d48Sopenharmony_ci        if (item.depth + 1 > dataCache.maxDepth) {
182fb726d48Sopenharmony_ci          // @ts-ignore
183fb726d48Sopenharmony_ci          dataCache.maxDepth = item.depth + 1;
184fb726d48Sopenharmony_ci        }
185fb726d48Sopenharmony_ci        // @ts-ignore
186fb726d48Sopenharmony_ci        if (item.children && item.children.length > 0) {
187fb726d48Sopenharmony_ci          // @ts-ignore
188fb726d48Sopenharmony_ci          getArrayData(item.children);
189fb726d48Sopenharmony_ci        }
190fb726d48Sopenharmony_ci      }
191fb726d48Sopenharmony_ci    };
192fb726d48Sopenharmony_ci    getArrayData(result);
193fb726d48Sopenharmony_ci  }
194fb726d48Sopenharmony_ci  setTimeout((): void => {
195fb726d48Sopenharmony_ci    arrayBufferCallback(data, transfer);
196fb726d48Sopenharmony_ci  }, 150);
197fb726d48Sopenharmony_ci}
198fb726d48Sopenharmony_ci
199fb726d48Sopenharmony_cifunction arrayBufferCallback(data: unknown, transfer: boolean): void {
200fb726d48Sopenharmony_ci  // @ts-ignore
201fb726d48Sopenharmony_ci  let params = data.params;
202fb726d48Sopenharmony_ci  let dataFilter = filterPerfCallChartData(params.startNS, params.endNS, params.totalNS, params.frame, params.expand);
203fb726d48Sopenharmony_ci  let len = dataFilter.startTs.length;
204fb726d48Sopenharmony_ci  let perfCallChart = new PerfCallChart(len);
205fb726d48Sopenharmony_ci  for (let i = 0; i < len; i++) {
206fb726d48Sopenharmony_ci    perfCallChart.startTs[i] = dataFilter.startTs[i];
207fb726d48Sopenharmony_ci    perfCallChart.dur[i] = dataFilter.dur[i];
208fb726d48Sopenharmony_ci    perfCallChart.depth[i] = dataFilter.depth[i];
209fb726d48Sopenharmony_ci    perfCallChart.eventCount[i] = dataFilter.eventCount[i];
210fb726d48Sopenharmony_ci    perfCallChart.symbolId[i] = dataFilter.symbolId[i];
211fb726d48Sopenharmony_ci    perfCallChart.fileId[i] = dataFilter.fileId[i];
212fb726d48Sopenharmony_ci    perfCallChart.callchainId[i] = dataFilter.callchainId[i];
213fb726d48Sopenharmony_ci    perfCallChart.selfDur[i] = dataFilter.selfDur[i];
214fb726d48Sopenharmony_ci    perfCallChart.name[i] = dataFilter.name[i];
215fb726d48Sopenharmony_ci  }
216fb726d48Sopenharmony_ci  postPerfCallChartMessage(data, transfer, perfCallChart, len);
217fb726d48Sopenharmony_ci}
218fb726d48Sopenharmony_cifunction postPerfCallChartMessage(data: unknown, transfer: boolean, perfCallChart: PerfCallChart, len: number): void {
219fb726d48Sopenharmony_ci  (self as unknown as Worker).postMessage(
220fb726d48Sopenharmony_ci    {
221fb726d48Sopenharmony_ci      // @ts-ignore
222fb726d48Sopenharmony_ci      id: data.id,
223fb726d48Sopenharmony_ci      // @ts-ignore
224fb726d48Sopenharmony_ci      action: data.action,
225fb726d48Sopenharmony_ci      results: transfer
226fb726d48Sopenharmony_ci        ? {
227fb726d48Sopenharmony_ci          startTs: perfCallChart.startTs.buffer,
228fb726d48Sopenharmony_ci          dur: perfCallChart.dur.buffer,
229fb726d48Sopenharmony_ci          depth: perfCallChart.depth.buffer,
230fb726d48Sopenharmony_ci          callchainId: perfCallChart.callchainId.buffer,
231fb726d48Sopenharmony_ci          eventCount: perfCallChart.eventCount.buffer,
232fb726d48Sopenharmony_ci          symbolId: perfCallChart.symbolId.buffer,
233fb726d48Sopenharmony_ci          fileId: perfCallChart.fileId.buffer,
234fb726d48Sopenharmony_ci          selfDur: perfCallChart.selfDur.buffer,
235fb726d48Sopenharmony_ci          name: perfCallChart.name.buffer,
236fb726d48Sopenharmony_ci          maxDepth: dataCache.maxDepth,
237fb726d48Sopenharmony_ci        }
238fb726d48Sopenharmony_ci        : {},
239fb726d48Sopenharmony_ci      len: len,
240fb726d48Sopenharmony_ci    },
241fb726d48Sopenharmony_ci    transfer
242fb726d48Sopenharmony_ci      ? [
243fb726d48Sopenharmony_ci        perfCallChart.startTs.buffer,
244fb726d48Sopenharmony_ci        perfCallChart.dur.buffer,
245fb726d48Sopenharmony_ci        perfCallChart.depth.buffer,
246fb726d48Sopenharmony_ci        perfCallChart.callchainId.buffer,
247fb726d48Sopenharmony_ci        perfCallChart.eventCount.buffer,
248fb726d48Sopenharmony_ci        perfCallChart.symbolId.buffer,
249fb726d48Sopenharmony_ci        perfCallChart.fileId.buffer,
250fb726d48Sopenharmony_ci        perfCallChart.selfDur.buffer,
251fb726d48Sopenharmony_ci        perfCallChart.name.buffer,
252fb726d48Sopenharmony_ci      ]
253fb726d48Sopenharmony_ci      : []
254fb726d48Sopenharmony_ci  );
255fb726d48Sopenharmony_ci}
256fb726d48Sopenharmony_ci
257fb726d48Sopenharmony_ciexport function filterPerfCallChartData(
258fb726d48Sopenharmony_ci  startNS: number,
259fb726d48Sopenharmony_ci  endNS: number,
260fb726d48Sopenharmony_ci  totalNS: number,
261fb726d48Sopenharmony_ci  frame: unknown,
262fb726d48Sopenharmony_ci  expand: boolean
263fb726d48Sopenharmony_ci): DataSource {
264fb726d48Sopenharmony_ci  let dataSource = new DataSource();
265fb726d48Sopenharmony_ci  let data: unknown = {};
266fb726d48Sopenharmony_ci  dataCache.startTs.reduce((pre, current, index) => {
267fb726d48Sopenharmony_ci    if (
268fb726d48Sopenharmony_ci      dataCache.dur[index] > 0 &&
269fb726d48Sopenharmony_ci      current + dataCache.dur[index] >= startNS &&
270fb726d48Sopenharmony_ci      current <= endNS &&
271fb726d48Sopenharmony_ci      ((!expand && dataCache.depth[index] === 0) || expand)
272fb726d48Sopenharmony_ci    ) {
273fb726d48Sopenharmony_ci      let x = 0;
274fb726d48Sopenharmony_ci      if (current > startNS && current < endNS) {
275fb726d48Sopenharmony_ci        x = Math.trunc(ns2x(current, startNS, endNS, totalNS, frame));
276fb726d48Sopenharmony_ci      } else {
277fb726d48Sopenharmony_ci        x = 0;
278fb726d48Sopenharmony_ci      }
279fb726d48Sopenharmony_ci      let key = `${x}-${dataCache.depth[index]}`;
280fb726d48Sopenharmony_ci      // @ts-ignore
281fb726d48Sopenharmony_ci      let preIndex = pre[key];
282fb726d48Sopenharmony_ci      if (preIndex !== undefined) {
283fb726d48Sopenharmony_ci        // @ts-ignore
284fb726d48Sopenharmony_ci        pre[key] = dataCache.dur[preIndex] > dataCache.dur[index] ? preIndex : index;
285fb726d48Sopenharmony_ci      } else {
286fb726d48Sopenharmony_ci        // @ts-ignore
287fb726d48Sopenharmony_ci        pre[key] = index;
288fb726d48Sopenharmony_ci      }
289fb726d48Sopenharmony_ci    }
290fb726d48Sopenharmony_ci    return pre;
291fb726d48Sopenharmony_ci  }, data);
292fb726d48Sopenharmony_ci  setDataSource(data, dataSource);
293fb726d48Sopenharmony_ci  return dataSource;
294fb726d48Sopenharmony_ci}
295fb726d48Sopenharmony_cifunction setDataSource(data: unknown, dataSource: DataSource): void {
296fb726d48Sopenharmony_ci  // @ts-ignore
297fb726d48Sopenharmony_ci  Reflect.ownKeys(data).map((kv: string | symbol): void => {
298fb726d48Sopenharmony_ci    // @ts-ignore
299fb726d48Sopenharmony_ci    let index = data[kv as string] as number;
300fb726d48Sopenharmony_ci    // @ts-ignore
301fb726d48Sopenharmony_ci    dataSource.startTs.push(dataCache.startTs[index]);
302fb726d48Sopenharmony_ci    dataSource.dur.push(dataCache.dur[index]);
303fb726d48Sopenharmony_ci    dataSource.depth.push(dataCache.depth[index]);
304fb726d48Sopenharmony_ci    dataSource.eventCount.push(dataCache.eventCount[index]);
305fb726d48Sopenharmony_ci    dataSource.symbolId.push(dataCache.symbolId[index]);
306fb726d48Sopenharmony_ci    dataSource.fileId.push(dataCache.fileId[index]);
307fb726d48Sopenharmony_ci    dataSource.callchainId.push(dataCache.callchainId[index]);
308fb726d48Sopenharmony_ci    dataSource.selfDur.push(dataCache.selfDur[index]);
309fb726d48Sopenharmony_ci    dataSource.name.push(dataCache.name[index]);
310fb726d48Sopenharmony_ci  });
311fb726d48Sopenharmony_ci}
312fb726d48Sopenharmony_ci// 将perf_sample表的数据根据callchain_id分组并赋值startTime,endTime等等
313fb726d48Sopenharmony_cifunction combinePerfSampleByCallChainId(sampleList: Array<unknown>, params: unknown): unknown[] {
314fb726d48Sopenharmony_ci  return combineChartData(
315fb726d48Sopenharmony_ci    sampleList.map((sample) => {
316fb726d48Sopenharmony_ci      let perfSample: unknown = {};
317fb726d48Sopenharmony_ci      // @ts-ignore
318fb726d48Sopenharmony_ci      perfSample.children = [];
319fb726d48Sopenharmony_ci      // @ts-ignore
320fb726d48Sopenharmony_ci      perfSample.children[0] = {};
321fb726d48Sopenharmony_ci      // @ts-ignore
322fb726d48Sopenharmony_ci      perfSample.depth = -1;
323fb726d48Sopenharmony_ci      // @ts-ignore
324fb726d48Sopenharmony_ci      perfSample.callchainId = sample.callchainId;
325fb726d48Sopenharmony_ci      // @ts-ignore
326fb726d48Sopenharmony_ci      perfSample.threadId = sample.threadId;
327fb726d48Sopenharmony_ci      // @ts-ignore
328fb726d48Sopenharmony_ci      perfSample.id = sample.id;
329fb726d48Sopenharmony_ci      // @ts-ignore
330fb726d48Sopenharmony_ci      perfSample.cpuId = sample.cpuId;
331fb726d48Sopenharmony_ci      // @ts-ignore
332fb726d48Sopenharmony_ci      perfSample.startTime = sample.startTs;
333fb726d48Sopenharmony_ci      // @ts-ignore
334fb726d48Sopenharmony_ci      perfSample.endTime = sample.startTs + sample.dur;
335fb726d48Sopenharmony_ci      // @ts-ignore
336fb726d48Sopenharmony_ci      perfSample.totalTime = sample.dur;
337fb726d48Sopenharmony_ci      // @ts-ignore
338fb726d48Sopenharmony_ci      perfSample.eventCount = sample.eventCount;
339fb726d48Sopenharmony_ci      return perfSample;
340fb726d48Sopenharmony_ci    }),
341fb726d48Sopenharmony_ci    params
342fb726d48Sopenharmony_ci  );
343fb726d48Sopenharmony_ci}
344fb726d48Sopenharmony_ci
345fb726d48Sopenharmony_cifunction combineChartData(samples: unknown, params: unknown): Array<unknown> {
346fb726d48Sopenharmony_ci  let combineSample: unknown = [];
347fb726d48Sopenharmony_ci  // 遍历sample表查到的数据,并且为其匹配相应的callchain数据
348fb726d48Sopenharmony_ci  // @ts-ignore
349fb726d48Sopenharmony_ci  for (let sample of samples) {
350fb726d48Sopenharmony_ci    let stackTop = dataCache.callstack.get(`${sample.callchainId}-0`);
351fb726d48Sopenharmony_ci    if (stackTop) {
352fb726d48Sopenharmony_ci      let stackTopSymbol = JSON.parse(JSON.stringify(stackTop));
353fb726d48Sopenharmony_ci      stackTopSymbol.startTime = sample.startTime;
354fb726d48Sopenharmony_ci      stackTopSymbol.endTime = sample.endTime;
355fb726d48Sopenharmony_ci      stackTopSymbol.totalTime = sample.totalTime;
356fb726d48Sopenharmony_ci      stackTopSymbol.threadId = sample.threadId;
357fb726d48Sopenharmony_ci      stackTopSymbol.cpuId = sample.cpuId;
358fb726d48Sopenharmony_ci      stackTopSymbol.eventCount = sample.eventCount;
359fb726d48Sopenharmony_ci      setDur(stackTopSymbol);
360fb726d48Sopenharmony_ci      sample.children = [];
361fb726d48Sopenharmony_ci      sample.children.push(stackTopSymbol);
362fb726d48Sopenharmony_ci      // 每一项都和combineSample对比
363fb726d48Sopenharmony_ci      // @ts-ignore
364fb726d48Sopenharmony_ci      if (combineSample.length === 0) {
365fb726d48Sopenharmony_ci        // @ts-ignore
366fb726d48Sopenharmony_ci        combineSample.push(sample);
367fb726d48Sopenharmony_ci      } else {
368fb726d48Sopenharmony_ci        // @ts-ignore
369fb726d48Sopenharmony_ci        let pre = combineSample[combineSample.length - 1];
370fb726d48Sopenharmony_ci        // @ts-ignore
371fb726d48Sopenharmony_ci        if (params.type === 0) {
372fb726d48Sopenharmony_ci          if (pre.threadId === sample.threadId && pre.endTime === sample.startTime) {
373fb726d48Sopenharmony_ci            // @ts-ignore
374fb726d48Sopenharmony_ci            combinePerfCallData(combineSample[combineSample.length - 1], sample);
375fb726d48Sopenharmony_ci          } else {
376fb726d48Sopenharmony_ci            // @ts-ignore
377fb726d48Sopenharmony_ci            combineSample.push(sample);
378fb726d48Sopenharmony_ci          }
379fb726d48Sopenharmony_ci        } else {
380fb726d48Sopenharmony_ci          // @ts-ignore
381fb726d48Sopenharmony_ci          combinePerfCallData(combineSample[combineSample.length - 1], sample);
382fb726d48Sopenharmony_ci        }
383fb726d48Sopenharmony_ci      }
384fb726d48Sopenharmony_ci    }
385fb726d48Sopenharmony_ci  }
386fb726d48Sopenharmony_ci  // @ts-ignore
387fb726d48Sopenharmony_ci  return combineSample;
388fb726d48Sopenharmony_ci}
389fb726d48Sopenharmony_ci
390fb726d48Sopenharmony_ci// 递归设置dur,startTime,endTime
391fb726d48Sopenharmony_cifunction setDur(data: unknown): void {
392fb726d48Sopenharmony_ci  // @ts-ignore
393fb726d48Sopenharmony_ci  if (data.children && data.children.length > 0) {
394fb726d48Sopenharmony_ci    // @ts-ignore
395fb726d48Sopenharmony_ci    data.children[0].totalTime = data.totalTime;
396fb726d48Sopenharmony_ci    // @ts-ignore
397fb726d48Sopenharmony_ci    data.children[0].startTime = data.startTime;
398fb726d48Sopenharmony_ci    // @ts-ignore
399fb726d48Sopenharmony_ci    data.children[0].endTime = data.endTime;
400fb726d48Sopenharmony_ci    // @ts-ignore
401fb726d48Sopenharmony_ci    data.children[0].threadId = data.threadId;
402fb726d48Sopenharmony_ci    // @ts-ignore
403fb726d48Sopenharmony_ci    data.children[0].cpuId = data.cpuId;
404fb726d48Sopenharmony_ci    // @ts-ignore
405fb726d48Sopenharmony_ci    data.children[0].eventCount = data.eventCount;
406fb726d48Sopenharmony_ci    // @ts-ignore
407fb726d48Sopenharmony_ci    setDur(data.children[0]);
408fb726d48Sopenharmony_ci  } else {
409fb726d48Sopenharmony_ci    return;
410fb726d48Sopenharmony_ci  }
411fb726d48Sopenharmony_ci}
412fb726d48Sopenharmony_ci
413fb726d48Sopenharmony_ci// hiperf火焰图合并逻辑
414fb726d48Sopenharmony_cifunction combinePerfCallData(data1: unknown, data2: unknown): void {
415fb726d48Sopenharmony_ci  if (fixMergeRuler(data1, data2)) {
416fb726d48Sopenharmony_ci    // @ts-ignore
417fb726d48Sopenharmony_ci    data1.endTime = data2.endTime;
418fb726d48Sopenharmony_ci    // @ts-ignore
419fb726d48Sopenharmony_ci    data1.totalTime = data1.endTime - data1.startTime;
420fb726d48Sopenharmony_ci    // @ts-ignore
421fb726d48Sopenharmony_ci    data1.eventCount += data2.eventCount;
422fb726d48Sopenharmony_ci    // @ts-ignore
423fb726d48Sopenharmony_ci    if (data1.children && data1.children.length > 0 && data2.children && data2.children.length > 0) {
424fb726d48Sopenharmony_ci      // @ts-ignore
425fb726d48Sopenharmony_ci      if (fixMergeRuler(data1.children[data1.children.length - 1], data2.children[0])) {
426fb726d48Sopenharmony_ci        // @ts-ignore
427fb726d48Sopenharmony_ci        combinePerfCallData(data1.children[data1.children.length - 1], data2.children[0]);
428fb726d48Sopenharmony_ci      } else {
429fb726d48Sopenharmony_ci        // @ts-ignore
430fb726d48Sopenharmony_ci        if (data1.children[data1.children.length - 1].depth === data2.children[0].depth) {
431fb726d48Sopenharmony_ci          // @ts-ignore
432fb726d48Sopenharmony_ci          data1.children.push(data2.children[0]);
433fb726d48Sopenharmony_ci        }
434fb726d48Sopenharmony_ci      }
435fb726d48Sopenharmony_ci      // @ts-ignore
436fb726d48Sopenharmony_ci    } else if (data2.children && data2.children.length > 0 && (!data1.children || data1.children.length === 0)) {
437fb726d48Sopenharmony_ci      // @ts-ignore
438fb726d48Sopenharmony_ci      data1.endTime = data2.endTime;
439fb726d48Sopenharmony_ci      // @ts-ignore
440fb726d48Sopenharmony_ci      data1.totalTime = data1.endTime - data1.startTime;
441fb726d48Sopenharmony_ci      // @ts-ignore
442fb726d48Sopenharmony_ci      data1.children = [];
443fb726d48Sopenharmony_ci      // @ts-ignore
444fb726d48Sopenharmony_ci      data1.children.push(data2.children[0]);
445fb726d48Sopenharmony_ci    } else {
446fb726d48Sopenharmony_ci    }
447fb726d48Sopenharmony_ci  }
448fb726d48Sopenharmony_ci  return;
449fb726d48Sopenharmony_ci}
450fb726d48Sopenharmony_ci
451fb726d48Sopenharmony_ci/**
452fb726d48Sopenharmony_ci * 合并规则
453fb726d48Sopenharmony_ci * @param data1
454fb726d48Sopenharmony_ci * @param data2
455fb726d48Sopenharmony_ci */
456fb726d48Sopenharmony_cifunction fixMergeRuler(data1: unknown, data2: unknown): boolean {
457fb726d48Sopenharmony_ci  // @ts-ignore
458fb726d48Sopenharmony_ci  return data1.depth === data2.depth && data1.name === data2.name;
459fb726d48Sopenharmony_ci}
460fb726d48Sopenharmony_ci
461fb726d48Sopenharmony_ciexport const hiPerfCallStackDataCacheSql = (): string => {
462fb726d48Sopenharmony_ci  return `select c.callchain_id as callchainId,
463fb726d48Sopenharmony_ci                 c.file_id   as fileId,
464fb726d48Sopenharmony_ci                 c.depth,
465fb726d48Sopenharmony_ci                 c.symbol_id as symbolId,
466fb726d48Sopenharmony_ci                 c.name
467fb726d48Sopenharmony_ci          from perf_callchain c
468fb726d48Sopenharmony_ci          where callchain_id != -1;`;
469fb726d48Sopenharmony_ci};
470fb726d48Sopenharmony_ci
471fb726d48Sopenharmony_ciexport function hiPerfCallChartClearCache(clearStack: boolean): void {
472fb726d48Sopenharmony_ci  if (clearStack) {
473fb726d48Sopenharmony_ci    dataCache.callstack.clear();
474fb726d48Sopenharmony_ci    dataCache.sampleList.length = 0;
475fb726d48Sopenharmony_ci  }
476fb726d48Sopenharmony_ci  dataCache.startTs = [];
477fb726d48Sopenharmony_ci  dataCache.dur = [];
478fb726d48Sopenharmony_ci  dataCache.depth = [];
479fb726d48Sopenharmony_ci  dataCache.eventCount = [];
480fb726d48Sopenharmony_ci  dataCache.symbolId = [];
481fb726d48Sopenharmony_ci  dataCache.fileId = [];
482fb726d48Sopenharmony_ci  dataCache.callchainId = [];
483fb726d48Sopenharmony_ci  dataCache.selfDur = [];
484fb726d48Sopenharmony_ci  dataCache.name = [];
485fb726d48Sopenharmony_ci  dataCache.maxDepth = 1;
486fb726d48Sopenharmony_ci}
487fb726d48Sopenharmony_ci
488fb726d48Sopenharmony_cifunction arrayBufferCallStackHandler(data: unknown, res: unknown[]): void {
489fb726d48Sopenharmony_ci  for (const stack of res) {
490fb726d48Sopenharmony_ci    let item = stack;
491fb726d48Sopenharmony_ci    // @ts-ignore
492fb726d48Sopenharmony_ci    if (data.params.trafic === TraficEnum.ProtoBuffer) {
493fb726d48Sopenharmony_ci      item = {
494fb726d48Sopenharmony_ci        // @ts-ignore
495fb726d48Sopenharmony_ci        callchainId: stack.hiperfCallStackData.callchainId || 0,
496fb726d48Sopenharmony_ci        // @ts-ignore
497fb726d48Sopenharmony_ci        fileId: stack.hiperfCallStackData.fileId || 0,
498fb726d48Sopenharmony_ci        // @ts-ignore
499fb726d48Sopenharmony_ci        depth: stack.hiperfCallStackData.depth || 0,
500fb726d48Sopenharmony_ci        // @ts-ignore
501fb726d48Sopenharmony_ci        symbolId: stack.hiperfCallStackData.symbolId || 0,
502fb726d48Sopenharmony_ci        // @ts-ignore
503fb726d48Sopenharmony_ci        name: stack.hiperfCallStackData.name || 0,
504fb726d48Sopenharmony_ci      };
505fb726d48Sopenharmony_ci    }
506fb726d48Sopenharmony_ci    // @ts-ignore
507fb726d48Sopenharmony_ci    dataCache.callstack.set(`${item.callchainId}-${item.depth}`, item);
508fb726d48Sopenharmony_ci    // @ts-ignore
509fb726d48Sopenharmony_ci    let parentSymbol = dataCache.callstack.get(`${item.callchainId}-${item.depth - 1}`);
510fb726d48Sopenharmony_ci    // @ts-ignore
511fb726d48Sopenharmony_ci    if (parentSymbol && parentSymbol.callchainId === item.callchainId && parentSymbol.depth === item.depth - 1) {
512fb726d48Sopenharmony_ci      // @ts-ignore
513fb726d48Sopenharmony_ci      parentSymbol.children = [];
514fb726d48Sopenharmony_ci      // @ts-ignore
515fb726d48Sopenharmony_ci      parentSymbol.children.push(item);
516fb726d48Sopenharmony_ci    }
517fb726d48Sopenharmony_ci  }
518fb726d48Sopenharmony_ci  for (let key of Array.from(dataCache.callstack.keys())) {
519fb726d48Sopenharmony_ci    if (!key.endsWith('-0')) {
520fb726d48Sopenharmony_ci      dataCache.callstack.delete(key);
521fb726d48Sopenharmony_ci    }
522fb726d48Sopenharmony_ci  }
523fb726d48Sopenharmony_ci  (self as unknown as Worker).postMessage(
524fb726d48Sopenharmony_ci    {
525fb726d48Sopenharmony_ci      // @ts-ignore
526fb726d48Sopenharmony_ci      id: data.id,
527fb726d48Sopenharmony_ci      // @ts-ignore
528fb726d48Sopenharmony_ci      action: data.action,
529fb726d48Sopenharmony_ci      results: 'ok',
530fb726d48Sopenharmony_ci      len: res.length,
531fb726d48Sopenharmony_ci    },
532fb726d48Sopenharmony_ci    []
533fb726d48Sopenharmony_ci  );
534fb726d48Sopenharmony_ci}
535fb726d48Sopenharmony_ci
536fb726d48Sopenharmony_cifunction ns2x(ns: number, startNS: number, endNS: number, duration: number, rect: unknown): number {
537fb726d48Sopenharmony_ci  if (endNS === 0) {
538fb726d48Sopenharmony_ci    endNS = duration;
539fb726d48Sopenharmony_ci  }
540fb726d48Sopenharmony_ci  // @ts-ignore
541fb726d48Sopenharmony_ci  let xSizeHiperf: number = ((ns - startNS) * rect.width) / (endNS - startNS);
542fb726d48Sopenharmony_ci  if (xSizeHiperf < 0) {
543fb726d48Sopenharmony_ci    xSizeHiperf = 0;
544fb726d48Sopenharmony_ci    // @ts-ignore
545fb726d48Sopenharmony_ci  } else if (xSizeHiperf > rect.width) {
546fb726d48Sopenharmony_ci    // @ts-ignore
547fb726d48Sopenharmony_ci    xSizeHiperf = rect.width;
548fb726d48Sopenharmony_ci  }
549fb726d48Sopenharmony_ci  return xSizeHiperf;
550fb726d48Sopenharmony_ci}
551fb726d48Sopenharmony_ciclass PerfCallChart {
552fb726d48Sopenharmony_ci  startTs: Float64Array;
553fb726d48Sopenharmony_ci  dur: Float64Array;
554fb726d48Sopenharmony_ci  depth: Int32Array;
555fb726d48Sopenharmony_ci  eventCount: Int32Array;
556fb726d48Sopenharmony_ci  symbolId: Int32Array;
557fb726d48Sopenharmony_ci  fileId: Int32Array;
558fb726d48Sopenharmony_ci  callchainId: Int32Array;
559fb726d48Sopenharmony_ci  selfDur: Int32Array;
560fb726d48Sopenharmony_ci  name: Int32Array;
561fb726d48Sopenharmony_ci  constructor(len: number) {
562fb726d48Sopenharmony_ci    this.startTs = new Float64Array(len);
563fb726d48Sopenharmony_ci    this.dur = new Float64Array(len);
564fb726d48Sopenharmony_ci    this.depth = new Int32Array(len);
565fb726d48Sopenharmony_ci    this.eventCount = new Int32Array(len);
566fb726d48Sopenharmony_ci    this.symbolId = new Int32Array(len);
567fb726d48Sopenharmony_ci    this.fileId = new Int32Array(len);
568fb726d48Sopenharmony_ci    this.callchainId = new Int32Array(len);
569fb726d48Sopenharmony_ci    this.selfDur = new Int32Array(len);
570fb726d48Sopenharmony_ci    this.name = new Int32Array(len);
571fb726d48Sopenharmony_ci  }
572fb726d48Sopenharmony_ci}
573fb726d48Sopenharmony_ciclass DataSource {
574fb726d48Sopenharmony_ci  startTs: Array<number>;
575fb726d48Sopenharmony_ci  dur: Array<number>;
576fb726d48Sopenharmony_ci  depth: Array<number>;
577fb726d48Sopenharmony_ci  eventCount: Array<number>;
578fb726d48Sopenharmony_ci  symbolId: Array<number>;
579fb726d48Sopenharmony_ci  fileId: Array<number>;
580fb726d48Sopenharmony_ci  callchainId: Array<number>;
581fb726d48Sopenharmony_ci  selfDur: Array<number>;
582fb726d48Sopenharmony_ci  name: Array<number>;
583fb726d48Sopenharmony_ci  constructor() {
584fb726d48Sopenharmony_ci    this.startTs = [];
585fb726d48Sopenharmony_ci    this.dur = [];
586fb726d48Sopenharmony_ci    this.depth = [];
587fb726d48Sopenharmony_ci    this.eventCount = [];
588fb726d48Sopenharmony_ci    this.symbolId = [];
589fb726d48Sopenharmony_ci    this.fileId = [];
590fb726d48Sopenharmony_ci    this.callchainId = [];
591fb726d48Sopenharmony_ci    this.selfDur = [];
592fb726d48Sopenharmony_ci    this.name = [];
593fb726d48Sopenharmony_ci  }
594fb726d48Sopenharmony_ci}
595