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.sortCpuFreqLimitTable(this.cpuFreqLimitSortKey, this.cpuFreqLimitSortType); 108 } 109 110 sortCpuFreqLimitTable(key: string, type: number): void { 111 if (type === 0) { 112 this.cpuFreqLimitsTbl!.recycleDataSource = this.cpuFreqLimitSource; 113 } else { 114 let cpuFreqLimitsArr = Array.from(this.cpuFreqLimitSource); 115 cpuFreqLimitsArr.sort((cpuFreqLimitA, cpuFreqLimitB): number => { 116 if (key === 'timeStr') { 117 return this.compareTime(cpuFreqLimitA, cpuFreqLimitB, type); 118 } else if (key === 'valueStr') { 119 return this.compareValue(cpuFreqLimitA, cpuFreqLimitB, type); 120 } else if (key === 'cpu') { 121 return this.compareCpu(cpuFreqLimitA, cpuFreqLimitB, type); 122 } else if (key === 'type') { 123 return this.compareType(cpuFreqLimitA, cpuFreqLimitB, type); 124 } else { 125 return 0; 126 } 127 }); 128 this.cpuFreqLimitsTbl!.recycleDataSource = cpuFreqLimitsArr; 129 } 130 } 131 132 compareTime(cpuFreqLimitA: unknown, cpuFreqLimitB: unknown, type: number): number { 133 if (type === 1) { 134 // @ts-ignore 135 return cpuFreqLimitA.time - cpuFreqLimitB.time; 136 } else { 137 // @ts-ignore 138 return cpuFreqLimitB.time - cpuFreqLimitA.time; 139 } 140 } 141 142 compareValue(cpuFreqLimitA: unknown, cpuFreqLimitB: unknown, type: number): number { 143 if (type === 1) { 144 // @ts-ignore 145 return cpuFreqLimitA.value - cpuFreqLimitB.value; 146 } else { 147 // @ts-ignore 148 return cpuFreqLimitB.value - cpuFreqLimitA.value; 149 } 150 } 151 152 compareCpu(cpuFreqLimitA: unknown, cpuFreqLimitB: unknown, type: number): number { 153 // @ts-ignore 154 if (cpuFreqLimitA.cpu > cpuFreqLimitB.cpu) { 155 return type === 2 ? -1 : 1; // @ts-ignore 156 } else if (cpuFreqLimitA.cpu === cpuFreqLimitB.cpu) { 157 return 0; 158 } else { 159 return type === 2 ? 1 : -1; 160 } 161 } 162 163 compareType(cpuFreqLimitA: unknown, cpuFreqLimitB: unknown, type: number): number { 164 // @ts-ignore 165 if (cpuFreqLimitA.type > cpuFreqLimitB.type) { 166 return type === 2 ? 1 : -1; // @ts-ignore 167 } else if (cpuFreqLimitA.type === cpuFreqLimitB.type) { 168 return 0; 169 } else { 170 return type === 2 ? -1 : 1; 171 } 172 } 173 174 initHtml(): string { 175 return ` 176 <style> 177 .cpu-freq-limit-tbl { 178 height: auto; 179 } 180 :host{ 181 display: flex; 182 flex-direction: column; 183 padding: 10px 10px; 184 } 185 </style> 186 <lit-table id="tb-cpu-freq-limit" class="cpu-freq-limit-tbl"> 187 <lit-table-column class="cpu-freq-limit-column" width="20%" title="Cpu" data-index="cpu" key="cpu" align="flex-start" order> 188 </lit-table-column> 189 <lit-table-column class="cpu-freq-limit-column" width="1fr" title="Type" data-index="type" key="type" align="flex-start" order> 190 </lit-table-column> 191 <lit-table-column class="cpu-freq-limit-column" width="1fr" title="Time" data-index="timeStr" key="timeStr" align="flex-start" order> 192 </lit-table-column> 193 <lit-table-column class="cpu-freq-limit-column" width="1fr" title="Value" data-index="valueStr" key="valueStr" align="flex-start" order> 194 </lit-table-column> 195 </lit-table> 196 `; 197 } 198} 199 200class CpuFreqLimit { 201 cpu: string = ''; 202 type: string = ''; 203 time: number = 0; 204 value: number = 0; 205 timeStr: string = ''; 206 valueStr: string = ''; 207} 208