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 { type LitTable } from '../../../../../base-ui/table/lit-table'; 18import { type SelectionParam } from '../../../../bean/BoxSelection'; 19import { MemoryConfig } from '../../../../bean/MemoryConfig'; 20import { Utils } from '../../base/Utils'; 21import { resizeObserver } from '../SheetUtils'; 22import { PurgeableTabStruct } from './TabPanePurgTotal'; 23import { querySysPurgeableTab } from '../../../../database/sql/Ability.sql'; 24import { queryProcessPurgeableTab } from '../../../../database/sql/ProcessThread.sql'; 25 26@element('tabpane-purg-pin') 27export class TabPanePurgPin extends BaseElement { 28 private purgeablePinTable: LitTable | null | undefined; 29 private purgeablePinSource: Array<PurgeableTabStruct> = []; 30 private tabTitle: HTMLDivElement | undefined | null; 31 private purgPinTimeRange: HTMLLabelElement | undefined | null; 32 private sortKey = 'avgSize'; 33 private sortType = 2; 34 35 set data(selection: SelectionParam) { 36 if (this.purgeablePinTable) { 37 //@ts-ignore 38 this.purgeablePinTable.shadowRoot?.querySelector('.table').style.height = `${ 39 this.parentElement!.clientHeight - 45 40 }px`; 41 } 42 this.init(); 43 this.purgPinTimeRange!.textContent = 44 'Selected range: ' + ((selection.rightNs - selection.leftNs) / 1000000.0).toFixed(5) + ' ms'; 45 this.purgeablePinTable!.loading = true; 46 this.purgeablePinTable!.recycleDataSource = []; 47 if (selection.purgeablePinAbility.length > 0) { 48 this.purgeablePinSource = []; 49 querySysPurgeableTab( 50 selection.leftNs, 51 selection.rightNs, 52 (MemoryConfig.getInstance().interval * 1000_000) / 5, 53 true 54 ).then((purgePinResults) => { 55 this.purgeablePinTable!.loading = false; 56 this.getDataSource(purgePinResults); 57 }); 58 } else if (selection.purgeablePinVM.length > 0) { 59 this.purgeablePinSource = []; 60 queryProcessPurgeableTab( 61 selection.leftNs, 62 selection.rightNs, 63 (MemoryConfig.getInstance().interval * 1000_000) / 5, 64 MemoryConfig.getInstance().iPid, 65 true 66 ).then((results) => { 67 this.purgeablePinTable!.loading = false; 68 this.getDataSource(results); 69 }); 70 } 71 } 72 73 getDataSource(res: unknown): void { 74 // @ts-ignore 75 if (res.length > 0) { 76 // @ts-ignore 77 for (let i = 0; i < res.length; i++) { 78 // @ts-ignore 79 this.purgeablePinSource.push(this.toTabStruct(res[i].name, res[i].maxSize, res[i].minSize, res[i].avgSize)); 80 } 81 this.sortByColumn({ key: this.sortKey, sort: this.sortType }); 82 let total = this.totalData(this.purgeablePinSource); 83 this.purgeablePinSource.unshift(total); 84 this.purgeablePinTable!.recycleDataSource = this.purgeablePinSource; 85 this.purgeablePinSource.shift(); 86 } else { 87 this.purgeablePinSource = []; 88 this.purgeablePinTable!.recycleDataSource = []; 89 } 90 } 91 92 private init(): void { 93 const thTable = this.tabTitle!.querySelector('.th'); 94 const purgePinTblNodes = thTable!.querySelectorAll('div'); 95 if (this.tabTitle!.hasAttribute('sort')) { 96 this.tabTitle!.removeAttribute('sort'); 97 purgePinTblNodes.forEach((item) => { 98 item.querySelectorAll('svg').forEach((svg) => { 99 svg.style.display = 'none'; 100 }); 101 }); 102 } 103 this.sortKey = 'avgSize'; 104 this.sortType = 2; 105 } 106 107 private toTabStruct( 108 type: string, 109 maxPurgePinSize: number, 110 minPurgePinSize: number, 111 avgPurgePinSize: number 112 ): PurgeableTabStruct { 113 const tabStruct = new PurgeableTabStruct( 114 type, 115 maxPurgePinSize, 116 minPurgePinSize, 117 avgPurgePinSize, 118 Utils.getBinaryByteWithUnit(avgPurgePinSize), 119 Utils.getBinaryByteWithUnit(maxPurgePinSize), 120 Utils.getBinaryByteWithUnit(minPurgePinSize) 121 ); 122 return tabStruct; 123 } 124 125 private totalData(source: Array<PurgeableTabStruct>): PurgeableTabStruct { 126 // 计算总的time作为表格的第一行显示 127 let pinAvg = 0; 128 let pinMax = 0; 129 let pinMin = 0; 130 for (let item of source) { 131 pinAvg += item.avgSize; 132 pinMax += item.maxSize; 133 pinMin += item.minSize; 134 } 135 let pinData = this.toTabStruct('Total', pinAvg, pinMax, pinMin); 136 return pinData; 137 } 138 139 private sortByColumn(detail: unknown): void { 140 // @ts-ignore 141 function compare(key, sort, type) { 142 return function (purgePinLeftData: unknown, purgePinRightData: unknown) { 143 // 不管哪一列的排序方式是0(默认排序),都按照avgSize列从大到小排序 144 if (sort === 0) { 145 sort = 2; 146 key = 'avgSize'; 147 type = 'number'; 148 } 149 if (type === 'number') { 150 // @ts-ignore 151 return sort === 2 // @ts-ignore 152 ? parseFloat(purgePinRightData[key]) - parseFloat(purgePinLeftData[key]) // @ts-ignore 153 : parseFloat(purgePinLeftData[key]) - parseFloat(purgePinRightData[key]); 154 } else { 155 if (sort === 2) { 156 // @ts-ignore 157 return purgePinRightData[key].toString().localeCompare(purgePinLeftData[key].toString()); 158 } else { 159 // @ts-ignore 160 return purgePinLeftData[key].toString().localeCompare(purgePinRightData[key].toString()); 161 } 162 } 163 }; 164 } 165 // @ts-ignore 166 if (detail.key === 'type') { 167 // @ts-ignore 168 this.purgeablePinSource.sort(compare(detail.key, detail.sort, 'string')); 169 } else { 170 // @ts-ignore 171 this.purgeablePinSource.sort(compare(detail.key, detail.sort, 'number')); 172 } 173 let pin = this.totalData(this.purgeablePinSource); 174 this.purgeablePinSource.unshift(pin); 175 this.purgeablePinTable!.recycleDataSource = this.purgeablePinSource; 176 this.purgeablePinSource.shift(); 177 } 178 179 initElements(): void { 180 this.purgeablePinTable = this.shadowRoot?.querySelector<LitTable>('#tb-purgeable-pin'); 181 this.tabTitle = this.purgeablePinTable!.shadowRoot?.querySelector('.thead') as HTMLDivElement; 182 this.purgPinTimeRange = this.shadowRoot?.querySelector<HTMLLabelElement>('#purg-pin-time-range'); 183 this.purgeablePinTable!.addEventListener('column-click', (evt: unknown) => { 184 // @ts-ignore 185 this.sortKey = evt.detail.key; // @ts-ignore 186 this.sortType = evt.detail.sort; 187 // @ts-ignore 188 this.sortByColumn(evt.detail); 189 }); 190 } 191 192 connectedCallback(): void { 193 super.connectedCallback(); 194 resizeObserver(this.parentElement!, this.purgeablePinTable!); 195 } 196 197 initHtml(): string { 198 return ` 199 <style> 200 :host{ 201 display: flex; 202 flex-direction: column; 203 padding: 10px 10px; 204 } 205 .purg-pin-label{ 206 display: flex; 207 height: 20px; 208 align-items: center; 209 flex-direction: row; 210 margin-bottom: 5px; 211 } 212 #purg-pin-time-range{ 213 width: auto; 214 text-align: end; 215 font-size: 10pt; 216 } 217 </style> 218 <div class="purg-pin-label"> 219 <div style="flex: 1"></div> 220 <label id="purg-pin-time-range">Selected range:0.0 ms</label> 221 </div> 222 <lit-table id="tb-purgeable-pin" style="height: auto"> 223 <lit-table-column width="1fr" title="Type" data-index="type" key="type" align="flex-start" order> 224 </lit-table-column> 225 <lit-table-column width="1fr" title="AvgSize" data-index="avgSizeStr" key="avgSize" align="flex-start" order> 226 </lit-table-column> 227 <lit-table-column width="1fr" title="MaxSize" data-index="maxSizeStr" key="maxSize" align="flex-start" order> 228 </lit-table-column> 229 <lit-table-column width="1fr" title="MinSize" data-index="minSizeStr" key="minSize" align="flex-start" order> 230 </lit-table-column> 231 </lit-table> 232 `; 233 } 234} 235