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 { Utils } from '../../base/Utils'; 20import { ColorUtils } from '../../base/ColorUtils'; 21import { CpuFreqLimitsStruct } from '../../../../database/ui-worker/cpu/ProcedureWorkerCpuFreqLimits'; 22import { resizeObserver } from '../SheetUtils'; 23import { getCpuLimitFreqBoxSelect } from '../../../../database/sql/Cpu.sql'; 24 25@element('tabpane-cpu-freq-limits') 26export class TabPaneCpuFreqLimits extends BaseElement { 27 private cpuFreqLimitsTbl: LitTable | null | undefined; 28 private selectionParam: SelectionParam | null | undefined; 29 private cpuFreqLimitSource: CpuFreqLimit[] = []; 30 private cpuFreqLimitSortKey: string = 'cpu'; 31 private cpuFreqLimitSortType: number = 0; 32 33 set data(cpuFreqLimitSelection: SelectionParam | unknown) { 34 if (cpuFreqLimitSelection === this.selectionParam) { 35 return; 36 } 37 // @ts-ignore 38 this.selectionParam = cpuFreqLimitSelection; 39 // @ts-ignore 40 this.cpuFreqLimitsTbl!.shadowRoot!.querySelector('.table').style.height = 41 this.parentElement!.clientHeight - 25 + 'px'; 42 let list: unknown[] = []; 43 // @ts-ignore 44 getCpuLimitFreqBoxSelect(cpuFreqLimitSelection.cpuFreqLimit, cpuFreqLimitSelection.rightNs).then((res) => { 45 for (let it of res) { 46 //@ts-ignore 47 if (!it.dur || it.startNs + it.dur > cpuFreqLimitSelection.rightNs) { 48 //@ts-ignore 49 it.dur = (cpuFreqLimitSelection.rightNs || 0) - (it.startNs || 0); 50 } 51 } 52 //@ts-ignore 53 this.formatData(res, cpuFreqLimitSelection.leftNs, cpuFreqLimitSelection.rightNs); 54 }); 55 } 56 57 initElements(): void { 58 this.cpuFreqLimitsTbl = this.shadowRoot!.querySelector<LitTable>('#tb-cpu-freq-limit'); 59 this.cpuFreqLimitsTbl!.addEventListener('column-click', (evt) => { 60 // @ts-ignore 61 this.cpuFreqLimitSortKey = evt.detail.key; 62 // @ts-ignore 63 this.cpuFreqLimitSortType = evt.detail.sort; 64 // @ts-ignore 65 this.sortCpuFreqLimitTable(evt.detail.key, evt.detail.sort); 66 }); 67 } 68 69 connectedCallback(): void { 70 super.connectedCallback(); 71 resizeObserver(this.parentElement!, this.cpuFreqLimitsTbl!, 25); 72 } 73 74 formatData(list: CpuFreqLimitsStruct[], start: number, end: number): void { 75 let limitsMap = new Map<string, CpuFreqLimit>(); 76 let groupMapData = (time: number, id: string, item: CpuFreqLimitsStruct): void => { 77 if (limitsMap.has(id)) { 78 limitsMap.get(id)!.time += time; 79 } else { 80 let isMax = id.endsWith('max'); 81 let limit = new CpuFreqLimit(); 82 limit.cpu = `Cpu ${item.cpu}`; 83 limit.time = time; 84 limit.type = isMax ? 'Max Freqency' : 'Min Frequency'; 85 limit.value = isMax ? item.max! : item.min!; 86 limitsMap.set(id, limit); 87 } 88 }; 89 list.forEach((item) => { 90 if (item.startNs! > end) { 91 return; 92 } 93 let max = Math.max(item.startNs || 0, start); 94 let min = Math.min((item.startNs || 0) + item.dur, end); 95 if (max < min) { 96 let maxId = `${item.cpu}-${item.max}-max`; 97 let minId = `${item.cpu}-${item.min}-min`; 98 groupMapData(min - max, maxId, item); 99 groupMapData(min - max, minId, item); 100 } 101 }); 102 this.cpuFreqLimitSource = Array.from(limitsMap.values()).map((item) => { 103 item.timeStr = Utils.getProbablyTime(item.time); 104 item.valueStr = `${ColorUtils.formatNumberComma(item.value!)} kHz`; 105 return item; 106 }); 107 this.cpuFreqLimitSource.sort((a, b): number => { 108 let cpuLeftData = Number(a.cpu.toString().replace('Cpu', '')); 109 let cpuRightData = Number(b.cpu.toString().replace('Cpu', '')); 110 if (cpuLeftData > cpuRightData) { 111 return 1; 112 } else { 113 return -1; 114 } 115 }); 116 this.sortCpuFreqLimitTable(this.cpuFreqLimitSortKey, this.cpuFreqLimitSortType); 117 } 118 119 sortCpuFreqLimitTable(key: string, type: number): void { 120 if (type === 0) { 121 this.cpuFreqLimitsTbl!.recycleDataSource = this.cpuFreqLimitSource; 122 } else { 123 let cpuFreqLimitsArr = Array.from(this.cpuFreqLimitSource); 124 cpuFreqLimitsArr.sort((cpuFreqLimitA, cpuFreqLimitB): number => { 125 if (key === 'timeStr') { 126 return this.compareTime(cpuFreqLimitA, cpuFreqLimitB, type); 127 } else if (key === 'valueStr') { 128 return this.compareValue(cpuFreqLimitA, cpuFreqLimitB, type); 129 } else if (key === 'cpu') { 130 return this.compareCpu(cpuFreqLimitA, cpuFreqLimitB, type); 131 } else if (key === 'type') { 132 return this.compareType(cpuFreqLimitA, cpuFreqLimitB, type); 133 } else { 134 return 0; 135 } 136 }); 137 this.cpuFreqLimitsTbl!.recycleDataSource = cpuFreqLimitsArr; 138 } 139 } 140 141 compareTime(cpuFreqLimitA: unknown, cpuFreqLimitB: unknown, type: number): number { 142 if (type === 1) { 143 // @ts-ignore 144 return cpuFreqLimitA.time - cpuFreqLimitB.time; 145 } else { 146 // @ts-ignore 147 return cpuFreqLimitB.time - cpuFreqLimitA.time; 148 } 149 } 150 151 compareValue(cpuFreqLimitA: unknown, cpuFreqLimitB: unknown, type: number): number { 152 if (type === 1) { 153 // @ts-ignore 154 return cpuFreqLimitA.value - cpuFreqLimitB.value; 155 } else { 156 // @ts-ignore 157 return cpuFreqLimitB.value - cpuFreqLimitA.value; 158 } 159 } 160 161 compareCpu(cpuFreqLimitA: unknown, cpuFreqLimitB: unknown, type: number): number { 162 // @ts-ignore 163 let cpuLeftData = Number(cpuFreqLimitA.cpu.toString().replace('Cpu', '')); 164 // @ts-ignore 165 let cpuRightData = Number(cpuFreqLimitB.cpu.toString().replace('Cpu', '')); 166 if (type === 1) { 167 return cpuLeftData - cpuRightData; 168 } else { 169 return cpuRightData - cpuLeftData; 170 } 171 } 172 173 compareType(cpuFreqLimitA: unknown, cpuFreqLimitB: unknown, type: number): number { 174 // @ts-ignore 175 if (cpuFreqLimitA.type > cpuFreqLimitB.type) { 176 return type === 2 ? 1 : -1; // @ts-ignore 177 } else if (cpuFreqLimitA.type === cpuFreqLimitB.type) { 178 return 0; 179 } else { 180 return type === 2 ? -1 : 1; 181 } 182 } 183 184 initHtml(): string { 185 return ` 186 <style> 187 .cpu-freq-limit-tbl { 188 height: auto; 189 } 190 :host{ 191 display: flex; 192 flex-direction: column; 193 padding: 10px 10px; 194 } 195 </style> 196 <lit-table id="tb-cpu-freq-limit" class="cpu-freq-limit-tbl"> 197 <lit-table-column class="cpu-freq-limit-column" width="20%" title="Cpu" data-index="cpu" key="cpu" align="flex-start" order> 198 </lit-table-column> 199 <lit-table-column class="cpu-freq-limit-column" width="1fr" title="Type" data-index="type" key="type" align="flex-start" order> 200 </lit-table-column> 201 <lit-table-column class="cpu-freq-limit-column" width="1fr" title="Time" data-index="timeStr" key="timeStr" align="flex-start" order> 202 </lit-table-column> 203 <lit-table-column class="cpu-freq-limit-column" width="1fr" title="Value" data-index="valueStr" key="valueStr" align="flex-start" order> 204 </lit-table-column> 205 </lit-table> 206 `; 207 } 208} 209 210class CpuFreqLimit { 211 cpu: string = ''; 212 type: string = ''; 213 time: number = 0; 214 value: number = 0; 215 timeStr: string = ''; 216 valueStr: string = ''; 217} 218