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 DISKIO_TYPE_MAP, 24 FileSysEvent, 25 IoCompletionTimes, VirtualMemoryEvent, 26 VM_TYPE_MAP 27} from "../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js"; 28import {TabPaneFilter} from "../TabPaneFilter.js"; 29import {getTabVirtualMemoryType} from "../../../../database/SqlLite.js"; 30 31@element('tabpane-io-completiontimes') 32export class TabPaneIoCompletionTimes extends BaseElement { 33 private defaultNativeTypes = ["All",...Object.values(VM_TYPE_MAP)]; 34 private native_type: Array<string> = [...this.defaultNativeTypes]; 35 private tbl: LitTable | null | undefined; 36 private tblData: LitTable | null | undefined; 37 private progressEL:LitProgressBar | null | undefined; 38 private loadingList:number[] = [] 39 private loadingPage:any; 40 private sortKey: string = "startTs"; 41 private sortType: number = 0; 42 private currentSelection: SelectionParam | undefined | null 43 private source: Array<IoCompletionTimes> = []; 44 private queryDataSource: Array<IoCompletionTimes> = []; 45 private statsticsSelection: Array<any> = [] 46 47 set data(val: SelectionParam | null | undefined) { 48 if (val == this.currentSelection) { 49 return 50 } 51 this.currentSelection = val 52 this.initFilterTypes(val!).then(()=>{ 53 this.queryData(val!) 54 }); 55 // @ts-ignore 56 this.tbl?.shadowRoot.querySelector(".table").style.height = (this.parentElement.clientHeight - 20 - 31) + "px" 57 // @ts-ignore 58 this.tblData?.shadowRoot.querySelector(".table").style.height = (this.parentElement.clientHeight - 20 - 31) + "px" 59 this.tbl!.recycleDataSource = []; 60 this.tblData!.recycleDataSource = []; 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 as FileSysEvent); 86 procedurePool.submitWithName("logic0","fileSystem-queryStack", 87 { callchainId : data.callchainId },undefined,(res:any)=>{ 88 this.tblData!.recycleDataSource = res; 89 }) 90 }); 91 this.tbl!.addEventListener('column-click', (evt) => { 92 // @ts-ignore 93 this.sortKey = evt.detail.key 94 // @ts-ignore 95 this.sortType = evt.detail.sort 96 // @ts-ignore 97 this.sortTable(evt.detail.key,evt.detail.sort) 98 }) 99 } 100 101 async initFilterTypes(val: SelectionParam){ 102 let filter = this.shadowRoot?.querySelector<TabPaneFilter>("#filter") 103 let typeKeys = await getTabVirtualMemoryType(val.leftNs,val.rightNs); 104 this.defaultNativeTypes = ["All"] 105 typeKeys.forEach((item)=>{ 106 // @ts-ignore 107 this.defaultNativeTypes.push(VM_TYPE_MAP[item.type+""]) 108 }) 109 this.native_type = [...this.defaultNativeTypes] 110 filter!.setSelectList([...this.defaultNativeTypes],null,"Operation Type") 111 filter!.firstSelect = "0" 112 } 113 114 async fromStastics(val: SelectionParam | any) { 115 if(val.fileSystemVMData == undefined){ 116 return 117 } 118 this.tblData!.recycleDataSource = [] 119 this.tblData?.clearAllSelection(undefined) 120 let filter = this.shadowRoot?.querySelector<TabPaneFilter>("#filter") 121 if (this.currentSelection != val) { 122 await this.initFilterTypes(val) 123 } 124 let typeIndexOf = this.native_type.indexOf(val.fileSystemVMData.path.value); 125 if(typeIndexOf == -1){ 126 this.statsticsSelection.push(val.fileSystemVMData.path) 127 this.native_type.push(val.fileSystemVMData.path.value) 128 typeIndexOf = this.native_type.length - 1 129 } 130 if (this.currentSelection != val) { 131 this.currentSelection = val 132 filter!.setSelectList(this.native_type, null,"Operation Type") 133 filter!.firstSelect = typeIndexOf + "" 134 this.queryData(val) 135 }else { 136 if(typeIndexOf == parseInt(filter!.firstSelect)){ 137 return 138 } 139 filter!.setSelectList(this.native_type, null,"Operation Type") 140 filter!.firstSelect = typeIndexOf + "" 141 this.filterTypeData(val?.fileSystemVMData?.path||undefined) 142 val.fileSystemVMData = undefined 143 this.tbl!.recycleDataSource = this.source 144 } 145 } 146 147 queryData(val: SelectionParam){ 148 this.loadingList.push(1) 149 this.progressEL!.loading = true 150 this.loadingPage.style.visibility = "visible" 151 this.source = []; 152 this.queryDataSource = []; 153 procedurePool.submitWithName("logic0","fileSystem-queryIOEvents", 154 {leftNs:val.leftNs,rightNs:val.rightNs,typeArr:val.fileSystemType},undefined,(res:any)=>{ 155 this.source = this.source.concat(res.data) 156 this.queryDataSource = this.queryDataSource.concat(res.data) 157 this.filterTypeData(val?.fileSystemVMData?.path||undefined) 158 val.fileSystemVMData = undefined 159 res.data = null; 160 if(!res.isSending){ 161 this.tbl!.recycleDataSource = this.source; 162 this.loadingList.splice(0,1) 163 if(this.loadingList.length == 0) { 164 this.progressEL!.loading = false 165 this.loadingPage.style.visibility = "hidden" 166 } 167 } 168 }) 169 } 170 171 filterTypeData(pathData:any){ 172 } 173 174 sortTable(key: string,type:number){ 175 if(type == 0){ 176 this.tbl!.recycleDataSource = this.source 177 }else{ 178 let arr = Array.from(this.source) 179 arr.sort((a,b):number=>{ 180 if(key == "startTsStr"){ 181 if(type == 1){ 182 return a.startTs - b.startTs ; 183 }else{ 184 return b.startTs - a.startTs ; 185 } 186 }else if(key == "durStr"){ 187 if(type == 1){ 188 return a.dur - b.dur ; 189 }else{ 190 return b.dur - a.dur ; 191 } 192 }else if(key == "process"){ 193 if (a.process > b.process) { 194 return type === 2 ? 1 : -1; 195 } else if (a.process == b.process) { 196 return 0; 197 } else { 198 return type === 2 ? -1 : 1; 199 } 200 }else if(key == "durPer4kStr"){ 201 if(type == 1){ 202 return a.durPer4k - b.durPer4k ; 203 }else{ 204 return b.durPer4k - a.durPer4k ; 205 } 206 }else if(key == "thread"){ 207 if (a.thread > b.thread) { 208 return type === 2 ? 1 : -1; 209 } else if (a.thread == b.thread) { 210 return 0; 211 } else { 212 return type === 2 ? -1 : 1; 213 } 214 }else { 215 return 0; 216 } 217 }) 218 this.tbl!.recycleDataSource = arr; 219 } 220 } 221 222 initHtml(): string { 223 return ` 224 <style> 225 :host{ 226 display: flex; 227 flex-direction: column; 228 padding: 10px 10px 0 10px; 229 } 230 .loading{ 231 bottom: 0; 232 position: absolute; 233 left: 0; 234 right: 0; 235 width:100%; 236 background:transparent; 237 z-index: 999999; 238 } 239 .progress{ 240 bottom: 33px; 241 position: absolute; 242 height: 1px; 243 z-index: 99; 244 left: 0; 245 right: 0; 246 } 247 tab-pane-filter { 248 border: solid rgb(216,216,216) 1px; 249 float: left; 250 position: fixed; 251 bottom: 0; 252 width: 100%; 253 } 254 </style> 255 <div style="display: flex;flex-direction: column"> 256 <div style="display: flex;flex-direction: row;"> 257 <lit-slicer style="width:100%"> 258 <div style="width: 65%"> 259 <lit-table id="tbl" style="height: auto"> 260 <lit-table-column width="200px" title="Start" data-index="startTsStr" key="startTsStr" align="flex-start" order></lit-table-column> 261 <lit-table-column width="260px" title="Total Latency" data-index="durStr" key="durStr" align="flex-start" order></lit-table-column> 262 <lit-table-column width="200px" title="Process" data-index="process" key="process" align="flex-start" order></lit-table-column> 263 <lit-table-column width="200px" title="Latency per 4KB" data-index="durPer4kStr" key="durPer4kStr" align="flex-start" order></lit-table-column> 264 <lit-table-column width="200px" title="Thread" data-index="thread" key="thread" align="flex-start" order></lit-table-column> 265 <lit-table-column width="200px" title="Operation" data-index="operation" key="operation" align="flex-start" ></lit-table-column> 266 <lit-table-column width="200px" title="Bytes" data-index="sizeStr" key="sizeStr" align="flex-start" ></lit-table-column> 267 <lit-table-column width="280px" title="Path" data-index="path" key="path" align="flex-start" ></lit-table-column> 268 <lit-table-column width="200px" title="Block number" data-index="blockNumber" key="blockNumber" align="flex-start" ></lit-table-column> 269 <lit-table-column width="240px" title="Tier" data-index="tier" key="tier" align="flex-start" ></lit-table-column> 270 <lit-table-column width="600px" title="Backtrace" data-index="backtrace" key="backtrace" align="flex-start" > 271 <template> 272 <div> 273 <span>{{backtrace[0]}}</span> 274 <span v-if="backtrace.length > 1">⬅</span> 275 <span v-if="backtrace.length > 1"style="color: #565656"> {{backtrace[1]}}</span> 276 </div> 277 </template> 278 </lit-table-column> 279 </lit-table> 280 </div> 281 <lit-slicer-track ></lit-slicer-track> 282 <lit-table id="tbr" no-head style="height: auto;border-left: 1px solid var(--dark-border1,#e2e2e2)"> 283 <lit-table-column width="60px" title="" data-index="type" key="type" align="flex-start" > 284 <template> 285 <div v-if=" type == -1 ">Thread:</div> 286 <img src="img/library.png" size="20" v-if=" type == 1 "> 287 <img src="img/function.png" size="20" v-if=" type == 0 "> 288 </template> 289 </lit-table-column> 290 <lit-table-column width="1fr" title="" data-index="symbol" key="symbol" align="flex-start"> 291 </lit-table-column> 292 </lit-table> 293 </lit-slicer> 294 </div> 295 <lit-progress-bar class="progress"></lit-progress-bar> 296 <tab-pane-filter id="filter"></tab-pane-filter> 297 <div class="loading"></div> 298 </div> 299`; 300 } 301} 302