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 { SpSchedulingAnalysis } from './SpSchedulingAnalysis';
19import { procedurePool } from '../../database/Procedure';
20import { info } from '../../../log/Log';
21import '../../../base-ui/progress-bar/LitProgressBar';
22import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar';
23import './TableNoData';
24import { TableNoData } from './TableNoData';
25
26@element('top20-thread-run-time')
27export class Top20ThreadRunTime extends BaseElement {
28  traceChange: boolean = false;
29  private threadRunTimeTbl: LitTable | null | undefined;
30  private threadRunTimeProgress: LitProgressBar | null | undefined;
31  private nodata: TableNoData | null | undefined;
32  private threadRunTimeData: Array<unknown> = [];
33
34  initElements(): void {
35    this.threadRunTimeProgress = this.shadowRoot!.querySelector<LitProgressBar>('#loading');
36    this.threadRunTimeTbl = this.shadowRoot!.querySelector<LitTable>('#tb-thread-run-time');
37    this.nodata = this.shadowRoot!.querySelector<TableNoData>('#nodata');
38
39    this.threadRunTimeTbl!.addEventListener('row-click', (evt: unknown): void => {
40      //@ts-ignore
41      let data = evt.detail.data;
42      data.isSelected = true;
43      // @ts-ignore
44      if ((evt.detail as unknown).callBack) {
45        // @ts-ignore
46        (evt.detail as unknown).callBack(true);
47      }
48    });
49
50    this.threadRunTimeTbl!.addEventListener('column-click', (evt): void => {
51      // @ts-ignore
52      this.sortByColumn(evt.detail);
53    });
54  }
55
56  init(): void {
57    if (!this.traceChange) {
58      if (this.threadRunTimeTbl!.recycleDataSource.length > 0) {
59        this.threadRunTimeTbl?.reMeauseHeight();
60      }
61      return;
62    }
63    this.threadRunTimeProgress!.loading = true;
64    this.traceChange = false;
65    this.queryLogicWorker('scheduling-Thread RunTime', 'query Thread Cpu Run Time Analysis Time:', (res): void => {
66      //@ts-ignore
67      this.nodata!.noData = res === undefined || res.length === 0;
68      //@ts-ignore
69      this.threadRunTimeTbl!.recycleDataSource = res;
70      this.threadRunTimeTbl?.reMeauseHeight();
71      this.threadRunTimeProgress!.loading = false;
72      //@ts-ignore
73      this.threadRunTimeData = res;
74    });
75  }
76
77  clearData(): void {
78    this.traceChange = true;
79    this.threadRunTimeTbl!.recycleDataSource = [];
80  }
81
82  queryLogicWorker(option: string, log: string, handler: (res: unknown) => void): void {
83    let threadRunTime = new Date().getTime();
84    procedurePool.submitWithName('logic0', option, { cpuMax: SpSchedulingAnalysis.cpuCount - 1 }, undefined, handler);
85    let durTime = new Date().getTime() - threadRunTime;
86    info(log, durTime);
87  }
88
89  sortByColumn(detail: unknown): void {
90    // @ts-ignore
91    function compare(threadRunTimeProperty, sort, type) {
92      return function (a: unknown, b: unknown) {
93        if (type === 'number') {
94          return sort === 2
95            ? // @ts-ignore
96              parseFloat(b[threadRunTimeProperty]) - parseFloat(a[threadRunTimeProperty])
97            : //@ts-ignore
98              parseFloat(a[threadRunTimeProperty]) - parseFloat(b[threadRunTimeProperty]);
99        } else {
100          if (sort === 2) {
101            //@ts-ignore
102            return b[threadRunTimeProperty].toString().localeCompare(a[threadRunTimeProperty].toString());
103          } else {
104            //@ts-ignore
105            return a[threadRunTimeProperty].toString().localeCompare(b[threadRunTimeProperty].toString());
106          }
107        }
108      };
109    }
110    //@ts-ignore
111    let key = detail.key;
112    if (key === 'maxDurationStr') {
113      key = 'maxDuration';
114      //@ts-ignore
115      this.threadRunTimeData.sort(compare(key, detail.sort, 'number'));
116    } else if (key === 'cpu' || key === 'no' || key === 'pid' || key === 'tid' || key === 'timestamp') {
117      //@ts-ignore
118      this.threadRunTimeData.sort(compare(key, detail.sort, 'number'));
119    } else {
120      //@ts-ignore
121      this.threadRunTimeData.sort(compare(key, detail.sort, 'string'));
122    }
123    this.threadRunTimeTbl!.recycleDataSource = this.threadRunTimeData;
124  }
125
126  initHtml(): string {
127    return `
128        <style>
129        :host {
130            width: 100%;
131            height: 100%;
132            background-color: var(--dark-background5,#F6F6F6);
133        }
134        .tb_run_time{
135            overflow: auto ;
136            border-radius: 5px;
137            border: solid 1px var(--dark-border1,#e0e0e0);
138            margin: 10px 10px 0 10px;
139            padding: 5px 15px
140        }
141        </style>
142        <lit-progress-bar id="loading" style="height: 1px;width: 100%" loading></lit-progress-bar>
143        <div style="height: 5px"></div>
144        <div class="tb_run_time" >
145            <table-no-data id="nodata" contentHeight="500px">
146                <lit-table id="tb-thread-run-time" style="height: auto;" hideDownload>
147                    <lit-table-column width="90px" title="NO" data-index="no" key="no" align="flex-start" order></lit-table-column>
148                    <lit-table-column width="140px" title="tid" data-index="tid" key="tid" align="flex-start" order></lit-table-column>
149                    <lit-table-column width="240px" title="t_name" data-index="tName" key="tName" align="flex-start" order></lit-table-column>
150                    <lit-table-column width="140px" title="pid" data-index="pid" key="pid" align="flex-start" order></lit-table-column>
151                    <lit-table-column width="240px" title="p_name" data-index="pName" key="pName" align="flex-start" order></lit-table-column>
152                    <lit-table-column width="140px" title="max duration" data-index="maxDurationStr" key="maxDurationStr" align="flex-start" order></lit-table-column>
153                    <lit-table-column width="200px" title="timestamp" data-index="timestamp" key="timestamp" align="flex-start" order>
154                        <template>
155                            <div onclick="{
156                                window.publish(window.SmartEvent.UI.SliceMark,this.parentElement.parentElement.data)
157                            }">{{timestamp}}</div>
158                        </template>
159                    </lit-table-column>
160                    <lit-table-column width="140px" title="cpu" data-index="cpu" key="cpu" align="flex-start" order></lit-table-column>
161                </lit-table>
162            </table-no-data>
163        </div>
164        <div style="height: 10px"></div>
165        `;
166  }
167}
168