• 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 { BaseElement, element } from '../../../../../base-ui/BaseElement';
17import { LitTable } from '../../../../../base-ui/table/lit-table';
18import { SelectionParam } from '../../../../bean/BoxSelection';
19import { CpuUsage, Freq } from '../../../../bean/CpuUsage';
20import { resizeObserver } from '../SheetUtils';
21import { getTabCpuFreq, getTabCpuUsage } from '../../../../database/sql/Cpu.sql';
22
23@element('tabpane-cpu-usage')
24export class TabPaneCpuUsage extends BaseElement {
25  private cpuUsageTbl: LitTable | null | undefined;
26  private range: HTMLLabelElement | null | undefined;
27  private orderByOldList: unknown[] = [];
28  private currentSelectionParam: SelectionParam | undefined;
29
30  set data(cpuUsageValue: SelectionParam | unknown) {
31    if (this.currentSelectionParam === cpuUsageValue) {
32      return;
33    }
34    // @ts-ignore
35    this.currentSelectionParam = cpuUsageValue;
36    this.range!.textContent =
37      // @ts-ignore
38      `Selected range: ${parseFloat(((cpuUsageValue.rightNs - cpuUsageValue.leftNs) / 1000000.0).toFixed(5))} ms`;
39    this.cpuUsageTbl!.loading = true;
40    Promise.all([
41      // @ts-ignore
42      getTabCpuUsage(cpuUsageValue.cpus, cpuUsageValue.leftNs, cpuUsageValue.rightNs, cpuUsageValue.traceId),
43      // @ts-ignore
44      getTabCpuFreq(cpuUsageValue.cpus, cpuUsageValue.leftNs, cpuUsageValue.rightNs, cpuUsageValue.traceId),
45    ]).then((result): void => {
46      this.cpuUsageTbl!.loading = false;
47      let usages = result[0];
48      let freqMap = this.groupByCpuToMap(result[1]);
49      let data = [];
50      // @ts-ignore
51      let range = cpuUsageValue.rightNs - cpuUsageValue.leftNs;
52      // @ts-ignore
53      for (let cpu of cpuUsageValue.cpus) {
54        let usage = new CpuUsage();
55        usage.cpu = cpu;
56        let u = usages.find((e): boolean => e.cpu === cpu);
57        if (u) {
58          usage.usage = u.usage;
59        } else {
60          usage.usage = 0;
61        }
62        if (usage.usage > 1) {
63          usage.usage = 1;
64        }
65        usage.usageStr = `${(usage.usage * 100.0).toFixed(2)}%`;
66        this.handleUsage(freqMap, usage, cpuUsageValue, range);
67        data.push(usage);
68      }
69      this.cpuUsageTbl!.recycleDataSource = data;
70      this.orderByOldList = [...data];
71    });
72  }
73
74  private handleUsage(freqMap: Map<number, Array<Freq>>, usage: CpuUsage, cpuUsageValue: unknown, range: number): void {
75    let arr = [];
76    if (freqMap.has(usage.cpu)) {
77      let freqList = freqMap.get(usage.cpu);
78      let list = [];
79      for (let i = 0; i < freqList!.length; i++) {
80        let freq = freqList![i];
81        if (i === freqList!.length - 1) {
82          // @ts-ignore
83          freq.dur = cpuUsageValue.rightNs - freq.startNs;
84        } else {
85          freq.dur = freqList![i + 1].startNs - freq.startNs;
86        }
87        // @ts-ignore
88        if (freq.startNs + freq.dur > cpuUsageValue.leftNs) {
89          list.push(freq);
90        }
91      }
92      if (list.length > 0) {
93        // @ts-ignore
94        if (list[0].startNs < cpuUsageValue.leftNs) {
95          // @ts-ignore
96          list[0].dur = list[0].startNs + list[0].dur - cpuUsageValue.leftNs;
97          // @ts-ignore
98          list[0].startNs = cpuUsageValue.leftNs;
99        }
100      }
101      arr = this.sortFreq(list);
102      this.getFreqTop3(usage, arr[0], arr[1], arr[2], range);
103    }
104  }
105
106  initElements(): void {
107    this.cpuUsageTbl = this.shadowRoot?.querySelector<LitTable>('#tb-cpu-usage');
108    this.range = this.shadowRoot?.querySelector('#time-range');
109    this.cpuUsageTbl?.addEventListener('column-click', (event): void => {
110      // @ts-ignore
111      let orderType = event.detail;
112      if (orderType.sort === 1) {
113        //倒序   注意  sort会改变原数组,需要传入table上的数组 不能传入缓存排序数组
114        this.sortTable(this.cpuUsageTbl!.recycleDataSource, orderType.key, false);
115      } else if (orderType.sort === 2) {
116        //正序
117        this.sortTable(this.cpuUsageTbl!.recycleDataSource, orderType.key, true);
118      } else {
119        //默认排序
120        this.cpuUsageTbl!.recycleDataSource = [...this.orderByOldList];
121      }
122    });
123  }
124
125  connectedCallback(): void {
126    super.connectedCallback();
127    resizeObserver(this.parentElement!, this.cpuUsageTbl!);
128  }
129
130  sortTable(arr: unknown[], key: string, sort: boolean): void {
131    this.cpuUsageTbl!.recycleDataSource = arr.sort((item1, item2): number => {
132      // @ts-ignore
133      let cpuUsageLeftData = Number(item1[key].toString().replace('%', ''));
134      // @ts-ignore
135      let cpuUsageRightData = Number(item2[key].toString().replace('%', ''));
136      if (cpuUsageLeftData > cpuUsageRightData) {
137        return sort ? -1 : 1;
138      } else if (cpuUsageLeftData < cpuUsageRightData) {
139        return sort ? 1 : -1;
140      } else {
141        return 0;
142      }
143    });
144  }
145
146  sortFreq(arr: Array<Freq>): Array<Array<number>> {
147    let cpuUsageMap = new Map<number, number>();
148    for (let freq of arr) {
149      if (cpuUsageMap.has(freq.value)) {
150        let sumDur = cpuUsageMap.get(freq.value)! + freq.dur;
151        cpuUsageMap.set(freq.value, sumDur);
152      } else {
153        cpuUsageMap.set(freq.value, freq.dur);
154      }
155    }
156    let array = Array.from(cpuUsageMap);
157    array.sort((a, b) => b[1] - a[1]);
158    return array;
159  }
160
161  getFreqTop3(usage: CpuUsage, top1: Array<number>, top2: Array<number>, top3: Array<number>, range: number): void {
162    // @ts-ignore
163    usage.top1 = top1 === undefined ? '-' : top1[0];
164    usage.top1Percent = top1 === undefined ? 0 : (top1[1] * 1.0) / range;
165    usage.top1PercentStr = top1 === undefined ? '-' : `${(usage.top1Percent * 100).toFixed(2)}%`;
166    // @ts-ignore
167    usage.top2 = top2 === undefined ? '-' : top2[0];
168    usage.top2Percent = top2 === undefined ? 0 : (top2[1] * 1.0) / range;
169    usage.top2PercentStr = top2 === undefined ? '-' : `${(usage.top2Percent * 100).toFixed(2)}%`;
170    // @ts-ignore
171    usage.top3 = top3 === undefined ? '-' : top3[0];
172    usage.top3Percent = top3 === undefined ? 0 : (top3[1] * 1.0) / range;
173    usage.top3PercentStr = top3 === undefined ? '-' : `${(usage.top3Percent * 100).toFixed(2)}%`;
174  }
175
176  groupByCpuToMap(arr: Array<Freq>): Map<number, Array<Freq>> {
177    let cpuUsageMap = new Map<number, Array<Freq>>();
178    for (let spt of arr) {
179      if (cpuUsageMap.has(spt.cpu)) {
180        cpuUsageMap.get(spt.cpu)!.push(spt);
181      } else {
182        let list: Array<Freq> = [];
183        list.push(spt);
184        cpuUsageMap.set(spt.cpu, list);
185      }
186    }
187    return cpuUsageMap;
188  }
189
190  initHtml(): string {
191    return `
192        <style>
193        .cpu-usage-label{
194            width: 100%;
195            height: 20px;
196        }
197        :host{
198            padding: 10px 10px;
199            display: flex;
200            flex-direction: column;
201        }
202        </style>
203        <label id="time-range" class="cpu-usage-label" style="text-align: end;font-size: 10pt;margin-bottom: 5px">Selected range:0.0 ms</label>
204        <lit-table id="tb-cpu-usage" style="height: auto">
205            <lit-table-column class="cpu-usage-column" order width="1fr" title="CPU" data-index="cpu" key="cpu" align="flex-start">
206            </lit-table-column>
207            <lit-table-column class="cpu-usage-column" order width="1fr" title="Usage" data-index="usageStr" key="usageStr" align="flex-start" >
208            </lit-table-column>
209            <lit-table-column class="cpu-usage-column" order width="1fr" title="CPU Freq Top1(K)" data-index="top1" key="top1" align="flex-start" >
210            </lit-table-column>
211            <lit-table-column class="cpu-usage-column" order width="1fr" title="Top1 percent(%)" data-index="top1PercentStr" key="top1PercentStr" align="flex-start" >
212            </lit-table-column>
213            <lit-table-column class="cpu-usage-column" order width="1fr" title="CPU Freq Top2(K)" data-index="top2" key="top2" align="flex-start" >
214            </lit-table-column>
215            <lit-table-column class="cpu-usage-column" order width="1fr" title="Top2 percent(%)" data-index="top2PercentStr" key="top2PercentStr" align="flex-start" >
216            </lit-table-column>
217            <lit-table-column class="cpu-usage-column" order width="1fr" title="CPU Freq Top3(K)" data-index="top3" key="top3" align="flex-start" >
218            </lit-table-column>
219            <lit-table-column class="cpu-usage-column" order width="1fr" title="Top3 percent(%)" data-index="top3PercentStr" key="top3PercentStr" align="flex-start" >
220            </lit-table-column>
221        </lit-table>
222        `;
223  }
224}
225