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 SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot'; 19import { MemoryConfig } from '../../../../bean/MemoryConfig'; 20import { Utils } from '../../base/Utils'; 21import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; 22import { type LitSelect } from '../../../../../base-ui/select/LitSelect'; 23import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; 24import { resizeObserverFromMemory } from '../SheetUtils'; 25import { queryVmTrackerShmSelectionData } from '../../../../database/sql/Memory.sql'; 26import { TabPaneVmTrackerShmComparisonHtml } from './TabPaneVmTrackerShmComparison.html'; 27 28@element('tabpane-vmtracker-shm-comparison') 29export class TabPaneVmTrackerShmComparison extends BaseElement { 30 private comparisonTableEl: LitTable | undefined | null; 31 private baseFileTs: number | undefined | null; 32 private targetFileTs: number | undefined | null; 33 private comparisonData!: unknown[]; 34 private baseFileData: Array<unknown> = []; 35 private targetFileData: Array<unknown> = []; 36 private memoryConfig: MemoryConfig = MemoryConfig.getInstance(); 37 private selectEl: LitSelect | undefined | null; 38 private filterEl: TabPaneJsMemoryFilter | undefined | null; 39 private comparisonSource: Array<ShmObj> = []; 40 41 initElements(): void { 42 this.comparisonTableEl = this.shadowRoot!.querySelector<LitTable>('#tb-comparison') as LitTable; 43 this.filterEl = this.shadowRoot!.querySelector<TabPaneJsMemoryFilter>('#filter'); 44 this.selectEl = this.filterEl?.shadowRoot?.querySelector<LitSelect>('lit-select'); 45 this.comparisonTableEl!.addEventListener('column-click', (e) => { 46 // @ts-ignore 47 this.sortShmByColumn(e.detail.key, e.detail.sort); 48 }); 49 } 50 51 connectedCallback(): void { 52 super.connectedCallback(); 53 resizeObserverFromMemory(this.parentElement!, this.comparisonTableEl!, this.filterEl!); 54 } 55 56 setShmData(data: SnapshotStruct, dataList: Array<SnapshotStruct>): void { 57 let fileArr: SnapshotStruct[] = []; 58 for (let file of dataList) { 59 if (file.startNs !== data.startNs) { 60 fileArr.push(file); 61 } 62 } 63 fileArr = fileArr.sort(); 64 this.baseFileTs = data.startNs; 65 this.initSelect(data.startNs, fileArr); 66 this.targetFileTs = fileArr[0].startNs; 67 this.updateComparisonData(data.startNs, fileArr[0].startNs); 68 } 69 70 async updateComparisonData(baseFileTs: number, targetFileTs: number): Promise<void> { 71 await queryVmTrackerShmSelectionData(baseFileTs, this.memoryConfig.iPid).then((result) => { 72 this.baseFileData = result; 73 }); 74 await queryVmTrackerShmSelectionData(targetFileTs, this.memoryConfig.iPid).then((result) => { 75 this.targetFileData = result; 76 }); 77 let sizeData = this.calSizeObj(this.baseFileData, this.targetFileData); 78 this.comparisonData = []; 79 this.comparisonData.push(sizeData); 80 // @ts-ignore 81 this.comparisonSource = this.comparisonData; 82 this.comparisonTableEl!.snapshotDataSource = this.comparisonData; 83 } 84 85 calSizeObj(baseFileData: Array<unknown>, targetFileData: Array<unknown>): ShmObj { 86 let sizeObj = new ShmObj(); 87 let baseSumSize = 0; 88 let targetSumSize = 0; 89 for (let file of baseFileData) { 90 // @ts-ignore 91 baseSumSize += file.size; 92 } 93 for (let file of targetFileData) { 94 // @ts-ignore 95 targetSumSize += file.size; 96 } 97 sizeObj.sizeDelta = baseSumSize - targetSumSize; 98 sizeObj.sizeDeltaStr = Utils.getBinaryByteWithUnit(sizeObj.sizeDelta); 99 return sizeObj; 100 } 101 102 initSelect(fileId: number, fileArr: Array<SnapshotStruct>): void { 103 let input = this.selectEl!.shadowRoot?.querySelector('input') as HTMLInputElement; 104 this.selectEl!.innerHTML = ''; 105 let option = new LitSelectOption(); 106 option.innerHTML = 'File Name'; 107 option.setAttribute('disabled', 'disabled'); 108 this.selectEl?.appendChild(option); 109 if (fileArr[0].name) { 110 option.setAttribute('value', fileArr[0].name); 111 } 112 this.selectEl!.defaultValue = fileArr[0].name || ''; 113 this.selectEl!.placeholder = fileArr[0].name || ''; 114 this.selectEl!.dataSource = fileArr; 115 let selectOption = this.selectEl!.querySelectorAll('lit-select-option'); 116 for (const item of selectOption) { 117 item.addEventListener('onSelected', (e) => { 118 this.comparisonTableEl!.scrollTop = 0; 119 for (let f of fileArr) { 120 if (input.value === f.name) { 121 this.updateComparisonData(fileId, f.startNs); 122 } 123 } 124 e.stopPropagation(); 125 }); 126 } 127 } 128 129 sortShmByColumn(column: string, sort: number): void { 130 switch (sort) { 131 case 0: 132 this.comparisonTableEl!.snapshotDataSource = this.comparisonSource; 133 break; 134 default: 135 let array = [...this.comparisonSource]; 136 switch (column) { 137 case 'sizeDelta': 138 this.comparisonTableEl!.snapshotDataSource = array.sort((shmComparisonLeftData, shmComparisonRightData) => { 139 return sort === 1 140 ? shmComparisonLeftData.sizeDelta - shmComparisonRightData.sizeDelta 141 : shmComparisonRightData.sizeDelta - shmComparisonLeftData.sizeDelta; 142 }); 143 break; 144 } 145 break; 146 } 147 } 148 149 initHtml(): string { 150 return TabPaneVmTrackerShmComparisonHtml; 151 } 152} 153 154class ShmObj { 155 sizeDelta = 0; 156 sizeDeltaStr: string = ''; 157} 158