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 { SysCallBoxJumpParam, SelectionData } from '../../../../bean/BoxSelection'; 19import { Utils } from '../../base/Utils'; 20import { resizeObserver } from '../SheetUtils'; 21import { querySysCallEventWithRange } from '../../../../database/sql/ProcessThread.sql'; 22import { SysCallMap } from '../../base/SysCallUtils'; 23 24interface SysCallChildItem { 25 pName: string; 26 tName: string; 27 pid: number; 28 tid: number; 29 nameId: number; 30 name: string; 31 startTs: string; 32 startTime: number; 33 absoluteTs: number; 34 dur: number; 35 args: string; 36 ret: number 37} 38 39@element('tabpane-syscall-child') 40export class TabPaneSysCallChild extends BaseElement { 41 private boxChildTbl: LitTable | null | undefined; 42 private boxChildRange: HTMLLabelElement | null | undefined; 43 private boxChildSource: Array<SysCallChildItem> = []; 44 private boxChildParam: SysCallBoxJumpParam | null | undefined; 45 46 set data(boxChildValue: SysCallBoxJumpParam) { 47 //切换Tab页 保持childTab数据不变 除非重新点击跳转 48 if (boxChildValue === this.boxChildParam || !boxChildValue.isJumpPage) { 49 return; 50 } // @ts-ignore 51 this.boxChildParam = boxChildValue; 52 //显示框选范围对应的时间 53 this.boxChildRange!.textContent = `Selected range: ${parseFloat( 54 ((boxChildValue.rightNs - boxChildValue.leftNs) / 1000000.0).toFixed(5) 55 )} ms`; 56 this.boxChildTbl!.recycleDataSource = []; 57 this.getDataByDB(boxChildValue); 58 } 59 60 initElements(): void { 61 this.boxChildTbl = this.shadowRoot?.querySelector<LitTable>('#tb-syscall-child'); 62 this.boxChildRange = this.shadowRoot?.querySelector('#time-range'); 63 this.boxChildTbl!.addEventListener('column-click', (evt): void => { 64 // @ts-ignore 65 this.sortByColumn(evt.detail); 66 }); 67 //监听row的点击事件,在对应起始时间上画标记棋子 68 this.boxChildTbl!.addEventListener('row-click', (evt): void => { 69 //@ts-ignore 70 let param = evt.detail.data; 71 param.isSelected = true; 72 this.boxChildTbl!.clearAllSelection(param); 73 this.boxChildTbl!.setCurrentSelection(param); 74 document.dispatchEvent( 75 new CustomEvent('triangle-flag', { 76 detail: { time: [param.startTime], type: 'triangle' }, 77 }) 78 ); 79 }); 80 } 81 82 connectedCallback(): void { 83 super.connectedCallback(); 84 resizeObserver(this.parentElement!, this.boxChildTbl!); 85 } 86 87 getDataByDB(val: SysCallBoxJumpParam): void { 88 this.boxChildTbl!.loading = true; 89 let ipidArr: number[] = []; 90 let itidArr: number[] = []; 91 Array.from(Utils.getInstance().sysCallEventTidsMap.values()).forEach(it => { 92 if (val?.processId?.includes(it.pid)) { 93 ipidArr.push(it.ipid); 94 } 95 if (val?.threadId?.includes(it.tid)) { 96 itidArr.push(it.itid); 97 } 98 }); 99 querySysCallEventWithRange(ipidArr, itidArr, val.leftNs, val.rightNs, val.sysCallId).then(result => { 100 this.boxChildTbl!.loading = false; 101 const arr: Array<SysCallChildItem> = []; 102 result.forEach(it => { 103 arr.push({ 104 pName: it.pName, 105 tName: it.tName, 106 pid: it.pid, 107 tid: it.tid, 108 name: SysCallMap.get(it.nameId) || 'unknown event', 109 nameId: it.nameId, 110 startTime: it.startTs, 111 startTs: Utils.getProbablyTime(it.startTs), 112 // @ts-ignore 113 absoluteTs: ((window as unknown).recordStartNS + it.startTs) / 1000000000, 114 dur: it.dur / 1000000, 115 args: it.args, 116 ret: it.ret 117 }); 118 }); 119 this.boxChildSource = arr; 120 if (this.boxChildTbl) { 121 // @ts-ignore 122 this.boxChildTbl.recycleDataSource = arr; 123 } 124 }); 125 } 126 127 initHtml(): string { 128 return ` 129 <style> 130 .box-child-label{ 131 text-align: end; 132 width: 100%; 133 height: 20px; 134 } 135 :host{ 136 padding: 10px 10px; 137 display: flex; 138 flex-direction: column; 139 } 140 </style> 141 <label id="time-range" class="box-child-label" style="font-size: 10pt;margin-bottom: 5px">Selected range:0.0 ms</label> 142 <div style="overflow: auto"> 143 <lit-table id="tb-syscall-child" style="height: auto"> 144 <lit-table-column order width="150px" data-index="name" key="name" align="flex-start" title="Event Name"> 145 </lit-table-column> 146 <lit-table-column order title="StartTime(Relative)" width="150px" data-index="startTs" key="startTs" align="flex-start" > 147 </lit-table-column> 148 <lit-table-column order title="StartTime(Absolute)" width="150px" data-index="absoluteTs" key="absoluteTs" align="flex-start" > 149 </lit-table-column> 150 <lit-table-column order width="150px" data-index="pName" key="pName" title="Process" align="flex-start" > 151 </lit-table-column> 152 <lit-table-column order width="150px" data-index="tName" key="tName" align="flex-start" title="Thread"> 153 </lit-table-column> 154 <lit-table-column order width="80px" data-index="dur" key="dur" title="duration(ms)" align="flex-start" > 155 </lit-table-column> 156 <lit-table-column order width="200px" data-index="args" key="args" align="flex-start" title="args"> 157 </lit-table-column> 158 <lit-table-column order width="80px" data-index="ret" title="ret" key="ret" align="flex-start" > 159 </lit-table-column> 160 </lit-table> 161 </div> 162 `; 163 } 164 165 sortByColumn(detail: unknown): void { 166 // @ts-ignore 167 function compare(property, sort, type) { 168 return function (boxChildLeftData: SelectionData, boxChildRightData: SelectionData): number { 169 if (type === 'number') { 170 return sort === 2 171 // @ts-ignore 172 ? parseFloat(boxChildRightData[property]) - parseFloat(boxChildLeftData[property]) 173 // @ts-ignore 174 : parseFloat(boxChildLeftData[property]) - parseFloat(boxChildRightData[property]); 175 } else { 176 // @ts-ignore 177 if (boxChildRightData[property] > boxChildLeftData[property]) { 178 return sort === 2 ? 1 : -1; 179 } else { 180 // @ts-ignore 181 if (boxChildRightData[property] === boxChildLeftData[property]) { 182 return 0; 183 } else { 184 return sort === 2 ? -1 : 1; 185 } 186 } 187 } 188 }; 189 } 190 191 // @ts-ignore 192 this.boxChildSource.sort(compare(detail.key, detail.sort, 'string')); 193 this.boxChildTbl!.recycleDataSource = this.boxChildSource; 194 } 195} 196