1fb726d48Sopenharmony_ci/*
2fb726d48Sopenharmony_ci * Copyright (C) 2024 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 { type CpuFreqData, type RunningFreqData, type RunningData } from '../component/trace/sheet/frequsage/TabPaneFreqUsageConfig';
17fb726d48Sopenharmony_ci
18fb726d48Sopenharmony_cilet comPower = new Map<number, Map<number, unknown>>();
19fb726d48Sopenharmony_cilet resultArray: Array<RunningFreqData> = [];
20fb726d48Sopenharmony_cilet timeZones: number = 0;
21fb726d48Sopenharmony_cilet maxCommpuPower: number = 0;
22fb726d48Sopenharmony_ci
23fb726d48Sopenharmony_ci/**
24fb726d48Sopenharmony_ci *
25fb726d48Sopenharmony_ci * @param args.runData 数据库查询上来的running数据,此函数会将数据整理成map结构,分组规则:'pid_tid'为键,running数据数字为值
26fb726d48Sopenharmony_ci * @returns 返回map对象及所有running数据的dur和,后续会依此计算百分比
27fb726d48Sopenharmony_ci */
28fb726d48Sopenharmony_cifunction orgnazitionMap(
29fb726d48Sopenharmony_ci  args: {
30fb726d48Sopenharmony_ci    runData: Array<RunningData>;
31fb726d48Sopenharmony_ci    cpuFreqData: Array<CpuFreqData>;
32fb726d48Sopenharmony_ci    leftNs: number;
33fb726d48Sopenharmony_ci    rightNs: number;
34fb726d48Sopenharmony_ci    cpuArray: number[];
35fb726d48Sopenharmony_ci  }
36fb726d48Sopenharmony_ci): Array<RunningFreqData> {
37fb726d48Sopenharmony_ci  let result: Map<string, Array<RunningData>> = new Map();
38fb726d48Sopenharmony_ci  let sum: number = 0;
39fb726d48Sopenharmony_ci  // 循环分组
40fb726d48Sopenharmony_ci  for (let i = 0; i < args.runData.length; i++) {
41fb726d48Sopenharmony_ci    let mapKey: string = args.runData[i].pid + '_' + args.runData[i].tid;
42fb726d48Sopenharmony_ci    // 该running数据若在map对象中不包含其'pid_tid'构成的键,则新加key-value值
43fb726d48Sopenharmony_ci    if (!result.has(mapKey)) {
44fb726d48Sopenharmony_ci      result.set(mapKey, new Array());
45fb726d48Sopenharmony_ci    }
46fb726d48Sopenharmony_ci    // 整理左右边界数据问题, 因为涉及多线程,所以必须放在循环里
47fb726d48Sopenharmony_ci    if (
48fb726d48Sopenharmony_ci      args.runData[i].ts < args.leftNs &&
49fb726d48Sopenharmony_ci      args.runData[i].ts + args.runData[i].dur > args.leftNs
50fb726d48Sopenharmony_ci    ) {
51fb726d48Sopenharmony_ci      args.runData[i].dur = args.runData[i].ts + args.runData[i].dur - args.leftNs;
52fb726d48Sopenharmony_ci      args.runData[i].ts = args.leftNs;
53fb726d48Sopenharmony_ci    }
54fb726d48Sopenharmony_ci    if (args.runData[i].ts + args.runData[i].dur > args.rightNs) {
55fb726d48Sopenharmony_ci      args.runData[i].dur = args.rightNs - args.runData[i].ts;
56fb726d48Sopenharmony_ci    }
57fb726d48Sopenharmony_ci    // 特殊处理数据表中dur为负值的情况
58fb726d48Sopenharmony_ci    if (args.runData[i].dur < 0) {
59fb726d48Sopenharmony_ci      args.runData[i].dur = 0;
60fb726d48Sopenharmony_ci    }
61fb726d48Sopenharmony_ci    // 分组整理数据
62fb726d48Sopenharmony_ci    result.get(mapKey)?.push({
63fb726d48Sopenharmony_ci      pid: args.runData[i].pid,
64fb726d48Sopenharmony_ci      tid: args.runData[i].tid,
65fb726d48Sopenharmony_ci      cpu: args.runData[i].cpu,
66fb726d48Sopenharmony_ci      dur: args.runData[i].dur,
67fb726d48Sopenharmony_ci      ts: args.runData[i].ts,
68fb726d48Sopenharmony_ci    });
69fb726d48Sopenharmony_ci    sum += args.runData[i].dur;
70fb726d48Sopenharmony_ci  }
71fb726d48Sopenharmony_ci  return dealCpuFreqData(args.cpuFreqData, result, sum, args.cpuArray);
72fb726d48Sopenharmony_ci}
73fb726d48Sopenharmony_ci
74fb726d48Sopenharmony_ci/**
75fb726d48Sopenharmony_ci *
76fb726d48Sopenharmony_ci * @param cpuFreqData cpu频点数据的数组
77fb726d48Sopenharmony_ci * @param result running数据的map对象
78fb726d48Sopenharmony_ci * @param sum running数据的时间和
79fb726d48Sopenharmony_ci * @returns 返回cpu频点数据map,'pid_tid'为键,频点算力值数据的数组为值
80fb726d48Sopenharmony_ci */
81fb726d48Sopenharmony_cifunction dealCpuFreqData(
82fb726d48Sopenharmony_ci  cpuFreqData: Array<CpuFreqData>,
83fb726d48Sopenharmony_ci  result: Map<string, Array<RunningData>>,
84fb726d48Sopenharmony_ci  sum: number,
85fb726d48Sopenharmony_ci  cpuList: number[]
86fb726d48Sopenharmony_ci): Array<RunningFreqData> {
87fb726d48Sopenharmony_ci  let runningFreqData: Map<string, Array<RunningFreqData>> = new Map();
88fb726d48Sopenharmony_ci  result.forEach((item, key) => {
89fb726d48Sopenharmony_ci    let resultList: Array<RunningFreqData> = new Array();
90fb726d48Sopenharmony_ci    for (let i = 0; i < item.length; i++) {
91fb726d48Sopenharmony_ci      for (let j = 0; j < cpuFreqData.length; j++) {
92fb726d48Sopenharmony_ci        let flag: number;
93fb726d48Sopenharmony_ci        if (item[i].cpu === cpuFreqData[j].cpu) {
94fb726d48Sopenharmony_ci          // 当running状态数据的开始时间大于频点数据开始时间,小于频点结束时间。且running数据的持续时间小于频点结束时间减去running数据开始时间的差值的情况
95fb726d48Sopenharmony_ci          if (
96fb726d48Sopenharmony_ci            item[i].ts > cpuFreqData[j].ts &&
97fb726d48Sopenharmony_ci            item[i].ts < cpuFreqData[j].ts + cpuFreqData[j].dur &&
98fb726d48Sopenharmony_ci            item[i].dur < cpuFreqData[j].ts + cpuFreqData[j].dur - item[i].ts
99fb726d48Sopenharmony_ci          ) {
100fb726d48Sopenharmony_ci            resultList.push(returnObj(item[i], cpuFreqData[j], sum, (flag = 1))!);
101fb726d48Sopenharmony_ci            item.splice(i, 1);
102fb726d48Sopenharmony_ci            i--;
103fb726d48Sopenharmony_ci            break;
104fb726d48Sopenharmony_ci          }
105fb726d48Sopenharmony_ci          if (
106fb726d48Sopenharmony_ci            item[i].ts > cpuFreqData[j].ts &&
107fb726d48Sopenharmony_ci            item[i].ts < cpuFreqData[j].ts + cpuFreqData[j].dur &&
108fb726d48Sopenharmony_ci            item[i].dur >= cpuFreqData[j].ts + cpuFreqData[j].dur - item[i].ts
109fb726d48Sopenharmony_ci          ) {
110fb726d48Sopenharmony_ci            // 当running状态数据的开始时间大于频点数据开始时间,小于频点结束时间。且running数据的持续时间大于等于频点结束时间减去running数据开始时间的差值的情况
111fb726d48Sopenharmony_ci            resultList.push(returnObj(item[i], cpuFreqData[j], sum, (flag = 2))!);
112fb726d48Sopenharmony_ci          }
113fb726d48Sopenharmony_ci          // 当running状态数据的开始时间小于等于频点数据开始时间,结束时间大于频点开始时间。且running数据的持续时间减去频点数据开始时间的差值小于频点数据持续时间的情况
114fb726d48Sopenharmony_ci          if (
115fb726d48Sopenharmony_ci            item[i].ts <= cpuFreqData[j].ts &&
116fb726d48Sopenharmony_ci            item[i].ts + item[i].dur > cpuFreqData[j].ts &&
117fb726d48Sopenharmony_ci            item[i].dur + item[i].ts - cpuFreqData[j].ts < cpuFreqData[j].dur
118fb726d48Sopenharmony_ci          ) {
119fb726d48Sopenharmony_ci            resultList.push(returnObj(item[i], cpuFreqData[j], sum, (flag = 3))!);
120fb726d48Sopenharmony_ci            item.splice(i, 1);
121fb726d48Sopenharmony_ci            i--;
122fb726d48Sopenharmony_ci            break;
123fb726d48Sopenharmony_ci          }
124fb726d48Sopenharmony_ci          if (
125fb726d48Sopenharmony_ci            item[i].ts <= cpuFreqData[j].ts &&
126fb726d48Sopenharmony_ci            item[i].ts + item[i].dur > cpuFreqData[j].ts &&
127fb726d48Sopenharmony_ci            item[i].dur + item[i].ts - cpuFreqData[j].ts >= cpuFreqData[j].dur
128fb726d48Sopenharmony_ci          ) {
129fb726d48Sopenharmony_ci            // 当running状态数据的开始时间小于等于频点数据开始时间,结束时间大于频点开始时间。且running数据的持续时间减去频点数据开始时间的差值大于等于频点数据持续时间的情况
130fb726d48Sopenharmony_ci            resultList.push(returnObj(item[i], cpuFreqData[j], sum, (flag = 4))!);
131fb726d48Sopenharmony_ci          }
132fb726d48Sopenharmony_ci          if (
133fb726d48Sopenharmony_ci            item[i].ts <= cpuFreqData[j].ts &&
134fb726d48Sopenharmony_ci            item[i].ts + item[i].dur <= cpuFreqData[j].ts
135fb726d48Sopenharmony_ci          ) {
136fb726d48Sopenharmony_ci            // 当running状态数据的开始时间小于等于频点数据开始时间,结束时间小于等于频点开始时间的情况
137fb726d48Sopenharmony_ci            resultList.push(returnObj(item[i], cpuFreqData[j], sum, (flag = 5))!);
138fb726d48Sopenharmony_ci            item.splice(i, 1);
139fb726d48Sopenharmony_ci            i--;
140fb726d48Sopenharmony_ci            break;
141fb726d48Sopenharmony_ci          }
142fb726d48Sopenharmony_ci        } else {
143fb726d48Sopenharmony_ci          if (!cpuList.includes(item[i].cpu)) {
144fb726d48Sopenharmony_ci            resultList.push(returnObj(item[i], cpuFreqData[j], sum, (flag = 5))!);
145fb726d48Sopenharmony_ci            item.splice(i, 1);
146fb726d48Sopenharmony_ci            i--;
147fb726d48Sopenharmony_ci            break;
148fb726d48Sopenharmony_ci          }
149fb726d48Sopenharmony_ci        }
150fb726d48Sopenharmony_ci      }
151fb726d48Sopenharmony_ci    }
152fb726d48Sopenharmony_ci    runningFreqData.set(key, mergeSameData(resultList));
153fb726d48Sopenharmony_ci  });
154fb726d48Sopenharmony_ci  return dealTree(runningFreqData);
155fb726d48Sopenharmony_ci}
156fb726d48Sopenharmony_ci
157fb726d48Sopenharmony_ci/**
158fb726d48Sopenharmony_ci *
159fb726d48Sopenharmony_ci * @param item running数据
160fb726d48Sopenharmony_ci * @param cpuFreqData 频点数据
161fb726d48Sopenharmony_ci * @param sum running总和
162fb726d48Sopenharmony_ci * @param flag 标志位,根据不同值返回不同结果
163fb726d48Sopenharmony_ci * @returns 返回新的对象
164fb726d48Sopenharmony_ci */
165fb726d48Sopenharmony_cifunction returnObj(
166fb726d48Sopenharmony_ci  item: RunningData,
167fb726d48Sopenharmony_ci  cpuFreqData: CpuFreqData,
168fb726d48Sopenharmony_ci  sum: number,
169fb726d48Sopenharmony_ci  flag: number
170fb726d48Sopenharmony_ci): RunningFreqData | undefined {
171fb726d48Sopenharmony_ci  const PERCENT: number = 100;
172fb726d48Sopenharmony_ci  const FREQ_MUTIPLE: number = 1000;
173fb726d48Sopenharmony_ci  //@ts-ignore
174fb726d48Sopenharmony_ci  const computorPower: number = comPower ? comPower.get(item.cpu)?.mapData.get(cpuFreqData.value)! : 0;
175fb726d48Sopenharmony_ci  let result;
176fb726d48Sopenharmony_ci  switch (flag) {
177fb726d48Sopenharmony_ci    case 1:
178fb726d48Sopenharmony_ci      result = {
179fb726d48Sopenharmony_ci        thread: item.pid + '_' + item.tid,
180fb726d48Sopenharmony_ci        consumption: cpuFreqData.value * item.dur,
181fb726d48Sopenharmony_ci        cpu: item.cpu,
182fb726d48Sopenharmony_ci        frequency: computorPower ? cpuFreqData.value / FREQ_MUTIPLE + ': ' + computorPower : cpuFreqData.value / FREQ_MUTIPLE,
183fb726d48Sopenharmony_ci        dur: item.dur,
184fb726d48Sopenharmony_ci        percent: (item.dur / sum) * PERCENT,
185fb726d48Sopenharmony_ci        consumpower: computorPower * item.dur,
186fb726d48Sopenharmony_ci        cpuload: (computorPower * item.dur) / (timeZones * maxCommpuPower) * PERCENT
187fb726d48Sopenharmony_ci      };
188fb726d48Sopenharmony_ci      break;
189fb726d48Sopenharmony_ci    case 2:
190fb726d48Sopenharmony_ci      result = {
191fb726d48Sopenharmony_ci        thread: item.pid + '_' + item.tid,
192fb726d48Sopenharmony_ci        consumption: cpuFreqData.value * (cpuFreqData.ts + cpuFreqData.dur - item.ts),
193fb726d48Sopenharmony_ci        cpu: item.cpu,
194fb726d48Sopenharmony_ci        frequency: computorPower ? cpuFreqData.value / FREQ_MUTIPLE + ': ' + computorPower : cpuFreqData.value / FREQ_MUTIPLE,
195fb726d48Sopenharmony_ci        dur: cpuFreqData.ts + cpuFreqData.dur - item.ts,
196fb726d48Sopenharmony_ci        percent: ((cpuFreqData.ts + cpuFreqData.dur - item.ts) / sum) * PERCENT,
197fb726d48Sopenharmony_ci        consumpower: computorPower * (cpuFreqData.ts + cpuFreqData.dur - item.ts),
198fb726d48Sopenharmony_ci        cpuload: (computorPower * (cpuFreqData.ts + cpuFreqData.dur - item.ts)) / (timeZones * maxCommpuPower) * PERCENT
199fb726d48Sopenharmony_ci      };
200fb726d48Sopenharmony_ci      break;
201fb726d48Sopenharmony_ci    case 3:
202fb726d48Sopenharmony_ci      result = {
203fb726d48Sopenharmony_ci        thread: item.pid + '_' + item.tid,
204fb726d48Sopenharmony_ci        consumption: cpuFreqData.value * (item.dur + item.ts - cpuFreqData.ts),
205fb726d48Sopenharmony_ci        cpu: item.cpu,
206fb726d48Sopenharmony_ci        frequency: computorPower ? cpuFreqData.value / FREQ_MUTIPLE + ': ' + computorPower : cpuFreqData.value / FREQ_MUTIPLE,
207fb726d48Sopenharmony_ci        dur: item.dur + item.ts - cpuFreqData.ts,
208fb726d48Sopenharmony_ci        percent: ((item.dur + item.ts - cpuFreqData.ts) / sum) * PERCENT,
209fb726d48Sopenharmony_ci        consumpower: computorPower * (item.dur + item.ts - cpuFreqData.ts),
210fb726d48Sopenharmony_ci        cpuload: (computorPower * (item.dur + item.ts - cpuFreqData.ts)) / (timeZones * maxCommpuPower) * PERCENT
211fb726d48Sopenharmony_ci      };
212fb726d48Sopenharmony_ci      break;
213fb726d48Sopenharmony_ci    case 4:
214fb726d48Sopenharmony_ci      result = {
215fb726d48Sopenharmony_ci        thread: item.pid + '_' + item.tid,
216fb726d48Sopenharmony_ci        consumption: cpuFreqData.value * cpuFreqData.dur,
217fb726d48Sopenharmony_ci        cpu: item.cpu,
218fb726d48Sopenharmony_ci        frequency: computorPower ? cpuFreqData.value / FREQ_MUTIPLE + ': ' + computorPower : cpuFreqData.value / FREQ_MUTIPLE,
219fb726d48Sopenharmony_ci        dur: cpuFreqData.dur,
220fb726d48Sopenharmony_ci        percent: (cpuFreqData.dur / sum) * PERCENT,
221fb726d48Sopenharmony_ci        consumpower: computorPower * cpuFreqData.dur,
222fb726d48Sopenharmony_ci        cpuload: (computorPower * cpuFreqData.dur) / (timeZones * maxCommpuPower) * PERCENT
223fb726d48Sopenharmony_ci      };
224fb726d48Sopenharmony_ci      break;
225fb726d48Sopenharmony_ci    case 5:
226fb726d48Sopenharmony_ci      result = {
227fb726d48Sopenharmony_ci        thread: item.pid + '_' + item.tid,
228fb726d48Sopenharmony_ci        consumption: 0,
229fb726d48Sopenharmony_ci        cpu: item.cpu,
230fb726d48Sopenharmony_ci        frequency: 'unknown',
231fb726d48Sopenharmony_ci        dur: item.dur,
232fb726d48Sopenharmony_ci        percent: (item.dur / sum) * PERCENT,
233fb726d48Sopenharmony_ci        consumpower: 0,
234fb726d48Sopenharmony_ci        cpuload: 0
235fb726d48Sopenharmony_ci      };
236fb726d48Sopenharmony_ci      break;
237fb726d48Sopenharmony_ci  }
238fb726d48Sopenharmony_ci  return result;
239fb726d48Sopenharmony_ci}
240fb726d48Sopenharmony_ci
241fb726d48Sopenharmony_ci/**
242fb726d48Sopenharmony_ci *
243fb726d48Sopenharmony_ci * @param resultList 单线程内running数据与cpu频点数据整合成的数组
244fb726d48Sopenharmony_ci */
245fb726d48Sopenharmony_cifunction mergeSameData(
246fb726d48Sopenharmony_ci  resultList: Array<RunningFreqData>
247fb726d48Sopenharmony_ci): Array<RunningFreqData> {
248fb726d48Sopenharmony_ci  let cpuFreqArr: Array<RunningFreqData> = [];
249fb726d48Sopenharmony_ci  let cpuArr: Array<number> = [];
250fb726d48Sopenharmony_ci  //合并同一线程内,当运行所在cpu和频点相同时,dur及percent进行累加求和
251fb726d48Sopenharmony_ci  for (let i = 0; i < resultList.length; i++) {
252fb726d48Sopenharmony_ci    if (!cpuArr.includes(resultList[i].cpu)) {
253fb726d48Sopenharmony_ci      cpuArr.push(resultList[i].cpu);
254fb726d48Sopenharmony_ci      cpuFreqArr.push(creatNewObj(resultList[i].cpu));
255fb726d48Sopenharmony_ci    }
256fb726d48Sopenharmony_ci    for (let j = i + 1; j < resultList.length; j++) {
257fb726d48Sopenharmony_ci      if (
258fb726d48Sopenharmony_ci        resultList[i].cpu === resultList[j].cpu &&
259fb726d48Sopenharmony_ci        resultList[i].frequency === resultList[j].frequency
260fb726d48Sopenharmony_ci      ) {
261fb726d48Sopenharmony_ci        resultList[i].dur += resultList[j].dur;
262fb726d48Sopenharmony_ci        resultList[i].percent += resultList[j].percent;
263fb726d48Sopenharmony_ci        resultList[i].consumption += resultList[j].consumption;
264fb726d48Sopenharmony_ci        resultList[i].consumpower += resultList[j].consumpower;
265fb726d48Sopenharmony_ci        resultList[i].cpuload += resultList[j].cpuload;
266fb726d48Sopenharmony_ci        resultList.splice(j, 1);
267fb726d48Sopenharmony_ci        j--;
268fb726d48Sopenharmony_ci      }
269fb726d48Sopenharmony_ci    }
270fb726d48Sopenharmony_ci    cpuFreqArr.find(function (item) {
271fb726d48Sopenharmony_ci      if (item.cpu === resultList[i].cpu) {
272fb726d48Sopenharmony_ci        item.children?.push(resultList[i]);
273fb726d48Sopenharmony_ci        item.children?.sort((a, b) => b.consumption - a.consumption);
274fb726d48Sopenharmony_ci        item.dur += resultList[i].dur;
275fb726d48Sopenharmony_ci        item.percent += resultList[i].percent;
276fb726d48Sopenharmony_ci        item.consumption += resultList[i].consumption;
277fb726d48Sopenharmony_ci        item.consumpower += resultList[i].consumpower;
278fb726d48Sopenharmony_ci        item.cpuload += resultList[i].cpuload;
279fb726d48Sopenharmony_ci        item.thread = resultList[i].thread;
280fb726d48Sopenharmony_ci      }
281fb726d48Sopenharmony_ci    });
282fb726d48Sopenharmony_ci  }
283fb726d48Sopenharmony_ci  cpuFreqArr.sort((a, b) => a.cpu - b.cpu);
284fb726d48Sopenharmony_ci  return cpuFreqArr;
285fb726d48Sopenharmony_ci}
286fb726d48Sopenharmony_ci
287fb726d48Sopenharmony_ci/**
288fb726d48Sopenharmony_ci *
289fb726d48Sopenharmony_ci * @param params cpu层级的数据
290fb726d48Sopenharmony_ci * @returns 整理好的进程级数据
291fb726d48Sopenharmony_ci */
292fb726d48Sopenharmony_cifunction dealTree(
293fb726d48Sopenharmony_ci  params: Map<string, Array<RunningFreqData>>
294fb726d48Sopenharmony_ci): Array<RunningFreqData> {
295fb726d48Sopenharmony_ci  let result: Array<RunningFreqData> = [];
296fb726d48Sopenharmony_ci  params.forEach((item, key) => {
297fb726d48Sopenharmony_ci    let process: RunningFreqData = creatNewObj(-1, false);
298fb726d48Sopenharmony_ci    let thread: RunningFreqData = creatNewObj(-2);
299fb726d48Sopenharmony_ci    for (let i = 0; i < item.length; i++) {
300fb726d48Sopenharmony_ci      thread.children?.push(item[i]);
301fb726d48Sopenharmony_ci      thread.dur += item[i].dur;
302fb726d48Sopenharmony_ci      thread.percent += item[i].percent;
303fb726d48Sopenharmony_ci      thread.consumption += item[i].consumption;
304fb726d48Sopenharmony_ci      thread.consumpower += item[i].consumpower;
305fb726d48Sopenharmony_ci      thread.cpuload += item[i].cpuload;
306fb726d48Sopenharmony_ci      thread.thread = item[i].thread;
307fb726d48Sopenharmony_ci    }
308fb726d48Sopenharmony_ci    process.children?.push(thread);
309fb726d48Sopenharmony_ci    process.dur += thread.dur;
310fb726d48Sopenharmony_ci    process.percent += thread.percent;
311fb726d48Sopenharmony_ci    process.consumption += thread.consumption;
312fb726d48Sopenharmony_ci    process.consumpower += thread.consumpower;
313fb726d48Sopenharmony_ci    process.cpuload += thread.cpuload;
314fb726d48Sopenharmony_ci    process.thread = process.thread! + key.split('_')[0];
315fb726d48Sopenharmony_ci    result.push(process);
316fb726d48Sopenharmony_ci  });
317fb726d48Sopenharmony_ci  for (let i = 0; i < result.length; i++) {
318fb726d48Sopenharmony_ci    for (let j = i + 1; j < result.length; j++) {
319fb726d48Sopenharmony_ci      if (result[i].thread === result[j].thread) {
320fb726d48Sopenharmony_ci        result[i].children?.push(result[j].children![0]);
321fb726d48Sopenharmony_ci        result[i].dur += result[j].dur;
322fb726d48Sopenharmony_ci        result[i].percent += result[j].percent;
323fb726d48Sopenharmony_ci        result[i].consumption += result[j].consumption;
324fb726d48Sopenharmony_ci        result[i].consumpower += result[j].consumpower;
325fb726d48Sopenharmony_ci        result[i].cpuload += result[j].cpuload;
326fb726d48Sopenharmony_ci        result.splice(j, 1);
327fb726d48Sopenharmony_ci        j--;
328fb726d48Sopenharmony_ci      }
329fb726d48Sopenharmony_ci    }
330fb726d48Sopenharmony_ci  }
331fb726d48Sopenharmony_ci  return result;
332fb726d48Sopenharmony_ci}
333fb726d48Sopenharmony_ci
334fb726d48Sopenharmony_ci/**
335fb726d48Sopenharmony_ci *
336fb726d48Sopenharmony_ci * @param cpu 根据cpu值创建层级结构,cpu < 0为线程、进程层级,其余为cpu层级
337fb726d48Sopenharmony_ci * @returns
338fb726d48Sopenharmony_ci */
339fb726d48Sopenharmony_cifunction creatNewObj(cpu: number, flag: boolean = true): RunningFreqData {
340fb726d48Sopenharmony_ci  return {
341fb726d48Sopenharmony_ci    thread: flag ? '' : 'P',
342fb726d48Sopenharmony_ci    consumption: 0,
343fb726d48Sopenharmony_ci    cpu: cpu,
344fb726d48Sopenharmony_ci    frequency: -1,
345fb726d48Sopenharmony_ci    dur: 0,
346fb726d48Sopenharmony_ci    percent: 0,
347fb726d48Sopenharmony_ci    children: [],
348fb726d48Sopenharmony_ci    consumpower: 0,
349fb726d48Sopenharmony_ci    cpuload: 0
350fb726d48Sopenharmony_ci  };
351fb726d48Sopenharmony_ci}
352fb726d48Sopenharmony_ci
353fb726d48Sopenharmony_ci/**
354fb726d48Sopenharmony_ci *
355fb726d48Sopenharmony_ci * @param arr 需要整理汇总的频点级数据
356fb726d48Sopenharmony_ci * @returns 返回一个total->cpu->频点的三级树结构数组
357fb726d48Sopenharmony_ci */
358fb726d48Sopenharmony_cifunction fixTotal(arr: Array<RunningFreqData>): Array<RunningFreqData> {
359fb726d48Sopenharmony_ci  let result: Array<RunningFreqData> = [];
360fb726d48Sopenharmony_ci  let flag: number = -1;
361fb726d48Sopenharmony_ci  // 数据入参的情况是,第一条为进程数据,其后是该进程下所有线程的数据。以进程数据做分割
362fb726d48Sopenharmony_ci  for (let i = 0; i < arr.length; i++) {
363fb726d48Sopenharmony_ci    // 判断如果是进程数据,则将其children的数组清空,并以其作为最顶层数据
364fb726d48Sopenharmony_ci    if (arr[i].thread?.indexOf('P') !== -1) {
365fb726d48Sopenharmony_ci      arr[i].children = [];
366fb726d48Sopenharmony_ci      arr[i].thread = arr[i].thread + '-summary data';
367fb726d48Sopenharmony_ci      result.push(arr[i]);
368fb726d48Sopenharmony_ci      // 标志判定当前数组的长度,也可用.length判断
369fb726d48Sopenharmony_ci      flag++;
370fb726d48Sopenharmony_ci    } else {
371fb726d48Sopenharmony_ci      // 非进程数据会进入到else中,去判断当前线程数据的cpu分组是否存在,不存在则进行创建
372fb726d48Sopenharmony_ci      if (result[flag].children![arr[i].cpu] === undefined) {
373fb726d48Sopenharmony_ci        result[flag].children![arr[i].cpu] = {
374fb726d48Sopenharmony_ci          thread: 'summary data',
375fb726d48Sopenharmony_ci          consumption: 0,
376fb726d48Sopenharmony_ci          cpu: arr[i].cpu,
377fb726d48Sopenharmony_ci          frequency: -1,
378fb726d48Sopenharmony_ci          dur: 0,
379fb726d48Sopenharmony_ci          percent: 0,
380fb726d48Sopenharmony_ci          children: [],
381fb726d48Sopenharmony_ci          consumpower: 0,
382fb726d48Sopenharmony_ci          cpuload: 0
383fb726d48Sopenharmony_ci        };
384fb726d48Sopenharmony_ci      }
385fb726d48Sopenharmony_ci      // 每有一条数据要放到cpu分组下时,则将该cpu分组的各项数据累和
386fb726d48Sopenharmony_ci      result[flag].children![arr[i].cpu].consumption += arr[i].consumption;
387fb726d48Sopenharmony_ci      result[flag].children![arr[i].cpu].consumpower += arr[i].consumpower;
388fb726d48Sopenharmony_ci      result[flag].children![arr[i].cpu].cpuload += arr[i].cpuload;
389fb726d48Sopenharmony_ci      result[flag].children![arr[i].cpu].dur += arr[i].dur;
390fb726d48Sopenharmony_ci      result[flag].children![arr[i].cpu].percent += arr[i].percent;
391fb726d48Sopenharmony_ci      // 查找当前cpu分组下是否存在与当前数据的频点相同的数据,返回相同数据的索引值
392fb726d48Sopenharmony_ci      let index: number = result[flag].children![
393fb726d48Sopenharmony_ci        arr[i].cpu
394fb726d48Sopenharmony_ci      ].children?.findIndex((item) => item.frequency === arr[i].frequency)!;
395fb726d48Sopenharmony_ci      // 若存在相同频点的数据,则进行合并,不同直接push
396fb726d48Sopenharmony_ci      if (index === -1) {
397fb726d48Sopenharmony_ci        arr[i].thread = 'summary data';
398fb726d48Sopenharmony_ci        result[flag].children![arr[i].cpu].children?.push(arr[i]);
399fb726d48Sopenharmony_ci      } else {
400fb726d48Sopenharmony_ci        result[flag].children![arr[i].cpu].children![index].consumption += arr[i].consumption;
401fb726d48Sopenharmony_ci        result[flag].children![arr[i].cpu].children![index].consumpower += arr[i].consumpower;
402fb726d48Sopenharmony_ci        result[flag].children![arr[i].cpu].children![index].dur += arr[i].dur;
403fb726d48Sopenharmony_ci        result[flag].children![arr[i].cpu].children![index].percent += arr[i].percent;
404fb726d48Sopenharmony_ci        result[flag].children![arr[i].cpu].children![index].cpuload += arr[i].cpuload;
405fb726d48Sopenharmony_ci      }
406fb726d48Sopenharmony_ci    }
407fb726d48Sopenharmony_ci  }
408fb726d48Sopenharmony_ci  return result;
409fb726d48Sopenharmony_ci}
410fb726d48Sopenharmony_ci
411fb726d48Sopenharmony_ci/**
412fb726d48Sopenharmony_ci *
413fb726d48Sopenharmony_ci * @param arr1 前次整理好的区分线程的数据
414fb726d48Sopenharmony_ci * @param arr2 不区分线程的Total数据
415fb726d48Sopenharmony_ci */
416fb726d48Sopenharmony_cifunction mergeTotal(
417fb726d48Sopenharmony_ci  arr1: Array<RunningFreqData>,
418fb726d48Sopenharmony_ci  arr2: Array<RunningFreqData>
419fb726d48Sopenharmony_ci): void {
420fb726d48Sopenharmony_ci  for (let i = 0; i < arr1.length; i++) {
421fb726d48Sopenharmony_ci    const num: number = arr2.findIndex((item) =>
422fb726d48Sopenharmony_ci      item.thread?.includes(arr1[i].thread!)
423fb726d48Sopenharmony_ci    );
424fb726d48Sopenharmony_ci    arr2[num].thread = 'summary data';
425fb726d48Sopenharmony_ci    arr1[i].children?.unshift(arr2[num]);
426fb726d48Sopenharmony_ci    arr2.splice(num, 1);
427fb726d48Sopenharmony_ci  }
428fb726d48Sopenharmony_ci}
429fb726d48Sopenharmony_ci
430fb726d48Sopenharmony_ci
431fb726d48Sopenharmony_ci/**
432fb726d48Sopenharmony_ci *
433fb726d48Sopenharmony_ci * @param arr 待整理的数组,会经过递归取到最底层的数据
434fb726d48Sopenharmony_ci */
435fb726d48Sopenharmony_cifunction recursion(arr: Array<RunningFreqData>): void {
436fb726d48Sopenharmony_ci  for (let idx = 0; idx < arr.length; idx++) {
437fb726d48Sopenharmony_ci    if (arr[idx].cpu === -1) {
438fb726d48Sopenharmony_ci      resultArray.push(arr[idx]);
439fb726d48Sopenharmony_ci    }
440fb726d48Sopenharmony_ci    if (arr[idx].children) {
441fb726d48Sopenharmony_ci      recursion(arr[idx].children!);
442fb726d48Sopenharmony_ci    } else {
443fb726d48Sopenharmony_ci      resultArray.push(arr[idx]);
444fb726d48Sopenharmony_ci    }
445fb726d48Sopenharmony_ci  }
446fb726d48Sopenharmony_ci}
447fb726d48Sopenharmony_ci
448fb726d48Sopenharmony_ciself.onmessage = (e: MessageEvent): void => {
449fb726d48Sopenharmony_ci  comPower = e.data.comPower;
450fb726d48Sopenharmony_ci  resultArray = [];
451fb726d48Sopenharmony_ci  timeZones = e.data.rightNs - e.data.leftNs;
452fb726d48Sopenharmony_ci  maxCommpuPower = 0;
453fb726d48Sopenharmony_ci  if (comPower) {
454fb726d48Sopenharmony_ci    comPower.forEach(item => {
455fb726d48Sopenharmony_ci      let maxFreq = 0;
456fb726d48Sopenharmony_ci      let commpuPower = 0;
457fb726d48Sopenharmony_ci      //@ts-ignore
458fb726d48Sopenharmony_ci      for (const i of item.mapData.entries()) {
459fb726d48Sopenharmony_ci        if (i[0] > maxFreq) {
460fb726d48Sopenharmony_ci          maxFreq = i[0];
461fb726d48Sopenharmony_ci          commpuPower = i[1];
462fb726d48Sopenharmony_ci        }
463fb726d48Sopenharmony_ci      }
464fb726d48Sopenharmony_ci      //@ts-ignore
465fb726d48Sopenharmony_ci      maxCommpuPower += commpuPower * item.smtRate;
466fb726d48Sopenharmony_ci    });
467fb726d48Sopenharmony_ci  }
468fb726d48Sopenharmony_ci  let result = orgnazitionMap(e.data);
469fb726d48Sopenharmony_ci  recursion(result);
470fb726d48Sopenharmony_ci  resultArray = JSON.parse(JSON.stringify(resultArray));
471fb726d48Sopenharmony_ci  mergeTotal(result, fixTotal(resultArray));
472fb726d48Sopenharmony_ci  self.postMessage(result);
473fb726d48Sopenharmony_ci};