• 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, RedrawTreeForm } from '../../../../../base-ui/table/lit-table';
18import { SelectionParam } from '../../../../bean/BoxSelection';
19import { Utils } from '../../base/Utils';
20import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar';
21import { TabPaneFilter } from '../TabPaneFilter';
22import '../TabPaneFilter';
23import { VM_TYPE_MAP } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem';
24import { getTabPaneVirtualMemoryStatisticsData } from '../../../../database/sql/Memory.sql';
25
26@element('tabpane-virtual-memory-statistics')
27export class TabPaneVirtualMemoryStatistics extends BaseElement {
28  private vmStatisticsTbl: LitTable | null | undefined;
29  private vmStatisticsSelectionParam: SelectionParam | null | undefined;
30  private vmStatisticsProgressEL: LitProgressBar | null | undefined;
31  private vmStatisticsFilter: TabPaneFilter | null | undefined;
32  private loadingPage: unknown;
33  private loadingList: number[] = [];
34  private vmStatisticsSource: Array<unknown> = [];
35  private vmStatisticsSortKey: string = '';
36  private vmStatisticsSortType: number = 0;
37  private vmStatisticsResultData: Array<unknown> = [];
38
39  set data(vmStatisticsSelection: SelectionParam | unknown) {
40    if (vmStatisticsSelection === this.vmStatisticsSelectionParam) {
41      return;
42    }
43    this.vmStatisticsProgressEL!.loading = true;
44    // @ts-ignore
45    this.loadingPage.style.visibility = 'visible';
46    // @ts-ignore
47    this.vmStatisticsSelectionParam = vmStatisticsSelection;
48    // @ts-ignore
49    this.vmStatisticsTbl!.shadowRoot!.querySelector('.table').style.height = `${this.parentElement!.clientHeight - 20
50      }px`;
51    this.queryDataByDB(vmStatisticsSelection);
52  }
53
54  initElements(): void {
55    this.vmStatisticsProgressEL = this.shadowRoot!.querySelector<LitProgressBar>('.progress');
56    this.loadingPage = this.shadowRoot!.querySelector('.loading');
57    this.vmStatisticsTbl = this.shadowRoot!.querySelector<LitTable>('#tb-vm-statistics');
58    this.vmStatisticsTbl!.addEventListener('column-click', (evt) => {
59      // @ts-ignore
60      this.vmStatisticsSortKey = evt.detail.key;
61      // @ts-ignore
62      this.vmStatisticsSortType = evt.detail.sort;
63      if (this.vmStatisticsSortType !== 0 && this.vmStatisticsSource.length > 0) {
64        this.sortVmStatisticsTable(this.vmStatisticsSource[0], this.vmStatisticsSortKey);
65      }
66      this.vmStatisticsTbl!.recycleDataSource = this.vmStatisticsSource;
67    });
68    this.vmStatisticsFilter = this.shadowRoot!.querySelector<TabPaneFilter>('#filter');
69    this.vmStatisticsFilter!.getStatisticsTypeData((type) => {
70      if (type === 'operation') {
71        this.sortStatus(this.vmStatisticsResultData, 'ipid', 'itid');
72      } else {
73        this.sortStatus(this.vmStatisticsResultData, 'type', 'ipid');
74      }
75      const labels = this.vmStatisticsTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label') as NodeListOf<HTMLLabelElement>;
76      labels.forEach((label, index) => {
77        if (type === 'operation') {
78          switch (index) {
79            case 0:
80              label.textContent = 'Process';
81              break;
82            case 1:
83              label.textContent = '/Thread';
84              break;
85            case 2:
86              label.textContent = '/Operation';
87              break;
88          }
89        } else {
90          switch (index) {
91            case 0:
92              label.textContent = 'Operation';
93              break;
94            case 1:
95              label.textContent = '/Process';
96              break;
97            case 2:
98              label.textContent = '/Thread';
99              break;
100          }
101        }
102      });
103    });
104  }
105
106  connectedCallback(): void {
107    super.connectedCallback();
108    new ResizeObserver((): void => {
109      if (this.parentElement!.clientHeight !== 0) {
110        // @ts-ignore
111        this.vmStatisticsTbl!.shadowRoot!.querySelector('.table').style.height = `${this.parentElement!.clientHeight - 10 - 32
112          }px`;
113        this.vmStatisticsTbl!.reMeauseHeight();
114        // @ts-ignore
115        this.loadingPage.style.height = `${this.parentElement!.clientHeight - 24}px`;
116      }
117    }).observe(this.parentElement!);
118  }
119
120  getInitData(initVmMemoryStatItem: unknown, nameTitle: unknown = 'pname', subtitle: unknown = null): unknown {
121    // @ts-ignore
122    let title = nameTitle === 'type' ? VM_TYPE_MAP[initVmMemoryStatItem[nameTitle]] : initVmMemoryStatItem[nameTitle];
123    return {
124      // @ts-ignore
125      ...initVmMemoryStatItem,
126      // @ts-ignore
127      title: title + (subtitle ? `(${initVmMemoryStatItem[subtitle]})` : ''),
128      // @ts-ignore
129      allDuration: Utils.getProbablyTime(initVmMemoryStatItem.allDuration),
130      // @ts-ignore
131      minDuration: Utils.getProbablyTime(initVmMemoryStatItem.minDuration),
132      // @ts-ignore
133      maxDuration: Utils.getProbablyTime(initVmMemoryStatItem.maxDuration),
134      // @ts-ignore
135      avgDuration: Utils.getProbablyTime(initVmMemoryStatItem.avgDuration),
136      // @ts-ignore
137      node: { ...initVmMemoryStatItem, children: [] },
138    };
139  }
140
141  queryDataByDB(vmMemoryStatParam: SelectionParam | unknown): void {
142    this.loadingList.push(1);
143    this.vmStatisticsProgressEL!.loading = true;
144    // @ts-ignore
145    this.loadingPage.style.visibility = 'visible';
146    getTabPaneVirtualMemoryStatisticsData(
147      // @ts-ignore
148      vmMemoryStatParam.leftNs + vmMemoryStatParam.recordStartNs,
149      // @ts-ignore
150      vmMemoryStatParam.rightNs + vmMemoryStatParam.recordStartNs
151    ).then((result) => {
152      this.loadingList.splice(0, 1);
153      if (this.loadingList.length === 0) {
154        this.vmStatisticsProgressEL!.loading = false;
155        // @ts-ignore
156        this.loadingPage.style.visibility = 'hidden';
157      }
158      this.vmStatisticsResultData = JSON.parse(JSON.stringify(result));
159      this.sortStatus(result, 'type', 'ipid');
160    });
161  }
162
163  sortStatus(result: Array<unknown>, firstLevel: string, secondLevel: string): void {
164    let vmMemoryStatFatherMap = new Map<unknown, unknown>();
165    let vmMemoryStatChildMap = new Map<unknown, unknown>();
166    let vmMemoryStatAllNode: unknown = {
167      title: 'All',
168      count: 0,
169      allDuration: 0,
170      minDuration: 0,
171      maxDuration: 0,
172      avgDuration: '',
173      children: [],
174    };
175    result.forEach((item, idx) => {
176      this.processChildMap(vmMemoryStatChildMap, item, firstLevel, secondLevel);
177      this.processFatherMap(vmMemoryStatFatherMap, item, firstLevel);
178      if (idx === 0) {
179        // @ts-ignore
180        vmMemoryStatAllNode.minDuration = item.minDuration;
181      } else {
182        // @ts-ignore
183        vmMemoryStatAllNode.minDuration =
184          // @ts-ignore
185          vmMemoryStatAllNode.minDuration <= item.minDuration ? vmMemoryStatAllNode.minDuration : item.minDuration;
186      }
187      // @ts-ignore
188      vmMemoryStatAllNode.count += item.count;
189      // @ts-ignore
190      vmMemoryStatAllNode.allDuration += item.allDuration;
191      // @ts-ignore
192      vmMemoryStatAllNode.maxDuration =
193        // @ts-ignore
194        vmMemoryStatAllNode.maxDuration >= item.maxDuration ? vmMemoryStatAllNode.maxDuration : item.maxDuration;
195    });
196    this.handleFatherMap(vmMemoryStatFatherMap, firstLevel, vmMemoryStatChildMap, vmMemoryStatAllNode);
197
198    // @ts-ignore
199    vmMemoryStatAllNode.avgDuration = vmMemoryStatAllNode.allDuration / vmMemoryStatAllNode.count;
200    vmMemoryStatAllNode = this.getInitData(vmMemoryStatAllNode);
201    // @ts-ignore
202    vmMemoryStatAllNode.title = 'All';
203    // @ts-ignore
204    vmMemoryStatAllNode.path = { type: null, tid: null, pid: null, value: 'All' };
205    this.vmStatisticsSource = result.length > 0 ? [vmMemoryStatAllNode] : [];
206    if (this.vmStatisticsSortType !== 0 && result.length > 0) {
207      this.sortVmStatisticsTable(this.vmStatisticsSource[0], this.vmStatisticsSortKey);
208    }
209    this.theadClick(this.vmStatisticsSource);
210    this.vmStatisticsTbl!.recycleDataSource = this.vmStatisticsSource;
211  }
212  private theadClick(res: Array<unknown>): void {
213    let labels = this.vmStatisticsTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label');
214    if (labels) {
215      for (let i = 0; i < labels.length; i++) {
216        let label = labels[i].innerHTML;
217        labels[i].addEventListener('click', (): void => {
218          if (i === 0) {
219            this.vmStatisticsTbl!.setStatus(res, false, 0, 1);
220            this.vmStatisticsTbl!.recycleDs = this.vmStatisticsTbl!.meauseTreeRowElement(res, RedrawTreeForm.Retract);
221          } else if (i === 1) {
222            this.vmStatisticsTbl!.setStatus(res, false, 0, 2);
223            this.vmStatisticsTbl!.recycleDs = this.vmStatisticsTbl!.meauseTreeRowElement(res, RedrawTreeForm.Retract);
224          } else if (i === 2) {
225            this.vmStatisticsTbl!.setStatus(res, true);
226            this.vmStatisticsTbl!.recycleDs = this.vmStatisticsTbl!.meauseTreeRowElement(res, RedrawTreeForm.Expand);
227          }
228        });
229      }
230    }
231  }
232  private handleFatherMap(
233    vmMemoryStatFatherMap: Map<unknown, unknown>,
234    firstLevel: string,
235    vmMemoryStatChildMap: Map<unknown, unknown>,
236    vmMemoryStatAllNode: unknown
237  ): void {
238    for (let ks of vmMemoryStatFatherMap.keys()) {
239      let sp = vmMemoryStatFatherMap.get(ks);
240      // @ts-ignore
241      sp!.children = [];
242      // @ts-ignore
243      sp.avgDuration = sp.allDuration / sp.count;
244      let vmMemoryStatNode = this.getInitData(
245        sp,
246        firstLevel === 'type' ? 'type' : 'pname',
247        firstLevel === 'type' ? null : 'pid'
248      );
249      // @ts-ignore
250      vmMemoryStatNode.path = { type: null, tid: null, pid: null, value: vmMemoryStatNode.title };
251      // @ts-ignore
252      vmMemoryStatNode.path[firstLevel === 'type' ? 'type' : 'pid'] =
253        // @ts-ignore
254        vmMemoryStatNode[firstLevel === 'type' ? 'type' : 'pid'];
255      this.handleChildMap(vmMemoryStatChildMap, ks, firstLevel, vmMemoryStatNode, sp);
256      // @ts-ignore
257      vmMemoryStatAllNode.children.push(vmMemoryStatNode);
258    }
259  }
260
261  private handleChildMap(
262    vmMemoryStatChildMap: Map<unknown, unknown>,
263    ks: unknown,
264    firstLevel: string,
265    vmMemoryStatNode: unknown,
266    sp: unknown
267  ): void {
268    for (let kst of vmMemoryStatChildMap.keys()) {
269      // @ts-ignore
270      if (kst.startsWith(`${ks}_`)) {
271        let spt = vmMemoryStatChildMap.get(kst);
272        let data = this.getInitData(
273          spt!,
274          firstLevel === 'type' ? 'pname' : 'tname',
275          firstLevel === 'type' ? 'pid' : 'tid'
276        );
277        this.handleData(data, vmMemoryStatNode, firstLevel);
278        // @ts-ignore
279        sp!.children.push(data);
280      }
281    }
282  }
283
284  private handleData(data: unknown, vmMemoryStatNode: unknown, firstLevel: string): void {
285    // @ts-ignore
286    data.path = {
287      type: null,
288      tid: null,
289      pid: null,
290      // @ts-ignore
291      value: `All-${vmMemoryStatNode.title}-${data.title}`,
292    };
293    // @ts-ignore
294    data.path[firstLevel === 'type' ? 'type' : 'pid'] = vmMemoryStatNode[firstLevel === 'type' ? 'type' : 'pid'];
295    // @ts-ignore
296    data.path[firstLevel === 'type' ? 'pid' : 'tid'] = data[firstLevel === 'type' ? 'pid' : 'tid'];
297    // @ts-ignore
298    data.children.forEach((e: unknown) => {
299      // @ts-ignore
300      e.path = {
301        type: null,
302        tid: null,
303        pid: null,
304        // @ts-ignore
305        value: `All-${vmMemoryStatNode.title}-${data.title}-${e.title}`,
306      };
307      // @ts-ignore
308      e.path[firstLevel === 'type' ? 'type' : 'pid'] = vmMemoryStatNode[firstLevel === 'type' ? 'type' : 'pid'];
309      // @ts-ignore
310      e.path[firstLevel === 'type' ? 'pid' : 'tid'] = data[firstLevel === 'type' ? 'pid' : 'tid'];
311      // @ts-ignore
312      e.path[firstLevel === 'type' ? 'tid' : 'type'] = e[firstLevel === 'type' ? 'tid' : 'type'];
313    });
314  }
315
316  private processFatherMap(vmMemoryStatFatherMap: Map<unknown, unknown>, item: unknown, firstLevel: string): void {
317    // @ts-ignore
318    if (vmMemoryStatFatherMap.has(item[firstLevel])) {
319      // @ts-ignore
320      let vmMemoryStatFatherObj = vmMemoryStatFatherMap.get(item[firstLevel]);
321      // @ts-ignore
322      vmMemoryStatFatherObj.count += item.count;
323      // @ts-ignore
324      vmMemoryStatFatherObj.allDuration += item.allDuration;
325      // @ts-ignore
326      vmMemoryStatFatherObj.minDuration =
327        // @ts-ignore
328        vmMemoryStatFatherObj.minDuration <= item.minDuration ? vmMemoryStatFatherObj.minDuration : item.minDuration;
329      // @ts-ignore
330      vmMemoryStatFatherObj.maxDuration =
331        // @ts-ignore
332        vmMemoryStatFatherObj.maxDuration >= item.maxDuration ? vmMemoryStatFatherObj.maxDuration : item.maxDuration;
333      // @ts-ignore
334      vmMemoryStatFatherObj.children.push(this.getInitData(item));
335    } else {
336      // @ts-ignore
337      vmMemoryStatFatherMap.set(item[firstLevel], {
338        // @ts-ignore
339        ...item,
340        children: [this.getInitData(item)],
341      });
342    }
343  }
344
345  private processChildMap(
346    vmMemoryStatChildMap: Map<unknown, unknown>,
347    item: unknown,
348    firstLevel: string,
349    secondLevel: string
350  ): void {
351    // @ts-ignore
352    if (vmMemoryStatChildMap.has(`${item[firstLevel]}_${item[secondLevel]}`)) {
353      // @ts-ignore
354      let vmMemoryStatChildObj = vmMemoryStatChildMap.get(`${item[firstLevel]}_${item[secondLevel]}`);
355      // @ts-ignore
356      vmMemoryStatChildObj.count += item.count;
357      // @ts-ignore
358      vmMemoryStatChildObj.allDuration += item.allDuration;
359      // @ts-ignore
360      vmMemoryStatChildObj.minDuration =
361        // @ts-ignore
362        vmMemoryStatChildObj.minDuration <= item.minDuration ? vmMemoryStatChildObj.minDuration : item.minDuration;
363      // @ts-ignore
364      vmMemoryStatChildObj.maxDuration =
365        // @ts-ignore
366        vmMemoryStatChildObj.maxDuration >= item.maxDuration ? vmMemoryStatChildObj.maxDuration : item.maxDuration;
367      // @ts-ignore
368      vmMemoryStatChildObj.children.push(
369        this.getInitData(item, firstLevel === 'type' ? 'tname' : 'type', firstLevel === 'type' ? 'tid' : null)
370      );
371    } else {
372      // @ts-ignore
373      vmMemoryStatChildMap.set(`${item[firstLevel]}_${item[secondLevel]}`, {
374        // @ts-ignore
375        ...item,
376        children: [
377          this.getInitData(item, firstLevel === 'type' ? 'tname' : 'type', firstLevel === 'type' ? 'tid' : null),
378        ],
379      });
380    }
381  }
382
383  sortVmStatisticsTable(allNode: unknown, key: string): void {
384    // @ts-ignore
385    allNode.children.sort((vmStatNodeA: unknown, vmStatNodeB: unknown) => {
386      // @ts-ignore
387      return this.vmStatisticsSortType === 1 ? vmStatNodeA.node[key] - vmStatNodeB.node[key] : vmStatNodeB.node[key] - vmStatNodeA.node[key];
388    });
389    // @ts-ignore
390    allNode.children.forEach((item: unknown): void => {
391      // @ts-ignore
392      item.children.sort((vmStatNodeA: unknown, vmStatNodeB: unknown) => {
393        let backData;
394        if (this.vmStatisticsSortType === 1) {
395          // @ts-ignore
396          backData = vmStatNodeA.node[key] - vmStatNodeB.node[key];
397        } else if (this.vmStatisticsSortType === 2) {
398          // @ts-ignore
399          backData = vmStatNodeB.node[key] - vmStatNodeA.node[key];
400        }
401        return backData;
402      });
403      // @ts-ignore
404      item.children.forEach((vmStatItem: unknown) => {
405        // @ts-ignore
406        vmStatItem.children.sort((vmStatItemA: unknown, vmStatItemB: unknown) => {
407          let backData;
408          if (this.vmStatisticsSortType === 1) {
409            // @ts-ignore
410            backData = vmStatItemA.node[key] - vmStatItemB.node[key];
411          } else if (this.vmStatisticsSortType === 2) {
412            // @ts-ignore
413            backData = vmStatItemB.node[key] - vmStatItemA.node[key];
414          }
415          return backData;
416        });
417      });
418    });
419  }
420
421  initHtml(): string {
422    return `
423        <style>
424        .vm-stat-progress{
425            bottom: 5px;
426            position: absolute;
427            height: 1px;
428            left: 0;
429            right: 0;
430        }
431        :host{
432            display: flex;
433            flex-direction: column;
434            padding: 10px 10px 0 10px;
435        }
436        .vm-stat-loading{
437            bottom: 0;
438            position: absolute;
439            left: 0;
440            right: 0;
441            width:100%;
442            background:transparent;
443            z-index: 999999;
444        }
445        </style>
446        <lit-table id="tb-vm-statistics" style="height: auto" tree>
447            <lit-table-column class="vm-memory-stat-column" width="20%" title="Operation/Process/Thread" data-index="title" key="title" align="flex-start"retract>
448            </lit-table-column>
449            <lit-table-column class="vm-memory-stat-column" width="1fr" title="Count" data-index="count" key="count" align="flex-start" order>
450            </lit-table-column>
451            <lit-table-column class="vm-memory-stat-column" width="1fr" title="Duration" data-index="allDuration" key="allDuration" align="flex-start" order>
452            </lit-table-column>
453            <lit-table-column class="vm-memory-stat-column" width="1fr" title="Min Duration" data-index="minDuration" key="minDuration" align="flex-start" order>
454            </lit-table-column>
455            <lit-table-column class="vm-memory-stat-column" width="1fr" title="Avg Duration" data-index="avgDuration" key="avgDuration" align="flex-start" order>
456            </lit-table-column>
457            <lit-table-column class="vm-memory-stat-column" width="1fr" title="Max Duration" data-index="maxDuration" key="maxDuration" align="flex-start" order>
458            </lit-table-column>
459        </lit-table>
460        <lit-progress-bar class="progress vm-stat-progress"></lit-progress-bar>
461        <tab-pane-filter id="filter" sort></tab-pane-filter>
462        <div class="loading vm-stat-loading"></div>
463        `;
464  }
465}
466