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.js"; 17import {LitTable} from "../../../../../base-ui/table/lit-table.js"; 18import {SelectionParam} from "../../../../bean/BoxSelection.js"; 19import "../../../../../base-ui/slicer/lit-slicer.js"; 20import {LitProgressBar} from "../../../../../base-ui/progress-bar/LitProgressBar.js"; 21import {procedurePool} from "../../../../database/Procedure.js"; 22import { 23 FileSysEvent, 24 VirtualMemoryEvent, 25 VM_TYPE_MAP 26} from "../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js"; 27import {FilterData, TabPaneFilter} from "../TabPaneFilter.js"; 28import {getTabVirtualMemoryType} from "../../../../database/SqlLite.js"; 29 30@element('tabpane-virtualmemory-event') 31export class TabPaneVirtualMemoryEvents extends BaseElement { 32 private defaultNativeTypes = ["All",...Object.values(VM_TYPE_MAP)]; 33 private native_type: Array<string> = [...this.defaultNativeTypes]; 34 private tbl: LitTable | null | undefined; 35 private tblData: LitTable | null | undefined; 36 private progressEL:LitProgressBar | null | undefined; 37 private loadingList:number[] = [] 38 private loadingPage:any; 39 private source: Array<VirtualMemoryEvent> = []; 40 private queryDataSource: Array<VirtualMemoryEvent> = []; 41 private sortKey: string = "startTs"; 42 private sortType: number = 0; 43 private currentSelection: SelectionParam | undefined | null 44 private statsticsSelection: Array<any> = [] 45 46 set data(val: SelectionParam | null | undefined) { 47 if (val == this.currentSelection) { 48 return 49 } 50 this.currentSelection = val 51 this.initFilterTypes(val!).then(()=>{ 52 this.queryData(val!) 53 }); 54 // @ts-ignore 55 this.tbl?.shadowRoot.querySelector(".table").style.height = (this.parentElement.clientHeight - 20 - 31) + "px" 56 // @ts-ignore 57 this.tblData?.shadowRoot.querySelector(".table").style.height = (this.parentElement.clientHeight - 20 - 31) + "px" 58 this.tbl!.recycleDataSource = []; 59 this.tblData!.recycleDataSource = []; 60 61 62 } 63 64 connectedCallback() { 65 new ResizeObserver((entries) => { 66 if (this.parentElement?.clientHeight != 0) { 67 // @ts-ignore 68 this.tbl?.shadowRoot.querySelector(".table").style.height = (this.parentElement.clientHeight) - 10 - 33 + "px"; 69 this.tbl?.reMeauseHeight(); 70 // @ts-ignore 71 this.tblData?.shadowRoot.querySelector(".table").style.height = (this.parentElement.clientHeight) - 10 -33 + "px" 72 this.tblData?.reMeauseHeight() 73 this.loadingPage.style.height = (this.parentElement!.clientHeight - 24) + "px" 74 } 75 }).observe(this.parentElement!) 76 } 77 78 initElements(): void { 79 this.loadingPage = this.shadowRoot?.querySelector('.loading'); 80 this.progressEL = this.shadowRoot?.querySelector('.progress') as LitProgressBar; 81 this.tbl = this.shadowRoot?.querySelector<LitTable>('#tbl'); 82 this.tblData = this.shadowRoot?.querySelector<LitTable>('#tbr'); 83 this.tbl!.addEventListener('row-click', (e) => { 84 // @ts-ignore 85 let data = e.detail.data; 86 (data as any).isSelected = true; 87 // @ts-ignore 88 if ((e.detail as any).callBack) { 89 // @ts-ignore 90 (e.detail as any).callBack(true) 91 } 92 procedurePool.submitWithName("logic0","fileSystem-queryStack", 93 { callchainId : data.callchainId },undefined,(res:any)=>{ 94 this.tblData!.recycleDataSource = res; 95 }) 96 }); 97 this.tbl!.addEventListener('column-click', (evt) => { 98 // @ts-ignore 99 this.sortKey = evt.detail.key 100 // @ts-ignore 101 this.sortType = evt.detail.sort 102 // @ts-ignore 103 this.sortTable(evt.detail.key,evt.detail.sort) 104 }) 105 this.shadowRoot?.querySelector<TabPaneFilter>("#filter")!.getFilterData((data: FilterData) => { 106 let index = parseInt(data.firstSelect||"0"); 107 if(index > this.defaultNativeTypes.length -1){ 108 this.filterTypeData(this.statsticsSelection[index - this.defaultNativeTypes.length]) 109 }else { 110 this.filterTypeData(undefined) 111 } 112 this.tbl!.recycleDataSource = this.source 113 }) 114 } 115 116 async initFilterTypes(val: SelectionParam){ 117 let filter = this.shadowRoot?.querySelector<TabPaneFilter>("#filter") 118 let typeKeys = await getTabVirtualMemoryType(val.leftNs,val.rightNs); 119 this.defaultNativeTypes = ["All"] 120 this.statsticsSelection = [] 121 typeKeys.forEach((item)=>{ 122 // @ts-ignore 123 this.defaultNativeTypes.push(VM_TYPE_MAP[item.type+""]) 124 }) 125 this.native_type = [...this.defaultNativeTypes] 126 filter!.setSelectList([...this.defaultNativeTypes],null,"Operation Type") 127 filter!.firstSelect = "0" 128 } 129 130 async fromStastics(val: SelectionParam | any) { 131 if(val.fileSystemVMData == undefined){ 132 return 133 } 134 this.tblData!.recycleDataSource = [] 135 this.tblData?.clearAllSelection(undefined) 136 let filter = this.shadowRoot?.querySelector<TabPaneFilter>("#filter") 137 if (this.currentSelection != val) { 138 await this.initFilterTypes(val) 139 } 140 let typeIndexOf = this.native_type.indexOf(val.fileSystemVMData.path.value); 141 if(typeIndexOf == -1){ 142 this.statsticsSelection.push(val.fileSystemVMData.path) 143 this.native_type.push(val.fileSystemVMData.path.value) 144 typeIndexOf = this.native_type.length - 1 145 } 146 if (this.currentSelection != val) { 147 this.currentSelection = val 148 filter!.setSelectList(this.native_type, null,"Operation Type") 149 filter!.firstSelect = typeIndexOf + "" 150 this.queryData(val) 151 }else { 152 if(typeIndexOf == parseInt(filter!.firstSelect)){ 153 return 154 } 155 filter!.setSelectList(this.native_type, null,"Operation Type") 156 filter!.firstSelect = typeIndexOf + "" 157 this.filterTypeData(val?.fileSystemVMData?.path||undefined) 158 val.fileSystemVMData = undefined 159 this.tbl!.recycleDataSource = this.source 160 } 161 } 162 163 queryData(val: SelectionParam){ 164 this.loadingList.push(1) 165 this.progressEL!.loading = true 166 this.loadingPage.style.visibility = "visible" 167 this.source = []; 168 this.queryDataSource = []; 169 procedurePool.submitWithName("logic0","fileSystem-queryVMEvents", 170 {leftNs:val.leftNs,rightNs:val.rightNs,typeArr:val.fileSystemType},undefined,(res:any)=>{ 171 this.source = this.source.concat(res.data) 172 this.queryDataSource = this.queryDataSource.concat(res.data) 173 this.filterTypeData(val?.fileSystemVMData?.path||undefined) 174 val.fileSystemVMData = undefined 175 res.data = null; 176 if(!res.isSending){ 177 this.tbl!.recycleDataSource = this.source; 178 this.loadingList.splice(0,1) 179 if(this.loadingList.length == 0) { 180 this.progressEL!.loading = false 181 this.loadingPage.style.visibility = "hidden" 182 } 183 } 184 }) 185 } 186 187 filterTypeData(pathData:any){ 188 let filter = this.shadowRoot?.querySelector<TabPaneFilter>("#filter") 189 let firstSelect = filter!.firstSelect; 190 let type = -1; 191 let tid = -1; 192 let pid = -1; 193 if(parseInt(firstSelect) <= this.defaultNativeTypes.length - 1){ 194 let typeEntry = Object.entries(VM_TYPE_MAP).find((entry)=>{ 195 return entry[1] == this.defaultNativeTypes[parseInt(firstSelect)] 196 }) 197 type = typeEntry?parseInt(typeEntry[0]):0 198 }else if(pathData!=undefined){ 199 type = parseInt(pathData.type); 200 tid = pathData.tid||-1; 201 pid = pathData.pid||-1; 202 }else if(pathData==undefined){ 203 return 204 } 205 let isTidFilter = false; 206 let isPidFilter = false; 207 let isTypeFilter = false; 208 this.source = this.queryDataSource.filter((item)=>{ 209 if(tid == -1){ 210 isTidFilter = true 211 }else { 212 isTidFilter = item.tid == tid 213 } 214 if(pid == -1){ 215 isPidFilter = true 216 }else{ 217 isPidFilter = item.pid == pid 218 } 219 isTypeFilter = type == 0 || item.type == type; 220 return isTidFilter&&isPidFilter&&isTypeFilter 221 }) 222 } 223 224 sortTable(key: string,type:number){ 225 if(type == 0){ 226 this.tbl!.recycleDataSource = this.source 227 }else{ 228 let arr = Array.from(this.source) 229 arr.sort((a,b):number=>{ 230 if(key == "startTsStr"){ 231 if(type == 1){ 232 return a.startTs - b.startTs ; 233 }else{ 234 return b.startTs - a.startTs ; 235 } 236 }else if(key == "durStr"){ 237 if(type == 1){ 238 return a.dur - b.dur ; 239 }else{ 240 return b.dur - a.dur ; 241 } 242 }else if(key == "thread"){ 243 if (a.thread > b.thread) { 244 return type === 2 ? 1 : -1; 245 } else if (a.thread == b.thread) { 246 return 0; 247 } else { 248 return type === 2 ? -1 : 1; 249 } 250 }else if(key == "sizeStr"){ 251 if(type == 1){ 252 return a.size - b.size ; 253 }else{ 254 return b.size - a.size ; 255 } 256 }else{ 257 return 0; 258 } 259 }) 260 this.tbl!.recycleDataSource = arr; 261 } 262 } 263 264 initHtml(): string { 265 return ` 266 <style> 267 :host{ 268 display: flex; 269 flex-direction: column; 270 padding: 10px 10px 0 10px; 271 } 272 .loading{ 273 bottom: 0; 274 position: absolute; 275 left: 0; 276 right: 0; 277 width:100%; 278 background:transparent; 279 z-index: 999999; 280 } 281 .progress{ 282 bottom: 33px; 283 position: absolute; 284 height: 1px; 285 z-index: 99; 286 left: 0; 287 right: 0; 288 } 289 tab-pane-filter { 290 border: solid rgb(216,216,216) 1px; 291 float: left; 292 position: fixed; 293 bottom: 0; 294 width: 100%; 295 } 296 </style> 297 <div style="display: flex;flex-direction: column"> 298 <div style="display: flex;flex-direction: row;"> 299 <lit-slicer style="width:100%"> 300 <div style="width: 65%"> 301 <lit-table id="tbl" style="height: auto"> 302 <lit-table-column width="1fr" title="Start Time" data-index="startTsStr" key="startTsStr" align="flex-start" order></lit-table-column> 303 <lit-table-column width="1fr" title="Duration" data-index="durStr" key="durStr" align="flex-start" order></lit-table-column> 304 <lit-table-column width="1fr" title="Thread" data-index="thread" key="thread" align="flex-start" order></lit-table-column> 305 <lit-table-column width="1fr" title="Operation" data-index="operation" key="operation" align="flex-start" ></lit-table-column> 306 <lit-table-column width="1fr" title="Adress" data-index="address" key="address" align="flex-start" ></lit-table-column> 307 <lit-table-column width="1fr" title="Size" data-index="sizeStr" key="sizeStr" align="flex-start" order></lit-table-column> 308 </lit-table> 309 </div> 310 <lit-slicer-track ></lit-slicer-track> 311 <lit-table id="tbr" no-head style="height: auto;border-left: 1px solid var(--dark-border1,#e2e2e2)"> 312 <lit-table-column width="60px" title="" data-index="type" key="type" align="flex-start" > 313 <template> 314 <div v-if=" type == -1 ">Thread:</div> 315 <img src="img/library.png" size="20" v-if=" type == 1 "> 316 <img src="img/function.png" size="20" v-if=" type == 0 "> 317 </template> 318 </lit-table-column> 319 <lit-table-column width="1fr" title="" data-index="symbol" key="symbol" align="flex-start"> 320 </lit-table-column> 321 </lit-table> 322 </lit-slicer> 323 </div> 324 <lit-progress-bar class="progress"></lit-progress-bar> 325 <tab-pane-filter id="filter" first></tab-pane-filter> 326 <div class="loading"></div> 327 </div> 328`; 329 } 330} 331