1fb726d48Sopenharmony_ci/*
2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb726d48Sopenharmony_ci * You may obtain a copy of the License at
6fb726d48Sopenharmony_ci *
7fb726d48Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb726d48Sopenharmony_ci *
9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and
13fb726d48Sopenharmony_ci * limitations under the License.
14fb726d48Sopenharmony_ci */
15fb726d48Sopenharmony_ci
16fb726d48Sopenharmony_ciimport { DataCache, JsProfilerSymbol, convertJSON } from '../../database/logic-worker/ProcedureLogicWorkerCommon';
17fb726d48Sopenharmony_ciimport { JsCpuProfilerChartFrame, type JsCpuProfilerUIStruct } from '../../bean/JsStruct';
18fb726d48Sopenharmony_ciimport { JsCpuProfilerSample, SampleType } from '../logic-worker/ProcedureLogicWorkerJsCpuProfiler';
19fb726d48Sopenharmony_ciimport { TraficEnum } from './utils/QueryEnum';
20fb726d48Sopenharmony_ciimport { Args } from './CommonArgs';
21fb726d48Sopenharmony_ci
22fb726d48Sopenharmony_ciconst dataCache = DataCache.getInstance();
23fb726d48Sopenharmony_ciconst ROOT_ID = 1;
24fb726d48Sopenharmony_cilet samples = Array<JsCpuProfilerSample>(); // Array index equals id;
25fb726d48Sopenharmony_ciconst jsCallChain: Array<JsCpuProfilerChartFrame> = [];
26fb726d48Sopenharmony_cilet chartId: number = 0;
27fb726d48Sopenharmony_ciconst jsDataCache: {
28fb726d48Sopenharmony_ci  childrenIds: Array<Array<number>>;
29fb726d48Sopenharmony_ci  column: Array<number>;
30fb726d48Sopenharmony_ci  depth: Array<number>;
31fb726d48Sopenharmony_ci  endTime: Array<number>;
32fb726d48Sopenharmony_ci  id: Array<number>;
33fb726d48Sopenharmony_ci  line: Array<number>;
34fb726d48Sopenharmony_ci  nameId: Array<number>;
35fb726d48Sopenharmony_ci  parentId: Array<number>;
36fb726d48Sopenharmony_ci  samplesIds: Array<Array<number>>;
37fb726d48Sopenharmony_ci  selfTime: Array<number>;
38fb726d48Sopenharmony_ci  startTime: Array<number>;
39fb726d48Sopenharmony_ci  totalTime: Array<number>;
40fb726d48Sopenharmony_ci  urlId: Array<number>;
41fb726d48Sopenharmony_ci  maxDepth: number;
42fb726d48Sopenharmony_ci} = {
43fb726d48Sopenharmony_ci  samplesIds: [],
44fb726d48Sopenharmony_ci  childrenIds: [],
45fb726d48Sopenharmony_ci  column: [],
46fb726d48Sopenharmony_ci  depth: [],
47fb726d48Sopenharmony_ci  endTime: [],
48fb726d48Sopenharmony_ci  id: [],
49fb726d48Sopenharmony_ci  line: [],
50fb726d48Sopenharmony_ci  nameId: [],
51fb726d48Sopenharmony_ci  parentId: [],
52fb726d48Sopenharmony_ci  selfTime: [],
53fb726d48Sopenharmony_ci  startTime: [],
54fb726d48Sopenharmony_ci  totalTime: [],
55fb726d48Sopenharmony_ci  urlId: [],
56fb726d48Sopenharmony_ci  maxDepth: 1,
57fb726d48Sopenharmony_ci};
58fb726d48Sopenharmony_ci
59fb726d48Sopenharmony_ciexport const initCallChainDataSql = (args: unknown):unknown => {
60fb726d48Sopenharmony_ci  const sql = `SELECT function_id AS id,
61fb726d48Sopenharmony_ci              0 As functionId,
62fb726d48Sopenharmony_ci            0 AS startTime,
63fb726d48Sopenharmony_ci            0 As endTime,
64fb726d48Sopenharmony_ci            0 As dur,
65fb726d48Sopenharmony_ci            function_index AS nameId,
66fb726d48Sopenharmony_ci            url_index AS urlId,
67fb726d48Sopenharmony_ci            line_number as line,
68fb726d48Sopenharmony_ci            column_number as column,
69fb726d48Sopenharmony_ci            hit_count AS hitCount,
70fb726d48Sopenharmony_ci            children AS childrenString,
71fb726d48Sopenharmony_ci            parent_id AS parentId
72fb726d48Sopenharmony_ci            FROM js_cpu_profiler_node`;
73fb726d48Sopenharmony_ci  return sql;
74fb726d48Sopenharmony_ci};
75fb726d48Sopenharmony_ci
76fb726d48Sopenharmony_ciexport const queryChartDataSqlMem = (args: Args):unknown => {
77fb726d48Sopenharmony_ci  const sql = `SELECT id,
78fb726d48Sopenharmony_ci            function_id AS functionId,
79fb726d48Sopenharmony_ci            start_time - ${args.recordStartNS} AS startTime,
80fb726d48Sopenharmony_ci            end_time - ${args.recordStartNS} AS endTime,
81fb726d48Sopenharmony_ci            dur
82fb726d48Sopenharmony_ci            FROM js_cpu_profiler_sample`;
83fb726d48Sopenharmony_ci  return sql;
84fb726d48Sopenharmony_ci};
85fb726d48Sopenharmony_ci
86fb726d48Sopenharmony_ciexport function cpuProfilerDataReceiver(data: unknown, proc: Function): void {
87fb726d48Sopenharmony_ci  //@ts-ignore
88fb726d48Sopenharmony_ci  let sql = initCallChainDataSql(data.params);
89fb726d48Sopenharmony_ci  let res = proc(sql);
90fb726d48Sopenharmony_ci  if (res.length > 0) {
91fb726d48Sopenharmony_ci    if (!dataCache.jsCallChain || dataCache.jsCallChain.length === 0) {
92fb726d48Sopenharmony_ci      dataCache.jsCallChain = res;
93fb726d48Sopenharmony_ci      //@ts-ignore
94fb726d48Sopenharmony_ci      createCallChain(data.params.trafic);
95fb726d48Sopenharmony_ci    }
96fb726d48Sopenharmony_ci    //@ts-ignore
97fb726d48Sopenharmony_ci    let sql = queryChartDataSqlMem(data.params);
98fb726d48Sopenharmony_ci    let chartData = proc(sql);
99fb726d48Sopenharmony_ci    if (chartData.length > 0) {
100fb726d48Sopenharmony_ci      //@ts-ignore
101fb726d48Sopenharmony_ci      samples = convertJSON(chartData);
102fb726d48Sopenharmony_ci      arrayBufferHandler(data, samples, true);
103fb726d48Sopenharmony_ci    }
104fb726d48Sopenharmony_ci  }
105fb726d48Sopenharmony_ci}
106fb726d48Sopenharmony_ci
107fb726d48Sopenharmony_ci/**
108fb726d48Sopenharmony_ci * 建立callChain每个函数的联系,设置depth跟children
109fb726d48Sopenharmony_ci */
110fb726d48Sopenharmony_cifunction createCallChain(trafic: TraficEnum): void {
111fb726d48Sopenharmony_ci  const jsSymbolMap = dataCache.jsSymbolMap;
112fb726d48Sopenharmony_ci  const symbol = new JsProfilerSymbol();
113fb726d48Sopenharmony_ci  for (let data of dataCache.jsCallChain!) {
114fb726d48Sopenharmony_ci    let sample = (trafic !== TraficEnum.Memory ? data.cpuProfilerData : data) || symbol;
115fb726d48Sopenharmony_ci    let item = data.cpuProfilerData || data;
116fb726d48Sopenharmony_ci    if (!item.childrenString) {
117fb726d48Sopenharmony_ci      item.childrenString = '';
118fb726d48Sopenharmony_ci    }
119fb726d48Sopenharmony_ci    jsSymbolMap.set(item.id, item);
120fb726d48Sopenharmony_ci    //root不需要显示,depth为-1
121fb726d48Sopenharmony_ci    if (item.id === ROOT_ID) {
122fb726d48Sopenharmony_ci      item.depth = -1;
123fb726d48Sopenharmony_ci    }
124fb726d48Sopenharmony_ci    if (item.parentId > 0) {
125fb726d48Sopenharmony_ci      let parentSymbol = jsSymbolMap.get(item.parentId);
126fb726d48Sopenharmony_ci      if (parentSymbol) {
127fb726d48Sopenharmony_ci        if (!parentSymbol.children) {
128fb726d48Sopenharmony_ci          parentSymbol.children = new Array<JsProfilerSymbol>();
129fb726d48Sopenharmony_ci          parentSymbol.childrenIds = new Array<number>();
130fb726d48Sopenharmony_ci          parentSymbol.childrenString = '';
131fb726d48Sopenharmony_ci        }
132fb726d48Sopenharmony_ci        parentSymbol.children.push(item);
133fb726d48Sopenharmony_ci        parentSymbol.childrenString! += `${item.id},`;
134fb726d48Sopenharmony_ci        parentSymbol.childrenIds.push(item.id);
135fb726d48Sopenharmony_ci        item.depth = parentSymbol.depth + 1;
136fb726d48Sopenharmony_ci      }
137fb726d48Sopenharmony_ci    }
138fb726d48Sopenharmony_ci  }
139fb726d48Sopenharmony_ci}
140fb726d48Sopenharmony_ci
141fb726d48Sopenharmony_cifunction combineChartData(res: Array<JsCpuProfilerSample>, trafic: TraficEnum): Array<JsCpuProfilerChartFrame> {
142fb726d48Sopenharmony_ci  const combineSample = new Array<JsCpuProfilerChartFrame>();
143fb726d48Sopenharmony_ci  const symbol = new JsCpuProfilerSample();
144fb726d48Sopenharmony_ci  for (let data of res) {
145fb726d48Sopenharmony_ci    let sample = (trafic !== TraficEnum.Memory ? data.cpuProfilerData : data) || symbol;
146fb726d48Sopenharmony_ci    const stackTopSymbol = dataCache.jsSymbolMap.get(sample.functionId);
147fb726d48Sopenharmony_ci    // root 节点不需要显示
148fb726d48Sopenharmony_ci    if (stackTopSymbol?.id === ROOT_ID) {
149fb726d48Sopenharmony_ci      sample.type = SampleType.OTHER;
150fb726d48Sopenharmony_ci      continue;
151fb726d48Sopenharmony_ci    }
152fb726d48Sopenharmony_ci    if (stackTopSymbol) {
153fb726d48Sopenharmony_ci      // 获取栈顶函数的整条调用栈为一个数组 下标0为触发的栈底函数
154fb726d48Sopenharmony_ci      sample.stack = getFullCallChainOfNode(stackTopSymbol);
155fb726d48Sopenharmony_ci      if (combineSample.length === 0) {
156fb726d48Sopenharmony_ci        // 首次combineSample没有数据时,用第一条数据创建一个调用树
157fb726d48Sopenharmony_ci        createNewChartFrame(sample, combineSample);
158fb726d48Sopenharmony_ci      } else {
159fb726d48Sopenharmony_ci        const lastCallChart = combineSample[combineSample.length - 1];
160fb726d48Sopenharmony_ci        if (isSymbolEqual(sample.stack[0], lastCallChart) && lastCallChart.endTime === sample.startTime) {
161fb726d48Sopenharmony_ci          combineCallChain(lastCallChart, sample);
162fb726d48Sopenharmony_ci        } else {
163fb726d48Sopenharmony_ci          // 一个调用链栈底函数与前一个不同时,需要新加入到combineSample
164fb726d48Sopenharmony_ci          createNewChartFrame(sample, combineSample);
165fb726d48Sopenharmony_ci        }
166fb726d48Sopenharmony_ci      }
167fb726d48Sopenharmony_ci    }
168fb726d48Sopenharmony_ci  }
169fb726d48Sopenharmony_ci  return combineSample;
170fb726d48Sopenharmony_ci}
171fb726d48Sopenharmony_ci
172fb726d48Sopenharmony_ci/**
173fb726d48Sopenharmony_ci * 根据每个sample的栈顶函数,获取完整的调用栈
174fb726d48Sopenharmony_ci * @param node 栈顶函数
175fb726d48Sopenharmony_ci * @returns 完整的调用栈
176fb726d48Sopenharmony_ci */
177fb726d48Sopenharmony_cifunction getFullCallChainOfNode(node: JsProfilerSymbol): Array<JsProfilerSymbol> {
178fb726d48Sopenharmony_ci  const callChain = new Array<JsProfilerSymbol>();
179fb726d48Sopenharmony_ci  callChain.push(node);
180fb726d48Sopenharmony_ci  while (node.parentId !== 0) {
181fb726d48Sopenharmony_ci    const parent = dataCache.jsSymbolMap.get(node.parentId);
182fb726d48Sopenharmony_ci    // id 1 is root Node
183fb726d48Sopenharmony_ci    if (!parent || parent.id <= ROOT_ID) {
184fb726d48Sopenharmony_ci      break;
185fb726d48Sopenharmony_ci    }
186fb726d48Sopenharmony_ci    callChain.push(parent);
187fb726d48Sopenharmony_ci    node = parent;
188fb726d48Sopenharmony_ci  }
189fb726d48Sopenharmony_ci  callChain.reverse();
190fb726d48Sopenharmony_ci  return callChain;
191fb726d48Sopenharmony_ci}
192fb726d48Sopenharmony_ci
193fb726d48Sopenharmony_cifunction createNewChartFrame(sample: JsCpuProfilerSample, combineSample: Array<JsCpuProfilerChartFrame>): void {
194fb726d48Sopenharmony_ci  let lastSymbol: JsCpuProfilerChartFrame;
195fb726d48Sopenharmony_ci  for (const [idx, symbol] of sample.stack!.entries()) {
196fb726d48Sopenharmony_ci    if (idx === 0) {
197fb726d48Sopenharmony_ci      lastSymbol = symbolToChartFrame(sample, symbol);
198fb726d48Sopenharmony_ci      combineSample.push(lastSymbol);
199fb726d48Sopenharmony_ci    } else {
200fb726d48Sopenharmony_ci      const callFrame = symbolToChartFrame(sample, symbol);
201fb726d48Sopenharmony_ci      lastSymbol!.children.push(callFrame);
202fb726d48Sopenharmony_ci      lastSymbol!.childrenIds.push(callFrame.id);
203fb726d48Sopenharmony_ci      callFrame.parentId = lastSymbol!.id;
204fb726d48Sopenharmony_ci      lastSymbol = callFrame;
205fb726d48Sopenharmony_ci    }
206fb726d48Sopenharmony_ci    if (idx + 1 === sample.stack?.length) {
207fb726d48Sopenharmony_ci      lastSymbol.selfTime = sample.dur;
208fb726d48Sopenharmony_ci    }
209fb726d48Sopenharmony_ci  }
210fb726d48Sopenharmony_ci}
211fb726d48Sopenharmony_ci
212fb726d48Sopenharmony_ci/**
213fb726d48Sopenharmony_ci * 创建一个JsCpuProfilerChartFrame 作为绘制泳道图的结构
214fb726d48Sopenharmony_ci * @param sample 数据库样本数据
215fb726d48Sopenharmony_ci * @param symbol 样本的每一个函数
216fb726d48Sopenharmony_ci * @returns JsCpuProfilerChartFrame
217fb726d48Sopenharmony_ci */
218fb726d48Sopenharmony_cifunction symbolToChartFrame(sample: JsCpuProfilerSample, symbol: JsProfilerSymbol): JsCpuProfilerChartFrame {
219fb726d48Sopenharmony_ci  const chartFrame = new JsCpuProfilerChartFrame(
220fb726d48Sopenharmony_ci    chartId++,
221fb726d48Sopenharmony_ci    symbol.nameId,
222fb726d48Sopenharmony_ci    sample.startTime,
223fb726d48Sopenharmony_ci    sample.endTime,
224fb726d48Sopenharmony_ci    sample.dur,
225fb726d48Sopenharmony_ci    symbol.depth,
226fb726d48Sopenharmony_ci    symbol.urlId,
227fb726d48Sopenharmony_ci    symbol.line,
228fb726d48Sopenharmony_ci    symbol.column
229fb726d48Sopenharmony_ci  );
230fb726d48Sopenharmony_ci  chartFrame.samplesIds.push(sample.id);
231fb726d48Sopenharmony_ci  return chartFrame;
232fb726d48Sopenharmony_ci}
233fb726d48Sopenharmony_ci
234fb726d48Sopenharmony_cifunction isSymbolEqual(symbol: JsProfilerSymbol, uiData: JsCpuProfilerUIStruct): boolean {
235fb726d48Sopenharmony_ci  return symbol.nameId === uiData.nameId && symbol.urlId === uiData.urlId;
236fb726d48Sopenharmony_ci}
237fb726d48Sopenharmony_ci
238fb726d48Sopenharmony_ci/**
239fb726d48Sopenharmony_ci * 相邻的两个sample的name,url,depth相同,且上一个的endTime等于下一个的startTime,
240fb726d48Sopenharmony_ci * 则两个sample的调用栈合并
241fb726d48Sopenharmony_ci * @param lastCallTree 上一个已经合并的树结构调用栈
242fb726d48Sopenharmony_ci * @param sample 当前样本数据
243fb726d48Sopenharmony_ci */
244fb726d48Sopenharmony_cifunction combineCallChain(lastCallTree: JsCpuProfilerChartFrame, sample: JsCpuProfilerSample): void {
245fb726d48Sopenharmony_ci  let lastCallTreeSymbol = lastCallTree;
246fb726d48Sopenharmony_ci  let parentCallFrame: JsCpuProfilerChartFrame;
247fb726d48Sopenharmony_ci  let isEqual = true;
248fb726d48Sopenharmony_ci  for (const [idx, symbol] of sample.stack!.entries()) {
249fb726d48Sopenharmony_ci    // 是否为每次采样的栈顶函数
250fb726d48Sopenharmony_ci    const isLastSymbol = idx + 1 === sample.stack?.length;
251fb726d48Sopenharmony_ci    if (
252fb726d48Sopenharmony_ci      isEqual &&
253fb726d48Sopenharmony_ci      isSymbolEqual(symbol, lastCallTreeSymbol) &&
254fb726d48Sopenharmony_ci      lastCallTreeSymbol.depth === idx &&
255fb726d48Sopenharmony_ci      lastCallTreeSymbol.endTime === sample.startTime
256fb726d48Sopenharmony_ci    ) {
257fb726d48Sopenharmony_ci      // 如果函数名跟depth匹配,则更新函数的持续时间
258fb726d48Sopenharmony_ci      lastCallTreeSymbol.endTime = sample.endTime;
259fb726d48Sopenharmony_ci      lastCallTreeSymbol.totalTime = sample.endTime - lastCallTreeSymbol.startTime;
260fb726d48Sopenharmony_ci      lastCallTreeSymbol.samplesIds.push(sample.id);
261fb726d48Sopenharmony_ci      let lastChildren = lastCallTreeSymbol.children;
262fb726d48Sopenharmony_ci      parentCallFrame = lastCallTreeSymbol;
263fb726d48Sopenharmony_ci      if (lastChildren && lastChildren.length > 0) {
264fb726d48Sopenharmony_ci        lastCallTreeSymbol = lastChildren[lastChildren.length - 1];
265fb726d48Sopenharmony_ci      }
266fb726d48Sopenharmony_ci      isEqual = true;
267fb726d48Sopenharmony_ci    } else {
268fb726d48Sopenharmony_ci      // 如果不匹配,则作为新的分支添加到lastCallTree
269fb726d48Sopenharmony_ci      const deltaFrame = symbolToChartFrame(sample, symbol);
270fb726d48Sopenharmony_ci      parentCallFrame!.children.push(deltaFrame);
271fb726d48Sopenharmony_ci      parentCallFrame!.childrenIds.push(deltaFrame.id);
272fb726d48Sopenharmony_ci      deltaFrame.parentId = parentCallFrame!.id;
273fb726d48Sopenharmony_ci      parentCallFrame = deltaFrame;
274fb726d48Sopenharmony_ci      isEqual = false;
275fb726d48Sopenharmony_ci    }
276fb726d48Sopenharmony_ci    // 每次采样的栈顶函数的selfTime为该次采样数据的时间
277fb726d48Sopenharmony_ci    if (isLastSymbol) {
278fb726d48Sopenharmony_ci      parentCallFrame.selfTime += sample.dur;
279fb726d48Sopenharmony_ci    }
280fb726d48Sopenharmony_ci  }
281fb726d48Sopenharmony_ci}
282fb726d48Sopenharmony_ci
283fb726d48Sopenharmony_cifunction arrayBufferHandler(data: unknown, res: JsCpuProfilerSample[], transfer: boolean): void {
284fb726d48Sopenharmony_ci  //@ts-ignore
285fb726d48Sopenharmony_ci  let result = combineChartData(res, data.params.trafic);
286fb726d48Sopenharmony_ci  clearJsCacheData();
287fb726d48Sopenharmony_ci  const getArrayData = (combineData: Array<JsCpuProfilerChartFrame>): void => {
288fb726d48Sopenharmony_ci    for (let item of combineData) {
289fb726d48Sopenharmony_ci      if (item.depth > -1) {
290fb726d48Sopenharmony_ci        jsDataCache.id.push(item.id);
291fb726d48Sopenharmony_ci        jsDataCache.startTime.push(item.startTime);
292fb726d48Sopenharmony_ci        jsDataCache.endTime.push(item.endTime);
293fb726d48Sopenharmony_ci        jsDataCache.selfTime.push(item.selfTime);
294fb726d48Sopenharmony_ci        jsDataCache.totalTime.push(item.totalTime);
295fb726d48Sopenharmony_ci        jsDataCache.column.push(item.column);
296fb726d48Sopenharmony_ci        jsDataCache.line.push(item.line);
297fb726d48Sopenharmony_ci        jsDataCache.depth.push(item.depth);
298fb726d48Sopenharmony_ci        jsDataCache.parentId.push(item.parentId);
299fb726d48Sopenharmony_ci        jsDataCache.nameId.push(item.nameId);
300fb726d48Sopenharmony_ci        jsDataCache.samplesIds.push([...item.samplesIds]);
301fb726d48Sopenharmony_ci        jsDataCache.urlId.push(item.urlId);
302fb726d48Sopenharmony_ci        jsDataCache.childrenIds.push([...item.childrenIds]);
303fb726d48Sopenharmony_ci        if (item.depth + 1 > jsDataCache.maxDepth) {
304fb726d48Sopenharmony_ci          jsDataCache.maxDepth = item.depth + 1;
305fb726d48Sopenharmony_ci        }
306fb726d48Sopenharmony_ci        if (item.children && item.children.length > 0) {
307fb726d48Sopenharmony_ci          getArrayData(item.children);
308fb726d48Sopenharmony_ci        }
309fb726d48Sopenharmony_ci      }
310fb726d48Sopenharmony_ci    }
311fb726d48Sopenharmony_ci  };
312fb726d48Sopenharmony_ci  getArrayData(result);
313fb726d48Sopenharmony_ci  setTimeout((): void => {
314fb726d48Sopenharmony_ci    arrayBufferCallback(data, transfer);
315fb726d48Sopenharmony_ci  }, 150);
316fb726d48Sopenharmony_ci}
317fb726d48Sopenharmony_cifunction arrayBufferCallback(data: unknown, transfer: boolean): void {
318fb726d48Sopenharmony_ci  let dataFilter = jsDataCache;
319fb726d48Sopenharmony_ci  let len = dataFilter!.startTime!.length;
320fb726d48Sopenharmony_ci  const arkTs = new ArkTS(len);
321fb726d48Sopenharmony_ci  for (let i = 0; i < len; i++) {
322fb726d48Sopenharmony_ci    arkTs.column[i] = dataFilter.column[i];
323fb726d48Sopenharmony_ci    arkTs.depth[i] = dataFilter.depth[i];
324fb726d48Sopenharmony_ci    arkTs.endTime[i] = dataFilter.endTime[i];
325fb726d48Sopenharmony_ci    arkTs.id[i] = dataFilter.id[i];
326fb726d48Sopenharmony_ci    arkTs.line[i] = dataFilter.line[i];
327fb726d48Sopenharmony_ci    arkTs.nameId[i] = dataFilter.nameId[i];
328fb726d48Sopenharmony_ci    arkTs.parentId[i] = dataFilter.parentId[i];
329fb726d48Sopenharmony_ci    arkTs.samplesIds[i] = [...dataFilter.samplesIds[i]];
330fb726d48Sopenharmony_ci    arkTs.selfTime[i] = dataFilter.selfTime[i];
331fb726d48Sopenharmony_ci    arkTs.startTime[i] = dataFilter.startTime[i];
332fb726d48Sopenharmony_ci    arkTs.totalTime[i] = dataFilter.totalTime[i];
333fb726d48Sopenharmony_ci    arkTs.urlId[i] = dataFilter.urlId[i];
334fb726d48Sopenharmony_ci    arkTs.childrenIds[i] = [...dataFilter.childrenIds[i]];
335fb726d48Sopenharmony_ci  }
336fb726d48Sopenharmony_ci  postMessage(data, transfer, arkTs, len);
337fb726d48Sopenharmony_ci  // 合并完泳道图数据之后,Tab页不再需要缓存数据
338fb726d48Sopenharmony_ci  if (jsCallChain) {
339fb726d48Sopenharmony_ci    dataCache.jsCallChain!.length = 0;
340fb726d48Sopenharmony_ci  }
341fb726d48Sopenharmony_ci  dataCache.jsSymbolMap!.clear();
342fb726d48Sopenharmony_ci}
343fb726d48Sopenharmony_cifunction postMessage(data: unknown, transfer: boolean, arkTs: ArkTS, len: number): void {
344fb726d48Sopenharmony_ci  (self as unknown as Worker).postMessage(
345fb726d48Sopenharmony_ci    {
346fb726d48Sopenharmony_ci      //@ts-ignore
347fb726d48Sopenharmony_ci      id: data.id,
348fb726d48Sopenharmony_ci      //@ts-ignore
349fb726d48Sopenharmony_ci      action: data.action,
350fb726d48Sopenharmony_ci      results: transfer
351fb726d48Sopenharmony_ci        ? {
352fb726d48Sopenharmony_ci            column: arkTs.column.buffer,
353fb726d48Sopenharmony_ci            depth: arkTs.depth.buffer,
354fb726d48Sopenharmony_ci            endTime: arkTs.endTime.buffer,
355fb726d48Sopenharmony_ci            id: arkTs.id.buffer,
356fb726d48Sopenharmony_ci            line: arkTs.line.buffer,
357fb726d48Sopenharmony_ci            nameId: arkTs.nameId.buffer,
358fb726d48Sopenharmony_ci            parentId: arkTs.parentId.buffer,
359fb726d48Sopenharmony_ci            samplesIds: arkTs.samplesIds,
360fb726d48Sopenharmony_ci            selfTime: arkTs.selfTime.buffer,
361fb726d48Sopenharmony_ci            startTime: arkTs.startTime.buffer,
362fb726d48Sopenharmony_ci            totalTime: arkTs.totalTime.buffer,
363fb726d48Sopenharmony_ci            urlId: arkTs.urlId.buffer,
364fb726d48Sopenharmony_ci            childrenIds: arkTs.childrenIds,
365fb726d48Sopenharmony_ci            maxDepth: jsDataCache.maxDepth,
366fb726d48Sopenharmony_ci          }
367fb726d48Sopenharmony_ci        : {},
368fb726d48Sopenharmony_ci      len: len,
369fb726d48Sopenharmony_ci    },
370fb726d48Sopenharmony_ci    transfer
371fb726d48Sopenharmony_ci      ? [
372fb726d48Sopenharmony_ci          arkTs.column.buffer,
373fb726d48Sopenharmony_ci          arkTs.depth.buffer,
374fb726d48Sopenharmony_ci          arkTs.endTime.buffer,
375fb726d48Sopenharmony_ci          arkTs.id.buffer,
376fb726d48Sopenharmony_ci          arkTs.line.buffer,
377fb726d48Sopenharmony_ci          arkTs.parentId.buffer,
378fb726d48Sopenharmony_ci          arkTs.selfTime.buffer,
379fb726d48Sopenharmony_ci          arkTs.startTime.buffer,
380fb726d48Sopenharmony_ci          arkTs.totalTime.buffer,
381fb726d48Sopenharmony_ci        ]
382fb726d48Sopenharmony_ci      : []
383fb726d48Sopenharmony_ci  );
384fb726d48Sopenharmony_ci}
385fb726d48Sopenharmony_ci
386fb726d48Sopenharmony_cifunction ns2x(ns: number, startNS: number, endNS: number, duration: number, width: number): number {
387fb726d48Sopenharmony_ci  if (endNS === 0) {
388fb726d48Sopenharmony_ci    endNS = duration;
389fb726d48Sopenharmony_ci  }
390fb726d48Sopenharmony_ci  let xSize: number = ((ns - startNS) * width) / (endNS - startNS);
391fb726d48Sopenharmony_ci  xSize = xSize < 0 ? 0 : xSize > width ? width : xSize;
392fb726d48Sopenharmony_ci  return xSize;
393fb726d48Sopenharmony_ci}
394fb726d48Sopenharmony_ci
395fb726d48Sopenharmony_cifunction clearJsCacheData(): void {
396fb726d48Sopenharmony_ci  chartId = 0;
397fb726d48Sopenharmony_ci  jsDataCache.childrenIds = [];
398fb726d48Sopenharmony_ci  jsDataCache.column = [];
399fb726d48Sopenharmony_ci  jsDataCache.depth = [];
400fb726d48Sopenharmony_ci  jsDataCache.endTime = [];
401fb726d48Sopenharmony_ci  jsDataCache.id = [];
402fb726d48Sopenharmony_ci  jsDataCache.line = [];
403fb726d48Sopenharmony_ci  jsDataCache.nameId = [];
404fb726d48Sopenharmony_ci  jsDataCache.parentId = [];
405fb726d48Sopenharmony_ci  jsDataCache.samplesIds = [];
406fb726d48Sopenharmony_ci  jsDataCache.selfTime = [];
407fb726d48Sopenharmony_ci  jsDataCache.startTime = [];
408fb726d48Sopenharmony_ci  jsDataCache.totalTime = [];
409fb726d48Sopenharmony_ci  jsDataCache.urlId = [];
410fb726d48Sopenharmony_ci  jsDataCache.maxDepth = 1;
411fb726d48Sopenharmony_ci}
412fb726d48Sopenharmony_ci
413fb726d48Sopenharmony_ciclass ArkTS {
414fb726d48Sopenharmony_ci  column: Int32Array;
415fb726d48Sopenharmony_ci  depth: Int32Array;
416fb726d48Sopenharmony_ci  endTime: Float64Array;
417fb726d48Sopenharmony_ci  id: Int32Array;
418fb726d48Sopenharmony_ci  line: Int32Array;
419fb726d48Sopenharmony_ci  nameId: Int32Array;
420fb726d48Sopenharmony_ci  parentId: Int32Array;
421fb726d48Sopenharmony_ci  samplesIds: Array<unknown>;
422fb726d48Sopenharmony_ci  selfTime: Float64Array;
423fb726d48Sopenharmony_ci  startTime: Float64Array;
424fb726d48Sopenharmony_ci  totalTime: Float64Array;
425fb726d48Sopenharmony_ci  urlId: Int32Array;
426fb726d48Sopenharmony_ci  childrenIds: Array<unknown>;
427fb726d48Sopenharmony_ci
428fb726d48Sopenharmony_ci  constructor(len: number) {
429fb726d48Sopenharmony_ci    this.column = new Int32Array(len);
430fb726d48Sopenharmony_ci    this.depth = new Int32Array(len);
431fb726d48Sopenharmony_ci    this.endTime = new Float64Array(len);
432fb726d48Sopenharmony_ci    this.id = new Int32Array(len);
433fb726d48Sopenharmony_ci    this.line = new Int32Array(len);
434fb726d48Sopenharmony_ci    this.nameId = new Int32Array(len);
435fb726d48Sopenharmony_ci    this.parentId = new Int32Array(len);
436fb726d48Sopenharmony_ci    this.samplesIds = [];
437fb726d48Sopenharmony_ci    this.selfTime = new Float64Array(len);
438fb726d48Sopenharmony_ci    this.startTime = new Float64Array(len);
439fb726d48Sopenharmony_ci    this.totalTime = new Float64Array(len);
440fb726d48Sopenharmony_ci    this.urlId = new Int32Array(len);
441fb726d48Sopenharmony_ci    this.childrenIds = [];
442fb726d48Sopenharmony_ci  }
443fb726d48Sopenharmony_ci}
444