• 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 { SelectionParam } from '../../../../bean/BoxSelection';
19import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar';
20import { resizeObserver } from '../SheetUtils';
21import { SpSystemTrace } from '../../../SpSystemTrace';
22import { drawLines } from '../../../../database/ui-worker/ProcedureWorkerCommon';
23import { TraceRow } from '../../base/TraceRow';
24import { CpuFreqStruct } from '../../../../database/ui-worker/ProcedureWorkerFreq';
25import { CpuStateStruct } from '../../../../database/ui-worker/cpu/ProcedureWorkerCpuState';
26import { getTabPaneCounterSampleData } from '../../../../database/sql/Cpu.sql';
27
28@element('tabpane-counter-sample')
29export class TabPaneCounterSample extends BaseElement {
30  private counterSampleTbl: LitTable | null | undefined;
31  private range: HTMLLabelElement | null | undefined;
32  private loadDataInCache: boolean = true;
33  private selectionParam: SelectionParam | null | undefined;
34  private sampleProgressEL: LitProgressBar | null | undefined;
35  private counterLoadingPage: unknown;
36  private counterLoadingList: number[] = [];
37  private counterSampleSource: unknown[] = [];
38  private counterSortKey: string = 'counter';
39  private counterSortType: number = 0;
40  private systemTrace: SpSystemTrace | undefined | null;
41  // @ts-ignore
42  private _rangeRow: Array<TraceRow<unknown>> | undefined | null;
43
44  set data(counterSampleValue: SelectionParam | unknown) {
45    if (counterSampleValue === this.selectionParam) {
46      return;
47    }
48    this.sampleProgressEL!.loading = true;
49    // @ts-ignore
50    this.counterLoadingPage.style.visibility = 'visible';
51    // @ts-ignore
52    this.selectionParam = counterSampleValue;
53    if (this.counterSampleTbl) {
54      // @ts-ignore
55      this.counterSampleTbl.shadowRoot.querySelector('.table').style.height = `${
56        this.parentElement!.clientHeight - 25
57      }px`;
58    }
59    this.queryDataByDB(counterSampleValue);
60  }
61  // @ts-ignore
62  set rangeTraceRow(rangeRow: Array<TraceRow<unknown>> | undefined) {
63    this._rangeRow = rangeRow;
64  }
65
66  initElements(): void {
67    this.sampleProgressEL = this.shadowRoot!.querySelector<LitProgressBar>('.progressCounter');
68    this.counterLoadingPage = this.shadowRoot!.querySelector('.loadingCounter');
69    this.counterSampleTbl = this.shadowRoot!.querySelector<LitTable>('#tb-counter-sample');
70    this.systemTrace = document
71      .querySelector('body > sp-application')
72      ?.shadowRoot!.querySelector<SpSystemTrace>('#sp-system-trace');
73    this.counterSampleTbl!.addEventListener('column-click', (evt): void => {
74      // @ts-ignore
75      this.counterSortKey = evt.detail.key;
76      // @ts-ignore
77      this.counterSortType = evt.detail.sort;
78      // @ts-ignore
79      this.sortTable(evt.detail.key, evt.detail.sort);
80    });
81    this.rowClickEvent();
82  }
83
84  private rowClickEvent(): void {
85    this.counterSampleTbl!.addEventListener('row-click', (evt): void => {
86      // @ts-ignore
87      let data = evt.detail.data;
88      let path = new Path2D();
89      if (this._rangeRow && this._rangeRow!.length > 0) {
90        let rangeTraceRow = this._rangeRow!.filter(function (item) {
91          return item.name.includes('State');
92        });
93        let cpuStateFilter = [];
94        for (let row of rangeTraceRow!) {
95          let context = row.collect ? this.systemTrace!.canvasFavoritePanelCtx! : this.systemTrace!.canvasPanelCtx!;
96          cpuStateFilter.push(...row.dataListCache);
97          row.canvasSave(context); // @ts-ignore
98          context.clearRect(row.frame.x, row.frame.y, row.frame.width, row.frame.height); // @ts-ignore
99          drawLines(context!, TraceRow.range?.xs || [], row.frame.height, this.systemTrace!.timerShaftEL!.lineColor());
100          if (row.name.includes('State') && parseInt(row.name.replace(/[^\d]/g, ' ')) === data.cpu) {
101            CpuFreqStruct.hoverCpuFreqStruct = undefined;
102            for (let i = 0; i < cpuStateFilter!.length; i++) {
103              if (
104                // @ts-ignore
105                cpuStateFilter[i].value === data.value &&
106                // @ts-ignore
107                cpuStateFilter[i].cpu === data.cpu &&
108                // @ts-ignore
109                Math.max(TraceRow.rangeSelectObject?.startNS!, cpuStateFilter[i].startTs!) <
110                  // @ts-ignore
111                  Math.min(TraceRow.rangeSelectObject?.endNS!, cpuStateFilter[i].startTs! + cpuStateFilter[i].dur!)
112              ) {
113                // @ts-ignore
114                CpuStateStruct.hoverStateStruct = cpuStateFilter[i];
115              }
116              // @ts-ignore
117              if (cpuStateFilter[i].cpu === data.cpu) {
118                // @ts-ignore
119                CpuStateStruct.draw(context, path, cpuStateFilter[i]);
120              }
121            }
122          } else {
123            for (let i = 0; i < cpuStateFilter!.length; i++) {
124              if (
125                row.name.includes('State') &&
126                // @ts-ignore
127                cpuStateFilter[i].cpu !== data.cpu &&
128                // @ts-ignore
129                cpuStateFilter[i].cpu === parseInt(row.name.replace(/[^\d]/g, ' '))
130              ) {
131                // @ts-ignore
132                CpuStateStruct.draw(context, path, cpuStateFilter[i]);
133              }
134            }
135          }
136          row.canvasRestore(context, this.systemTrace);
137        }
138      }
139    });
140  }
141
142  connectedCallback(): void {
143    super.connectedCallback();
144    // @ts-ignore
145    resizeObserver(this.parentElement!, this.counterSampleTbl!, 25, this.counterLoadingPage, 24);
146  }
147
148  queryDataByDB(counterSampleParam: SelectionParam | unknown): void {
149    this.counterLoadingList.push(1);
150    this.sampleProgressEL!.loading = true;
151    // @ts-ignore
152    this.counterLoadingPage.style.visibility = 'visible';
153
154    getTabPaneCounterSampleData(
155      // @ts-ignore
156      counterSampleParam.leftNs + counterSampleParam.recordStartNs,
157      // @ts-ignore
158      counterSampleParam.rightNs + counterSampleParam.recordStartNs,
159      // @ts-ignore
160      counterSampleParam.cpuStateFilterIds
161    ).then((result) => {
162      this.counterLoadingList.splice(0, 1);
163      if (this.counterLoadingList.length === 0) {
164        this.sampleProgressEL!.loading = false;
165        // @ts-ignore
166        this.counterLoadingPage.style.visibility = 'hidden';
167      }
168      let sampleMap = new Map<unknown, unknown>();
169      // @ts-ignore
170      counterSampleParam.cpuStateFilterIds.forEach((a: number): void => {
171        this.getInitTime(
172          //@ts-ignore
173          result.filter((f) => f.filterId === a),
174          sampleMap,
175          // @ts-ignore
176          counterSampleParam
177        );
178      });
179      // @ts-ignore
180      let counterSampleList: Array<unknown> = [];
181      sampleMap.forEach((a) => {
182        // @ts-ignore
183        a.timeStr = parseFloat((a.time / 1000000.0).toFixed(6));
184        counterSampleList.push(a);
185      });
186      this.counterSampleSource = counterSampleList;
187      this.sortTable(this.counterSortKey, this.counterSortType);
188    });
189  }
190  // @ts-ignore
191  getInitTime(initCounterResultList: Array<unknown>, sampleMap: Map<unknown, unknown>, val: SelectionParam): void {
192    let leftNs = val.leftNs + val.recordStartNs;
193    let rightNs = val.rightNs + val.recordStartNs;
194    if (initCounterResultList.length === 0) {
195      return;
196    }
197    // @ts-ignore
198    let idx = initCounterResultList.findIndex((a) => a.ts >= leftNs);
199    if (idx !== 0) {
200      initCounterResultList = initCounterResultList.slice(
201        idx === -1 ? initCounterResultList.length - 1 : idx - 1,
202        initCounterResultList.length
203      );
204    }
205    // @ts-ignore
206    if (initCounterResultList[0].ts < leftNs && idx !== 0) {
207      // @ts-ignore
208      initCounterResultList[0].ts = leftNs;
209    }
210    initCounterResultList.forEach((item, idx): void => {
211      if (idx + 1 === initCounterResultList.length) {
212        // @ts-ignore
213        item.time = rightNs - item.ts;
214      } else {
215        // @ts-ignore
216        item.time = initCounterResultList[idx + 1].ts - item.ts;
217      }
218      // @ts-ignore
219      if (sampleMap.has(`${item.filterId}-${item.value}`)) {
220        // @ts-ignore
221        let obj = sampleMap.get(`${item.filterId}-${item.value}`);
222        // @ts-ignore
223        obj.time += item.time;
224      } else {
225        // @ts-ignore
226        sampleMap.set(`${item.filterId}-${item.value}`, {
227          // @ts-ignore
228          ...item,
229          // @ts-ignore
230          counter: `Cpu ${item.cpu}`,
231          // @ts-ignore
232          count: initCounterResultList.filter((ele) => ele.value === item.value).length,
233        });
234      }
235    });
236  }
237
238  sortTable(key: string, type: number): void {
239    if (type === 0) {
240      this.counterSampleTbl!.recycleDataSource = this.counterSampleSource;
241    } else {
242      let arr = Array.from(this.counterSampleSource);
243      arr.sort((sortByColumnLeftData, sortByColumnRightData): number => {
244        if (key === 'timeStr') {
245          if (type === 1) {
246            // @ts-ignore
247            return sortByColumnLeftData.time - sortByColumnRightData.time;
248          } else {
249            // @ts-ignore
250            return sortByColumnRightData.time - sortByColumnLeftData.time;
251          }
252        } else if (key === 'counter') {
253          // @ts-ignore
254          if (sortByColumnLeftData.counter > sortByColumnRightData.counter) {
255            return type === 2 ? -1 : 1;
256            // @ts-ignore
257          } else if (sortByColumnLeftData.counter === sortByColumnRightData.counter) {
258            return 0;
259          } else {
260            return type === 2 ? 1 : -1;
261          }
262        } else if (key === 'value') {
263          if (type === 1) {
264            // @ts-ignore
265            return sortByColumnLeftData.value - sortByColumnRightData.value;
266          } else {
267            // @ts-ignore
268            return sortByColumnRightData.value - sortByColumnLeftData.value;
269          }
270        } else {
271          return 0;
272        }
273      });
274      this.counterSampleTbl!.recycleDataSource = arr;
275    }
276  }
277
278  initHtml(): string {
279    return `
280        <style>
281        .progressCounter{
282            height: 1px;
283            left: 0;
284            right: 0;
285            bottom: 5px;
286            position: absolute;
287        }
288        :host{
289            display: flex;
290            padding: 10px 10px;
291            flex-direction: column;
292        }
293        .loadingCounter{
294            left: 0;
295            right: 0;
296            width:100%;
297            bottom: 0;
298            position: absolute;
299            background:transparent;
300            z-index: 999999;
301        }
302        .counter-sample-table{
303            height: auto;
304        }
305        </style>
306        <lit-table id="tb-counter-sample" class="counter-sample-table">
307            <lit-table-column class="counter-sample-column" width="20%" order data-index="counter" key="counter" align="flex-start" title="Cpu" >
308            </lit-table-column>
309            <lit-table-column class="counter-sample-column" width="1fr" order data-index="timeStr" key="timeStr" align="flex-start" title="Time(ms)" >
310            </lit-table-column>
311            <lit-table-column class="counter-sample-column" width="1fr" order data-index="value" key="value" align="flex-start" title="Value" >
312            </lit-table-column>
313            <lit-table-column class="counter-sample-column" width="1fr" order data-index="count" key="count" align="flex-start" title="Count" >
314            </lit-table-column>
315        </lit-table>
316        <lit-progress-bar class="progressCounter"></lit-progress-bar>
317        <div class="loadingCounter"></div>
318        `;
319  }
320}
321