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 { 20 getTabPaneFilesystemStatistics, 21} from "../../../../database/SqlLite.js"; 22import {Utils} from "../../base/Utils.js"; 23import {LitProgressBar} from "../../../../../base-ui/progress-bar/LitProgressBar.js"; 24 25@element('tabpane-file-statistics') 26export class TabPaneFileStatistics extends BaseElement { 27 private tbl: LitTable | null | undefined; 28 private range: HTMLLabelElement | null | undefined; 29 private loadDataInCache: boolean = true; 30 private selectionParam:SelectionParam | null | undefined; 31 private progressEL:LitProgressBar | null | undefined; 32 private loadingPage:any; 33 private loadingList:number[] = []; 34 private source: Array<any> = []; 35 private typeList: Array<string> = ["OPEN", "CLOSE", "READ" , "WRITE"]; 36 private sortKey: string = ""; 37 private sortType: number = 0; 38 39 set data(val: SelectionParam | any) { 40 if(val == this.selectionParam){ 41 return; 42 } 43 this.progressEL!.loading = true 44 this.loadingPage.style.visibility = "visible" 45 this.selectionParam = val; 46 // @ts-ignore 47 this.tbl!.shadowRoot!.querySelector(".table").style.height = (this.parentElement!.clientHeight - 25) + "px" 48 this.queryDataByDB(val) 49 } 50 51 initElements(): void { 52 this.progressEL = this.shadowRoot!.querySelector<LitProgressBar>('.progress') 53 this.loadingPage = this.shadowRoot!.querySelector('.loading'); 54 this.tbl = this.shadowRoot!.querySelector<LitTable>('#tb-states'); 55 this.tbl!.addEventListener('column-click', (evt) => { 56 // @ts-ignore 57 this.sortKey = evt.detail.key 58 // @ts-ignore 59 this.sortType = evt.detail.sort; 60 61 let newSource = JSON.parse(JSON.stringify(this.source)); 62 if (this.sortType != 0 && newSource.length > 0) this.sortTable(newSource[0],this.sortKey); 63 this.tbl!.recycleDataSource = newSource; 64 }) 65 } 66 67 connectedCallback() { 68 super.connectedCallback(); 69 new ResizeObserver((entries) => { 70 if (this.parentElement!.clientHeight != 0) { 71 // @ts-ignore 72 this.tbl!.shadowRoot!.querySelector(".table").style.height = (this.parentElement!.clientHeight - 25) + "px" 73 this.tbl!.reMeauseHeight() 74 this.loadingPage.style.height = (this.parentElement!.clientHeight - 24) + "px" 75 } 76 }).observe(this.parentElement!); 77 } 78 79 getInitData(item:any){ 80 return { 81 ...item, 82 title : item.name+"("+item.pid+")", 83 logicalWrites : Utils.getBinaryByteWithUnit(item.logicalWrites), 84 logicalReads : Utils.getBinaryByteWithUnit(item.logicalReads), 85 otherFile : Utils.getBinaryByteWithUnit(item.otherFile), 86 allDuration : Utils.getProbablyTime(item.allDuration), 87 minDuration : Utils.getProbablyTime(item.minDuration), 88 maxDuration : Utils.getProbablyTime(item.maxDuration), 89 avgDuration : Utils.getProbablyTime(item.avgDuration), 90 node:{...item,children:[]}, 91 } 92 } 93 94 queryDataByDB(val: SelectionParam | any) { 95 this.loadingList.push(1) 96 this.progressEL!.loading = true 97 this.loadingPage.style.visibility = "visible"; 98 getTabPaneFilesystemStatistics(val.leftNs + val.recordStartNs,val.rightNs + val.recordStartNs).then(result => { 99 this.loadingList.splice(0,1) 100 if(this.loadingList.length == 0) { 101 this.progressEL!.loading = false 102 this.loadingPage.style.visibility = "hidden" 103 } 104 let fatherMap = new Map<any,any>() 105 let allNode:any = { 106 title:"All", 107 count:0, 108 logicalReads:0, 109 logicalWrites:0, 110 otherFile:0, 111 allDuration:0, 112 minDuration:0, 113 maxDuration:0, 114 avgDuration:"", 115 children:[], 116 }; 117 result.forEach((item,idx)=>{ 118 if (fatherMap.has(item.type)) { 119 let obj1 = fatherMap.get(item.type); 120 obj1.count += item.count; 121 obj1.logicalReads += item.logicalReads; 122 obj1.logicalWrites += item.logicalWrites; 123 obj1.otherFile += item.otherFile; 124 obj1.allDuration += item.allDuration; 125 obj1.minDuration = obj1.minDuration<=item.minDuration?obj1.minDuration:item.minDuration; 126 obj1.maxDuration = obj1.maxDuration>=item.maxDuration?obj1.maxDuration:item.maxDuration; 127 obj1.children.push(this.getInitData(item)); 128 }else { 129 fatherMap.set(item.type,{ 130 type:item.type, 131 count:item.count, 132 logicalReads:item.logicalReads, 133 logicalWrites:item.logicalWrites, 134 otherFile:item.otherFile, 135 allDuration:item.allDuration, 136 minDuration:item.minDuration, 137 maxDuration:item.maxDuration, 138 children:[this.getInitData(item)] 139 }) 140 } 141 if (idx == 0) { 142 allNode.minDuration = item.minDuration; 143 }else { 144 allNode.minDuration = allNode.minDuration<=item.minDuration?allNode.minDuration:item.minDuration; 145 } 146 allNode.count += item.count; 147 allNode.logicalReads += item.logicalReads; 148 allNode.logicalWrites += item.logicalWrites; 149 allNode.otherFile += item.otherFile; 150 allNode.allDuration += item.allDuration; 151 allNode.maxDuration = allNode.maxDuration>=item.maxDuration?allNode.maxDuration:item.maxDuration; 152 }) 153 fatherMap.forEach((item)=>{ 154 item.avgDuration = item.allDuration/item.count; 155 let node = this.getInitData(item); 156 if (item.type < 4) { 157 node.title = this.typeList[item.type] 158 }else { 159 node.title = item.type; 160 } 161 allNode.children.push(node) 162 }) 163 allNode.avgDuration = allNode.allDuration/allNode.count; 164 allNode = this.getInitData(allNode); 165 allNode.title = "All"; 166 this.source = result.length > 0 ? [allNode] : []; 167 let newSource = JSON.parse(JSON.stringify(this.source)); 168 if (this.sortType != 0 && result.length > 0) this.sortTable(newSource[0],this.sortKey); 169 this.tbl!.recycleDataSource = newSource; 170 }) 171 } 172 173 sortTable(allNode:any,key:string){ 174 allNode.children.sort((a:any, b:any) => { 175 if (this.sortType == 1) { 176 return a.node[key] - b.node[key] 177 }else if (this.sortType == 2) { 178 return b.node[key] - a.node[key] 179 } 180 }); 181 allNode.children.forEach((item:any)=>{ 182 item.children.sort((a:any, b:any) => { 183 if (this.sortType == 1) { 184 return a.node[key] - b.node[key] 185 }else if (this.sortType == 2) { 186 return b.node[key] - a.node[key] 187 } 188 }) 189 }); 190 } 191 192 initHtml(): string { 193 return ` 194 <style> 195 :host{ 196 display: flex; 197 flex-direction: column; 198 padding: 10px 10px; 199 } 200 .progress{ 201 bottom: 5px; 202 position: absolute; 203 height: 1px; 204 left: 0; 205 right: 0; 206 } 207 .loading{ 208 bottom: 0; 209 position: absolute; 210 left: 0; 211 right: 0; 212 width:100%; 213 background:transparent; 214 z-index: 999999; 215 } 216 </style> 217 <lit-table id="tb-states" style="height: auto" tree> 218 <lit-table-column width="20%" title="Syscall/Process" data-index="title" key="title" align="flex-start"> 219 </lit-table-column> 220 <lit-table-column width="1fr" title="Count" data-index="count" key="count" align="flex-start" order> 221 </lit-table-column> 222 <lit-table-column width="1fr" title="Logical Writes" data-index="logicalWrites" key="logicalWrites" align="flex-start" order> 223 </lit-table-column> 224 <lit-table-column width="1fr" title="Logical Reads" data-index="logicalReads" key="logicalReads" align="flex-start" order> 225 </lit-table-column> 226 <lit-table-column width="1fr" title="Other Filesystem Bytes" data-index="otherFile" key="otherFile" align="flex-start" order> 227 </lit-table-column> 228 <lit-table-column width="1fr" title="Duration" data-index="allDuration" key="allDuration" align="flex-start" order> 229 </lit-table-column> 230 <lit-table-column width="1fr" title="Min Duration" data-index="minDuration" key="minDuration" align="flex-start" order> 231 </lit-table-column> 232 <lit-table-column width="1fr" title="Avg Duration" data-index="avgDuration" key="avgDuration" align="flex-start" order> 233 </lit-table-column> 234 <lit-table-column width="1fr" title="Max Duration" data-index="maxDuration" key="maxDuration" align="flex-start" order> 235 </lit-table-column> 236 </lit-table> 237 <lit-progress-bar class="progress"></lit-progress-bar> 238 <div class="loading"></div> 239 `; 240 } 241} 242