• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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