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 '../../../../../base-ui/slicer/lit-slicer'; 20import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; 21import { procedurePool } from '../../../../database/Procedure'; 22import { VirtualMemoryEvent, VM_TYPE_MAP } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; 23import { FilterData, TabPaneFilter } from '../TabPaneFilter'; 24import { getTabVirtualMemoryType } from '../../../../database/sql/Memory.sql'; 25import { TabPaneVMEventsHtml } from './TabPaneVMEvents.html'; 26 27@element('tabpane-virtualmemory-event') 28export class TabPaneVirtualMemoryEvents extends BaseElement { 29 // @ts-ignore 30 private defaultNativeTypes = ['All', ...Object.values(VM_TYPE_MAP)]; 31 private nativeType: Array<string> = [...this.defaultNativeTypes]; 32 private vmEventTbl: LitTable | null | undefined; 33 private vmEventTblData: LitTable | null | undefined; 34 private vmEventProgressEL: LitProgressBar | null | undefined; 35 private loadingList: number[] = []; 36 private loadingPage: unknown; 37 private vmEventSource: Array<VirtualMemoryEvent> = []; 38 private queryVmEventDataSource: Array<VirtualMemoryEvent> = []; 39 private currentSelection: SelectionParam | undefined | null; 40 private statsticsSelection: Array<unknown> = []; 41 42 set data(vmEventSelection: SelectionParam | null | undefined) { 43 if (vmEventSelection === this.currentSelection) { 44 return; 45 } 46 this.currentSelection = vmEventSelection; 47 this.initFilterTypes(vmEventSelection!).then(() => { 48 this.queryData(vmEventSelection!); 49 }); 50 if (this.vmEventTbl) { 51 // @ts-ignore 52 this.vmEventTbl.shadowRoot.querySelector('.table').style.height = 53 this.parentElement!.clientHeight - 20 - 31 + 'px'; 54 this.vmEventTbl.recycleDataSource = []; 55 } 56 if (this.vmEventTblData) { 57 // @ts-ignore 58 this.vmEventTblData.shadowRoot.querySelector('.table').style.height = 59 this.parentElement!.clientHeight - 20 - 31 + 'px'; 60 this.vmEventTblData.recycleDataSource = []; 61 } 62 } 63 64 connectedCallback(): void { 65 new ResizeObserver((entries) => { 66 if (this.parentElement?.clientHeight !== 0) { 67 if (this.vmEventTbl) { 68 // @ts-ignore 69 this.vmEventTbl.shadowRoot.querySelector('.table').style.height = 70 this.parentElement!.clientHeight - 10 - 33 + 'px'; 71 this.vmEventTbl.reMeauseHeight(); 72 } 73 if (this.vmEventTblData) { 74 // @ts-ignore 75 this.vmEventTblData.shadowRoot.querySelector('.table').style.height = 76 this.parentElement!.clientHeight - 10 - 33 + 'px'; 77 this.vmEventTblData.reMeauseHeight(); 78 } // @ts-ignore 79 this.loadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px'; 80 } 81 }).observe(this.parentElement!); 82 } 83 84 initElements(): void { 85 this.loadingPage = this.shadowRoot?.querySelector('.loading'); 86 this.vmEventProgressEL = this.shadowRoot?.querySelector('.vm-event-progress') as LitProgressBar; 87 this.vmEventTbl = this.shadowRoot?.querySelector<LitTable>('#vm-event-tbl'); 88 this.vmEventTblData = this.shadowRoot?.querySelector<LitTable>('#vm-event-tbr'); 89 this.vmEventTbl!.addEventListener('row-click', (vmEventRowClick) => { 90 // @ts-ignore 91 let data = vmEventRowClick.detail.data; // @ts-ignore 92 (data as unknown).isSelected = true; 93 // @ts-ignore 94 if ((vmEventRowClick.detail as unknown).callBack) { 95 // @ts-ignore 96 (vmEventRowClick.detail as unknown).callBack(true); 97 } 98 procedurePool.submitWithName( 99 'logic0', 100 'fileSystem-queryStack', 101 { callchainId: data.callchainId }, 102 undefined, 103 (res: unknown) => { 104 // @ts-ignore 105 this.vmEventTblData!.recycleDataSource = res; 106 } 107 ); 108 }); 109 this.vmEventTbl!.addEventListener('column-click', (evt) => { 110 // @ts-ignore 111 this.vmEventSortKey = evt.detail.key; 112 // @ts-ignore 113 this.vmEventSortType = evt.detail.sort; 114 // @ts-ignore 115 this.sortVmEventTable(evt.detail.key, evt.detail.sort); 116 }); 117 this.shadowRoot?.querySelector<TabPaneFilter>('#vm-event-filter')!.getFilterData((data: FilterData) => { 118 let index = parseInt(data.firstSelect || '0'); 119 if (index > this.defaultNativeTypes.length - 1) { 120 this.filterTypeData(this.statsticsSelection[index - this.defaultNativeTypes.length]); 121 } else { 122 this.filterTypeData(undefined); 123 } 124 this.vmEventTbl!.recycleDataSource = this.vmEventSource; 125 }); 126 } 127 128 async initFilterTypes(vmEventParam: SelectionParam): Promise<void> { 129 let filter = this.shadowRoot?.querySelector<TabPaneFilter>('#vm-event-filter'); 130 let typeKeys = await getTabVirtualMemoryType(vmEventParam.leftNs, vmEventParam.rightNs); 131 this.defaultNativeTypes = ['All']; 132 this.statsticsSelection = []; 133 typeKeys.forEach((item) => { 134 // @ts-ignore 135 this.defaultNativeTypes.push(VM_TYPE_MAP[item.type + '']); 136 }); 137 this.nativeType = [...this.defaultNativeTypes]; 138 filter!.setSelectList([...this.defaultNativeTypes], null, 'Operation Type'); 139 filter!.firstSelect = '0'; 140 } 141 142 async fromStastics(vmEventParam: SelectionParam | unknown): Promise<void> { 143 // @ts-ignore 144 if (vmEventParam.fileSystemVMData === undefined) { 145 return; 146 } 147 this.vmEventTblData!.recycleDataSource = []; 148 this.vmEventTblData?.clearAllSelection(undefined); 149 let filter = this.shadowRoot?.querySelector<TabPaneFilter>('#vm-event-filter'); 150 if (this.currentSelection !== vmEventParam) { 151 // @ts-ignore 152 await this.initFilterTypes(vmEventParam); 153 } // @ts-ignore 154 let typeIndexOf = this.nativeType.indexOf(vmEventParam.fileSystemVMData.path.value); 155 if (typeIndexOf === -1) { 156 // @ts-ignore 157 this.statsticsSelection.push(vmEventParam.fileSystemVMData.path); // @ts-ignore 158 this.nativeType.push(vmEventParam.fileSystemVMData.path.value); 159 typeIndexOf = this.nativeType.length - 1; 160 } 161 if (this.currentSelection !== vmEventParam) { 162 // @ts-ignore 163 this.currentSelection = vmEventParam; 164 filter!.setSelectList(this.nativeType, null, 'Operation Type'); 165 filter!.firstSelect = typeIndexOf + ''; // @ts-ignore 166 this.queryData(vmEventParam); 167 } else { 168 if (typeIndexOf === parseInt(filter!.firstSelect)) { 169 return; 170 } 171 filter!.setSelectList(this.nativeType, null, 'Operation Type'); 172 filter!.firstSelect = typeIndexOf + ''; // @ts-ignore 173 this.filterTypeData(vmEventParam?.fileSystemVMData?.path || undefined); // @ts-ignore 174 vmEventParam.fileSystemVMData = undefined; 175 this.vmEventTbl!.recycleDataSource = this.vmEventSource; 176 } 177 } 178 179 queryData(vmEventParam: SelectionParam): void { 180 this.loadingList.push(1); 181 this.vmEventProgressEL!.loading = true; // @ts-ignore 182 this.loadingPage.style.visibility = 'visible'; 183 this.vmEventSource = []; 184 this.queryVmEventDataSource = []; 185 procedurePool.submitWithName( 186 'logic0', 187 'fileSystem-queryVMEvents', 188 { 189 leftNs: vmEventParam.leftNs, 190 rightNs: vmEventParam.rightNs, 191 typeArr: vmEventParam.fileSystemType, 192 }, 193 undefined, 194 (res: unknown) => { 195 // @ts-ignore 196 this.vmEventSource = this.vmEventSource.concat(res.data); // @ts-ignore 197 this.queryVmEventDataSource = this.queryVmEventDataSource.concat(res.data); 198 // @ts-ignore 199 this.filterTypeData(vmEventParam?.fileSystemVMData?.path || undefined); 200 vmEventParam.fileSystemVMData = undefined; // @ts-ignore 201 res.data = null; // @ts-ignore 202 if (!res.isSending) { 203 this.vmEventTbl!.recycleDataSource = this.vmEventSource; 204 this.loadingList.splice(0, 1); 205 if (this.loadingList.length === 0) { 206 this.vmEventProgressEL!.loading = false; // @ts-ignore 207 this.loadingPage.style.visibility = 'hidden'; 208 } 209 } 210 } 211 ); 212 } 213 214 filterTypeData(pathData: unknown): void { 215 let filter = this.shadowRoot?.querySelector<TabPaneFilter>('#vm-event-filter'); 216 let firstSelect = filter!.firstSelect; 217 let type = -1; 218 let tid = -1; 219 let pid = -1; 220 if (parseInt(firstSelect) <= this.defaultNativeTypes.length - 1) { 221 // @ts-ignore 222 let typeEntry = Object.entries(VM_TYPE_MAP).find((entry) => { 223 return entry[1] === this.defaultNativeTypes[parseInt(firstSelect)]; 224 }); 225 type = typeEntry ? parseInt(typeEntry[0]) : 0; 226 } else if (pathData !== undefined) { 227 // @ts-ignore 228 type = parseInt(pathData.type || 0); // @ts-ignore 229 tid = pathData.tid || -1; // @ts-ignore 230 pid = pathData.pid || -1; 231 } else if (pathData === undefined) { 232 return; 233 } 234 let isTidFilter = false; 235 let isPidFilter = false; 236 let isTypeFilter = false; 237 this.vmEventSource = this.queryVmEventDataSource.filter((item) => { 238 if (tid === -1) { 239 isTidFilter = true; 240 } else { 241 isTidFilter = item.tid === tid; 242 } 243 if (pid === -1) { 244 isPidFilter = true; 245 } else { 246 isPidFilter = item.pid === pid; 247 } 248 isTypeFilter = type === 0 || item.type === type; 249 return isTidFilter && isPidFilter && isTypeFilter; 250 }); 251 } 252 253 sortVmEventTable(key: string, type: number): void { 254 if (type === 0) { 255 this.vmEventTbl!.recycleDataSource = this.vmEventSource; 256 } else { 257 let arr = Array.from(this.vmEventSource); 258 arr.sort((vmEventA, vmEventB): number => { 259 if (key === 'startTsStr') { 260 if (type === 1) { 261 return vmEventA.startTs - vmEventB.startTs; 262 } else { 263 return vmEventB.startTs - vmEventA.startTs; 264 } 265 } else if (key === 'durStr') { 266 if (type === 1) { 267 return vmEventA.dur - vmEventB.dur; 268 } else { 269 return vmEventB.dur - vmEventA.dur; 270 } 271 } else if (key === 'thread') { 272 if (vmEventA.thread > vmEventB.thread) { 273 return type === 2 ? 1 : -1; 274 } else if (vmEventA.thread === vmEventB.thread) { 275 return 0; 276 } else { 277 return type === 2 ? -1 : 1; 278 } 279 } else if (key === 'sizeStr') { 280 if (type === 1) { 281 return vmEventA.size - vmEventB.size; 282 } else { 283 return vmEventB.size - vmEventA.size; 284 } 285 } else { 286 return 0; 287 } 288 }); 289 this.vmEventTbl!.recycleDataSource = arr; 290 } 291 } 292 293 initHtml(): string { 294 return TabPaneVMEventsHtml; 295 } 296} 297