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 GpuMemory } from '../../../../bean/AbilityMonitor'; 19import { MemoryConfig } from '../../../../bean/MemoryConfig'; 20import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; 21import { Utils } from '../../base/Utils'; 22import { getTabGpuMemoryVMTrackerClickData } from '../../../../database/sql/Memory.sql'; 23 24@element('tabpane-gpu-memory-selection-vmtracker') 25export class TabPaneGpuMemorySelectVmTracker extends BaseElement { 26 private gpuMemoryClickTable: LitTable | null | undefined; 27 private gpuMemoryClickSource: Array<GpuMemory> = []; 28 private tableThead: HTMLDivElement | undefined | null; 29 30 initElements(): void { 31 this.gpuMemoryClickTable = this.shadowRoot?.querySelector<LitTable>('#gpuMemoryClickTable'); 32 this.tableThead = this.gpuMemoryClickTable?.shadowRoot?.querySelector('.thead') as HTMLDivElement; 33 this.gpuMemoryClickTable!.addEventListener('column-click', (e) => { 34 // @ts-ignore 35 this.sortGpuMemoryByColumn(e.detail.key, e.detail.sort); 36 }); 37 } 38 39 connectedCallback(): void { 40 super.connectedCallback(); 41 new ResizeObserver(() => { 42 if (this.parentElement?.clientHeight !== 0) { 43 // @ts-ignore 44 this.gpuMemoryClickTable?.shadowRoot?.querySelector('.table').style.height = 45 this.parentElement!.clientHeight - 18 + 'px'; 46 this.parentElement!.style.overflow = 'hidden'; 47 this.gpuMemoryClickTable?.reMeauseHeight(); 48 } 49 }).observe(this.parentElement!); 50 } 51 52 private init(): void { 53 const thTable = this.tableThead!.querySelector('.th'); 54 const gpuMemoryVmTrackerTblNodes = thTable!.querySelectorAll('div'); 55 if (this.tableThead!.hasAttribute('sort')) { 56 this.tableThead!.removeAttribute('sort'); 57 gpuMemoryVmTrackerTblNodes.forEach((item) => { 58 item.querySelectorAll('svg').forEach((svg) => { 59 svg.style.display = 'none'; 60 }); 61 }); 62 } 63 } 64 65 queryGpuMemoryVmTrackerClickDataByDB(startNs: number): void { 66 this.init(); 67 getTabGpuMemoryVMTrackerClickData(startNs, MemoryConfig.getInstance().iPid).then((data) => { 68 if (data.length !== null && data.length > 0) { 69 data.forEach((item) => { 70 if (item.threadName !== null) { 71 item.thread = `${item.threadName}(${item.threadId})`; 72 } else { 73 item.thread = `Thread(${item.threadId})`; 74 } 75 item.timeStamp = ns2s(item.startNs); 76 item.sizes = Utils.getBinaryByteWithUnit(item.size); 77 }); 78 this.gpuMemoryClickTable!.recycleDataSource = data.sort(function ( 79 gpuMemoryLeftData: GpuMemory, 80 gpuMemoryRightData: GpuMemory 81 ) { 82 return gpuMemoryRightData.size - gpuMemoryLeftData.size; 83 }); 84 this.gpuMemoryClickSource = data; 85 } else { 86 this.gpuMemoryClickTable!.recycleDataSource = []; 87 this.gpuMemoryClickSource = []; 88 } 89 }); 90 } 91 92 initHtml(): string { 93 return ` 94<style> 95.gpuMemoryClickTable{ 96 height: auto; 97} 98:host{ 99 display: flex; 100 flex-direction: column; 101 padding: 10px 10px; 102} 103</style> 104<lit-table id="gpuMemoryClickTable" class="gpuMemoryClickTable"> 105 <lit-table-column order title="TimeStamp" data-index="timeStamp" key="startNs" align="flex-start" width="1fr" > 106 </lit-table-column> 107 <lit-table-column order title="GpuName" data-index="gpuName" key="gpuName" align="flex-start" width="1fr" > 108 </lit-table-column> 109 <lit-table-column order title="Thread(tid)" data-index="thread" key="thread" align="flex-start" width="1fr" > 110 </lit-table-column> 111 <lit-table-column order title="Size" data-index="sizes" key="size" align="flex-start" width="1fr" > 112 </lit-table-column> 113</lit-table> 114 `; 115 } 116 117 sortGpuMemoryByColumn(column: string, sort: number): void { 118 switch (sort) { 119 case 0: 120 this.gpuMemoryClickTable!.recycleDataSource = this.gpuMemoryClickSource; 121 break; 122 default: 123 let array = [...this.gpuMemoryClickSource]; 124 switch (column) { 125 case 'startNs': 126 this.gpuMemoryClickTable!.recycleDataSource = array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 127 return sort === 1 128 ? gpuMemoryLeftData.startNs - gpuMemoryRightData.startNs 129 : gpuMemoryRightData.startNs - gpuMemoryLeftData.startNs; 130 }); 131 break; 132 case 'gpuName': 133 this.gpuMemoryClickTable!.recycleDataSource = array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 134 return sort === 1 135 ? `${gpuMemoryLeftData.gpuName}`.localeCompare(`${gpuMemoryRightData.gpuName}`) 136 : `${gpuMemoryRightData.gpuName}`.localeCompare(`${gpuMemoryLeftData.gpuName}`); 137 }); 138 break; 139 case 'size': 140 this.gpuMemoryClickTable!.recycleDataSource = array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 141 return sort === 1 142 ? gpuMemoryLeftData.size - gpuMemoryRightData.size 143 : gpuMemoryRightData.size - gpuMemoryLeftData.size; 144 }); 145 break; 146 case 'thread': 147 this.gpuMemoryClickTable!.recycleDataSource = array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 148 return sort === 1 149 ? `${gpuMemoryLeftData.thread}`.localeCompare(`${gpuMemoryRightData.thread}`) 150 : `${gpuMemoryRightData.thread}`.localeCompare(`${gpuMemoryLeftData.thread}`); 151 }); 152 break; 153 } 154 break; 155 } 156 } 157} 158