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 { log } from '../../../../../log/Log'; 20import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon'; 21import { resizeObserver } from '../SheetUtils'; 22import { SoStruct } from '../../../../database/ui-worker/ProcedureWorkerSoInit'; 23import { getTabStaticInit } from '../../../../database/sql/ProcessThread.sql'; 24 25interface SoTreeItem { 26 name: string; 27 dur: number; 28 durStr: string; 29 ratio: string; 30 children: SoTreeItem[] | undefined; 31} 32 33@element('tabpane-static-init') 34export class TabPaneStaticInit extends BaseElement { 35 private staticinitTbl: LitTable | null | undefined; 36 private range: HTMLLabelElement | null | undefined; 37 private staticinitSource: Array<SoTreeItem> = []; 38 private currentSelectionParam: SelectionParam | undefined; 39 40 set data(staticinitParam: SelectionParam | unknown) { 41 this.initStaticTblStyle(staticinitParam); // @ts-ignore 42 getTabStaticInit(staticinitParam.processIds, staticinitParam.leftNs, staticinitParam.rightNs).then( 43 //@ts-ignore 44 (result: SoStruct[]) => { 45 this.staticinitTbl!.loading = false; 46 if (result !== null && result.length > 0) { 47 log(`getTabStaticInit result size : ${result.length}`); 48 let map: Map<number, SoTreeItem> = new Map<number, SoTreeItem>(); 49 result.forEach((item) => { 50 let so: SoTreeItem = { 51 name: (item.soName || '[NULL]').replace('dlopen: ', ''), 52 dur: item.dur || 0, 53 durStr: getProbablyTime(item.dur || 0), 54 ratio: '0%', 55 children: [], 56 }; 57 if (map.has(item.pid!)) { 58 let ps = map.get(item.pid!); 59 if (ps && ps.children) { 60 ps.dur += item.dur || 0; 61 ps.children!.push(so); 62 } 63 } else { 64 map.set(item.pid!, { 65 name: item.process || `Process ${item.pid}`, 66 dur: item.dur || 0, 67 durStr: '', 68 ratio: '100%', 69 children: [so], 70 }); 71 } 72 }); 73 let soArr = Array.from(map.values()); 74 soArr.forEach((it) => { 75 it.durStr = getProbablyTime(it.dur); 76 it.children!.forEach((child) => { 77 child.ratio = `${((child.dur * 100) / it.dur).toFixed(2)}%`; 78 }); 79 }); 80 this.staticinitSource = soArr; 81 this.staticinitTbl!.recycleDataSource = this.staticinitSource; 82 } else { 83 this.staticinitSource = []; 84 this.staticinitTbl!.recycleDataSource = []; 85 } 86 } 87 ); 88 } 89 90 private initStaticTblStyle(staticParam: SelectionParam | unknown): void { 91 if (this.currentSelectionParam === staticParam) { 92 return; 93 } // @ts-ignore 94 this.currentSelectionParam = staticParam; 95 //@ts-ignore 96 this.staticinitTbl?.shadowRoot?.querySelector('.table')?.style?.height = `${ 97 this.parentElement!.clientHeight - 45 98 }px`; // @ts-ignore 99 this.range!.textContent = `Selected range: ${((staticParam.rightNs - staticParam.leftNs) / 1000000.0).toFixed( 100 5 101 )} ms`; 102 this.staticinitTbl!.loading = true; 103 } 104 105 initElements(): void { 106 this.staticinitTbl = this.shadowRoot?.querySelector<LitTable>('#tb-staticinit'); 107 this.range = this.shadowRoot?.querySelector('#staticinit-time-range'); 108 this.staticinitTbl!.addEventListener('column-click', (evt: unknown) => { 109 // @ts-ignore 110 this.sortByColumn(evt.detail); 111 }); 112 } 113 114 connectedCallback(): void { 115 super.connectedCallback(); 116 resizeObserver(this.parentElement!, this.staticinitTbl!); 117 } 118 119 initHtml(): string { 120 return ` 121 <style> 122 .staticinit-table{ 123 flex-direction: row; 124 margin-bottom: 5px; 125 } 126 :host{ 127 display: flex; 128 flex-direction: column; 129 padding: 10px 10px; 130 } 131 </style> 132 <div class="staticinit-table" style="display: flex;height: 20px;align-items: center; 133 flex-direction: row;margin-bottom: 5px"> 134 <div style="flex: 1"></div> 135 <label id="staticinit-time-range" style="width: auto;text-align: end;font-size: 10pt;"> 136 Selected range:0.0 ms</label> 137 </div> 138 <div style="overflow: auto"> 139 <lit-table id="tb-staticinit" style="height: auto" tree> 140 <lit-table-column width="700px" title="Process / Lib" data-index="name" 141 key="name" align="flex-start" retract order> 142 </lit-table-column> 143 <lit-table-column width="200px" title="Duration" data-index="durStr" 144 key="durStr" align="flex-start" order > 145 </lit-table-column> 146 </lit-table> 147 </div> 148 `; 149 } 150 151 sortByColumn(soDetail: { sort: number; dur: number }): void { 152 let compare = (soA: SoTreeItem, soB: SoTreeItem): number => 153 soDetail.sort === 1 ? soA.dur - soB.dur : soB.dur - soA.dur; 154 this.staticinitSource.forEach((it) => it.children?.sort(compare)); 155 this.staticinitSource.sort(compare); 156 this.staticinitTbl!.recycleDataSource = this.staticinitSource; 157 } 158} 159