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