1fb726d48Sopenharmony_ci/*
2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb726d48Sopenharmony_ci * You may obtain a copy of the License at
6fb726d48Sopenharmony_ci *
7fb726d48Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb726d48Sopenharmony_ci *
9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and
13fb726d48Sopenharmony_ci * limitations under the License.
14fb726d48Sopenharmony_ci */
15fb726d48Sopenharmony_ci
16fb726d48Sopenharmony_ciimport { BaseElement, element } from '../../../base-ui/BaseElement';
17fb726d48Sopenharmony_ciimport { LitTable } from '../../../base-ui/table/lit-table';
18fb726d48Sopenharmony_ciimport { procedurePool } from '../../database/Procedure';
19fb726d48Sopenharmony_ciimport { info } from '../../../log/Log';
20fb726d48Sopenharmony_ciimport '../../../base-ui/chart/pie/LitChartPie';
21fb726d48Sopenharmony_ciimport { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie';
22fb726d48Sopenharmony_ciimport { LitSelect } from '../../../base-ui/select/LitSelect';
23fb726d48Sopenharmony_ciimport { LitSelectOption } from '../../../base-ui/select/LitSelectOption';
24fb726d48Sopenharmony_ciimport '../../../base-ui/progress-bar/LitProgressBar';
25fb726d48Sopenharmony_ciimport { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar';
26fb726d48Sopenharmony_ciimport './TableNoData';
27fb726d48Sopenharmony_ciimport { TableNoData } from './TableNoData';
28fb726d48Sopenharmony_ciimport { getProbablyTime } from '../../database/logic-worker/ProcedureLogicWorkerCommon';
29fb726d48Sopenharmony_ciimport { queryThreads } from '../../database/sql/ProcessThread.sql';
30fb726d48Sopenharmony_ciimport { Top20FrequencyThreadHtml } from './Top20FrequencyThread.html';
31fb726d48Sopenharmony_ci
32fb726d48Sopenharmony_ci@element('top20-frequency-thread')
33fb726d48Sopenharmony_ciexport class Top20FrequencyThread extends BaseElement {
34fb726d48Sopenharmony_ci  static threads: { id: number; tid: number; name: string }[] | undefined;
35fb726d48Sopenharmony_ci  traceChange: boolean = false;
36fb726d48Sopenharmony_ci  private frequencyThreadTbl: LitTable | null | undefined;
37fb726d48Sopenharmony_ci  private threadSelect: LitSelect | null | undefined;
38fb726d48Sopenharmony_ci  private frequencyThreadPie: LitChartPie | null | undefined;
39fb726d48Sopenharmony_ci  private currentThread: HTMLDivElement | null | undefined;
40fb726d48Sopenharmony_ci  private frequencyThreadProgress: LitProgressBar | null | undefined;
41fb726d48Sopenharmony_ci  private nodata: TableNoData | null | undefined;
42fb726d48Sopenharmony_ci  private currentTid: number = 0;
43fb726d48Sopenharmony_ci  private frequencyThreadData: Array<unknown> = [];
44fb726d48Sopenharmony_ci  private sortColumn: string = '';
45fb726d48Sopenharmony_ci  private sortType: number = 0;
46fb726d48Sopenharmony_ci
47fb726d48Sopenharmony_ci  initElements(): void {
48fb726d48Sopenharmony_ci    this.nodata = this.shadowRoot!.querySelector<TableNoData>('#nodata');
49fb726d48Sopenharmony_ci    this.frequencyThreadProgress = this.shadowRoot!.querySelector<LitProgressBar>('#loading');
50fb726d48Sopenharmony_ci    this.frequencyThreadTbl = this.shadowRoot!.querySelector<LitTable>('#tb-process-thread-count');
51fb726d48Sopenharmony_ci    this.currentThread = this.shadowRoot!.querySelector<HTMLDivElement>('#current_thread');
52fb726d48Sopenharmony_ci    this.threadSelect = this.shadowRoot!.querySelector<LitSelect>('#thread_select');
53fb726d48Sopenharmony_ci    this.frequencyThreadPie = this.shadowRoot!.querySelector<LitChartPie>('#pie');
54fb726d48Sopenharmony_ci
55fb726d48Sopenharmony_ci    this.threadSelect!.onchange = (e): void => {
56fb726d48Sopenharmony_ci      //@ts-ignore
57fb726d48Sopenharmony_ci      this.currentThread!.textContent = (e as unknown).detail.text;
58fb726d48Sopenharmony_ci      //@ts-ignore
59fb726d48Sopenharmony_ci      this.currentTid = parseInt(e.detail.selectValue);
60fb726d48Sopenharmony_ci      this.frequencyThreadProgress!.loading = true;
61fb726d48Sopenharmony_ci      this.queryData();
62fb726d48Sopenharmony_ci    };
63fb726d48Sopenharmony_ci
64fb726d48Sopenharmony_ci    this.frequencyThreadTbl!.addEventListener('row-click', (evt: unknown): void => {
65fb726d48Sopenharmony_ci      //@ts-ignore
66fb726d48Sopenharmony_ci      let data = evt.detail.data;
67fb726d48Sopenharmony_ci      data.isSelected = true; //@ts-ignore
68fb726d48Sopenharmony_ci      if ((evt.detail as unknown).callBack) {
69fb726d48Sopenharmony_ci        //@ts-ignore
70fb726d48Sopenharmony_ci        (evt.detail as unknown).callBack(true);
71fb726d48Sopenharmony_ci      }
72fb726d48Sopenharmony_ci    });
73fb726d48Sopenharmony_ci
74fb726d48Sopenharmony_ci    this.frequencyThreadTbl!.addEventListener('column-click', (evt: unknown): void => {
75fb726d48Sopenharmony_ci      //@ts-ignore
76fb726d48Sopenharmony_ci      this.sortColumn = evt.detail.key; //@ts-ignore
77fb726d48Sopenharmony_ci      this.sortType = evt.detail.sort;
78fb726d48Sopenharmony_ci      // @ts-ignore
79fb726d48Sopenharmony_ci      this.sortByColumn(evt.detail);
80fb726d48Sopenharmony_ci    });
81fb726d48Sopenharmony_ci    this.frequencyThreadTbl!.addEventListener('row-hover', (evt: unknown): void => {
82fb726d48Sopenharmony_ci      //@ts-ignore
83fb726d48Sopenharmony_ci      if (evt.detail.data) {
84fb726d48Sopenharmony_ci        //@ts-ignore
85fb726d48Sopenharmony_ci        let data = evt.detail.data;
86fb726d48Sopenharmony_ci        data.isHover = true; //@ts-ignore
87fb726d48Sopenharmony_ci        if ((evt.detail as unknown).callBack) {
88fb726d48Sopenharmony_ci          //@ts-ignore
89fb726d48Sopenharmony_ci          (evt.detail as unknown).callBack(true);
90fb726d48Sopenharmony_ci        }
91fb726d48Sopenharmony_ci      }
92fb726d48Sopenharmony_ci      this.frequencyThreadPie?.showHover();
93fb726d48Sopenharmony_ci    }); // @ts-ignore
94fb726d48Sopenharmony_ci    this.frequencyThreadTbl!.itemTextHandleMap.set('freq', (value) => (value === -1 ? 'unknown' : value));
95fb726d48Sopenharmony_ci  }
96fb726d48Sopenharmony_ci
97fb726d48Sopenharmony_ci  sortByColumn(detail: unknown): void {
98fb726d48Sopenharmony_ci    // @ts-ignore
99fb726d48Sopenharmony_ci    function compare(frequencyThreadProperty, sort, type) {
100fb726d48Sopenharmony_ci      return function (a: unknown, b: unknown) {
101fb726d48Sopenharmony_ci        if (type === 'number') {
102fb726d48Sopenharmony_ci          // @ts-ignore
103fb726d48Sopenharmony_ci          return sort === 2
104fb726d48Sopenharmony_ci            ? // @ts-ignore
105fb726d48Sopenharmony_ci              parseFloat(b[frequencyThreadProperty]) - parseFloat(a[frequencyThreadProperty])
106fb726d48Sopenharmony_ci            : //@ts-ignore
107fb726d48Sopenharmony_ci              parseFloat(a[frequencyThreadProperty]) - parseFloat(b[frequencyThreadProperty]);
108fb726d48Sopenharmony_ci        } else {
109fb726d48Sopenharmony_ci          if (sort === 2) {
110fb726d48Sopenharmony_ci            //@ts-ignore
111fb726d48Sopenharmony_ci            return b[frequencyThreadProperty].toString().localeCompare(a[frequencyThreadProperty].toString());
112fb726d48Sopenharmony_ci          } else {
113fb726d48Sopenharmony_ci            //@ts-ignore
114fb726d48Sopenharmony_ci            return a[frequencyThreadProperty].toString().localeCompare(b[frequencyThreadProperty].toString());
115fb726d48Sopenharmony_ci          }
116fb726d48Sopenharmony_ci        }
117fb726d48Sopenharmony_ci      };
118fb726d48Sopenharmony_ci    }
119fb726d48Sopenharmony_ci
120fb726d48Sopenharmony_ci    //@ts-ignore
121fb726d48Sopenharmony_ci    if (detail.key === 'timeStr') {
122fb726d48Sopenharmony_ci      //@ts-ignore
123fb726d48Sopenharmony_ci      detail.key = 'time'; //@ts-ignore
124fb726d48Sopenharmony_ci      this.frequencyThreadData.sort(compare(detail.key, detail.sort, 'number')); //@ts-ignore
125fb726d48Sopenharmony_ci    } else if (detail.key === 'no' || detail.key === 'cpu' || detail.key === 'freq' || detail.key === 'ratio') {
126fb726d48Sopenharmony_ci      //@ts-ignore
127fb726d48Sopenharmony_ci      this.frequencyThreadData.sort(compare(detail.key, detail.sort, 'number'));
128fb726d48Sopenharmony_ci    } else {
129fb726d48Sopenharmony_ci      //@ts-ignore
130fb726d48Sopenharmony_ci      this.frequencyThreadData.sort(compare(detail.key, detail.sort, 'string'));
131fb726d48Sopenharmony_ci    }
132fb726d48Sopenharmony_ci    this.frequencyThreadTbl!.recycleDataSource = this.frequencyThreadData;
133fb726d48Sopenharmony_ci  }
134fb726d48Sopenharmony_ci
135fb726d48Sopenharmony_ci  async init(): Promise<void> {
136fb726d48Sopenharmony_ci    if (!this.traceChange) {
137fb726d48Sopenharmony_ci      if (this.frequencyThreadTbl!.recycleDataSource.length > 0) {
138fb726d48Sopenharmony_ci        this.frequencyThreadTbl?.reMeauseHeight();
139fb726d48Sopenharmony_ci      }
140fb726d48Sopenharmony_ci      return;
141fb726d48Sopenharmony_ci    }
142fb726d48Sopenharmony_ci    this.traceChange = false;
143fb726d48Sopenharmony_ci    this.frequencyThreadProgress!.loading = true;
144fb726d48Sopenharmony_ci    if (Top20FrequencyThread.threads === undefined) {
145fb726d48Sopenharmony_ci      //@ts-ignore
146fb726d48Sopenharmony_ci      Top20FrequencyThread.threads = (await queryThreads()) || [];
147fb726d48Sopenharmony_ci      this.nodata!.noData = Top20FrequencyThread.threads === undefined || Top20FrequencyThread.threads.length === 0;
148fb726d48Sopenharmony_ci      this.threadSelect!.innerHTML = ''; //@ts-ignore
149fb726d48Sopenharmony_ci      let threads = Top20FrequencyThread.threads.map((it) => {
150fb726d48Sopenharmony_ci        let option = new LitSelectOption();
151fb726d48Sopenharmony_ci        option.setAttribute('value', `${it.tid}`);
152fb726d48Sopenharmony_ci        option.textContent = it.name;
153fb726d48Sopenharmony_ci        return option;
154fb726d48Sopenharmony_ci      });
155fb726d48Sopenharmony_ci      this.threadSelect!.append(...threads);
156fb726d48Sopenharmony_ci      this.threadSelect?.initOptions(); //@ts-ignore
157fb726d48Sopenharmony_ci      this.threadSelect!.value = `${Top20FrequencyThread.threads[0].tid}`; //@ts-ignore
158fb726d48Sopenharmony_ci      this.currentThread!.textContent = Top20FrequencyThread.threads[0].name; //@ts-ignore
159fb726d48Sopenharmony_ci      this.currentTid = Top20FrequencyThread.threads[0].tid;
160fb726d48Sopenharmony_ci      this.queryData();
161fb726d48Sopenharmony_ci    }
162fb726d48Sopenharmony_ci  }
163fb726d48Sopenharmony_ci
164fb726d48Sopenharmony_ci  queryData(): void {
165fb726d48Sopenharmony_ci    this.queryLogicWorker('scheduling-Thread Freq', 'query Thread Top 20 Frequency Time:', (res): void => {
166fb726d48Sopenharmony_ci      this.nodata!.noData =
167fb726d48Sopenharmony_ci        Top20FrequencyThread.threads === undefined ||
168fb726d48Sopenharmony_ci        Top20FrequencyThread.threads.length === 0 ||
169fb726d48Sopenharmony_ci        res === undefined || //@ts-ignore
170fb726d48Sopenharmony_ci        res.length === 0;
171fb726d48Sopenharmony_ci      (res as unknown[]).map((it: unknown, index: number): void => {
172fb726d48Sopenharmony_ci        //@ts-ignore
173fb726d48Sopenharmony_ci        it.no = index + 1;
174fb726d48Sopenharmony_ci      }); //@ts-ignore
175fb726d48Sopenharmony_ci      this.frequencyThreadData = res;
176fb726d48Sopenharmony_ci      if (this.sortColumn !== '') {
177fb726d48Sopenharmony_ci        this.sortByColumn({
178fb726d48Sopenharmony_ci          key: this.sortColumn,
179fb726d48Sopenharmony_ci          sort: this.sortType,
180fb726d48Sopenharmony_ci        });
181fb726d48Sopenharmony_ci      } else {
182fb726d48Sopenharmony_ci        //@ts-ignore
183fb726d48Sopenharmony_ci        this.frequencyThreadTbl!.recycleDataSource = res;
184fb726d48Sopenharmony_ci      }
185fb726d48Sopenharmony_ci      this.frequencyThreadTbl!.reMeauseHeight();
186fb726d48Sopenharmony_ci      this.setThreadPieConfig(res);
187fb726d48Sopenharmony_ci      this.frequencyThreadProgress!.loading = false;
188fb726d48Sopenharmony_ci      this.shadowRoot!.querySelector('#tb_vessel')!.scrollTop = 0;
189fb726d48Sopenharmony_ci    });
190fb726d48Sopenharmony_ci  }
191fb726d48Sopenharmony_ci
192fb726d48Sopenharmony_ci  private setThreadPieConfig(res: unknown): void {
193fb726d48Sopenharmony_ci    this.frequencyThreadPie!.config = {
194fb726d48Sopenharmony_ci      appendPadding: 10, //@ts-ignore
195fb726d48Sopenharmony_ci      data: this.getPieChartData(res),
196fb726d48Sopenharmony_ci      angleField: 'time',
197fb726d48Sopenharmony_ci      colorField: 'freq',
198fb726d48Sopenharmony_ci      colorFieldTransferHandler: (value) => (value === -1 ? 'unknown' : value),
199fb726d48Sopenharmony_ci      radius: 0.8,
200fb726d48Sopenharmony_ci      label: {
201fb726d48Sopenharmony_ci        type: 'outer',
202fb726d48Sopenharmony_ci      },
203fb726d48Sopenharmony_ci      tip: (obj): string => {
204fb726d48Sopenharmony_ci        return `<div>
205fb726d48Sopenharmony_ci                             <div>freq:${
206fb726d48Sopenharmony_ci                               // @ts-ignore
207fb726d48Sopenharmony_ci                               obj.obj.freq === -1 ? 'unknown' : obj.obj.freq
208fb726d48Sopenharmony_ci                             }</div> 
209fb726d48Sopenharmony_ci                             <div>cpu:${
210fb726d48Sopenharmony_ci                               // @ts-ignore
211fb726d48Sopenharmony_ci                               obj.obj.cpu
212fb726d48Sopenharmony_ci                             }</div> 
213fb726d48Sopenharmony_ci                             <div>time:${
214fb726d48Sopenharmony_ci                               // @ts-ignore
215fb726d48Sopenharmony_ci                               obj.obj.timeStr
216fb726d48Sopenharmony_ci                             }</div> 
217fb726d48Sopenharmony_ci                             <div>ratio:${
218fb726d48Sopenharmony_ci                               // @ts-ignore
219fb726d48Sopenharmony_ci                               obj.obj.ratio
220fb726d48Sopenharmony_ci                             }%</div>
221fb726d48Sopenharmony_ci                        </div>
222fb726d48Sopenharmony_ci                `;
223fb726d48Sopenharmony_ci      },
224fb726d48Sopenharmony_ci      hoverHandler: (data): void => {
225fb726d48Sopenharmony_ci        if (data) {
226fb726d48Sopenharmony_ci          this.frequencyThreadTbl!.setCurrentHover(data);
227fb726d48Sopenharmony_ci        } else {
228fb726d48Sopenharmony_ci          this.frequencyThreadTbl!.mouseOut();
229fb726d48Sopenharmony_ci        }
230fb726d48Sopenharmony_ci      },
231fb726d48Sopenharmony_ci      interactions: [
232fb726d48Sopenharmony_ci        {
233fb726d48Sopenharmony_ci          type: 'element-active',
234fb726d48Sopenharmony_ci        },
235fb726d48Sopenharmony_ci      ],
236fb726d48Sopenharmony_ci    };
237fb726d48Sopenharmony_ci  }
238fb726d48Sopenharmony_ci
239fb726d48Sopenharmony_ci  getPieChartData(res: unknown[]): unknown[] {
240fb726d48Sopenharmony_ci    if (res.length > 20) {
241fb726d48Sopenharmony_ci      let pieChartArr: unknown[] = [];
242fb726d48Sopenharmony_ci      let other: unknown = {
243fb726d48Sopenharmony_ci        cpu: '-',
244fb726d48Sopenharmony_ci        freq: 'other',
245fb726d48Sopenharmony_ci        time: 0,
246fb726d48Sopenharmony_ci        ratio: '0',
247fb726d48Sopenharmony_ci        totalDur: 0,
248fb726d48Sopenharmony_ci      };
249fb726d48Sopenharmony_ci      for (let i = 0; i < res.length; i++) {
250fb726d48Sopenharmony_ci        if (i < 19) {
251fb726d48Sopenharmony_ci          pieChartArr.push(res[i]);
252fb726d48Sopenharmony_ci        } else {
253fb726d48Sopenharmony_ci          //@ts-ignore
254fb726d48Sopenharmony_ci          other.time += res[i].time; //@ts-ignore
255fb726d48Sopenharmony_ci          other.timeStr = getProbablyTime(other.time); //@ts-ignore
256fb726d48Sopenharmony_ci          other.totalDur = res[i].totalDur; //@ts-ignore
257fb726d48Sopenharmony_ci          other.ratio = ((other.time / other.totalDur) * 100).toFixed(2);
258fb726d48Sopenharmony_ci        }
259fb726d48Sopenharmony_ci      }
260fb726d48Sopenharmony_ci      pieChartArr.push(other);
261fb726d48Sopenharmony_ci      return pieChartArr;
262fb726d48Sopenharmony_ci    }
263fb726d48Sopenharmony_ci    return res;
264fb726d48Sopenharmony_ci  }
265fb726d48Sopenharmony_ci
266fb726d48Sopenharmony_ci  clearData(): void {
267fb726d48Sopenharmony_ci    this.traceChange = true;
268fb726d48Sopenharmony_ci    this.threadSelect!.innerHTML = '';
269fb726d48Sopenharmony_ci    this.frequencyThreadPie!.dataSource = [];
270fb726d48Sopenharmony_ci    this.frequencyThreadTbl!.recycleDataSource = [];
271fb726d48Sopenharmony_ci  }
272fb726d48Sopenharmony_ci
273fb726d48Sopenharmony_ci  queryLogicWorker(option: string, log: string, handler: (res: unknown) => void): void {
274fb726d48Sopenharmony_ci    let frequencyThreadTime = new Date().getTime();
275fb726d48Sopenharmony_ci    procedurePool.submitWithName('logic0', option, { tid: this.currentTid }, undefined, handler);
276fb726d48Sopenharmony_ci    let durTime = new Date().getTime() - frequencyThreadTime;
277fb726d48Sopenharmony_ci    info(log, durTime);
278fb726d48Sopenharmony_ci  }
279fb726d48Sopenharmony_ci
280fb726d48Sopenharmony_ci  initHtml(): string {
281fb726d48Sopenharmony_ci    return Top20FrequencyThreadHtml;
282fb726d48Sopenharmony_ci  }
283fb726d48Sopenharmony_ci}
284