• 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 { getTabPaneFilesystemStatistics } from '../../../../database/sql/SqlLite.sql';
22
23@element('tabpane-file-statistics')
24export class TabPaneFileStatistics extends BaseElement {
25  private fileStatisticsTbl: LitTable | null | undefined;
26  private selectionParam: SelectionParam | null | undefined;
27  private fileStatisticsProgressEL: LitProgressBar | null | undefined;
28  private fileStatisticsLoadingPage: unknown;
29  private fileStatisticsLoadingList: number[] = [];
30  private fileStatisticsSource: Array<unknown> = [];
31  private typeList: Array<string> = ['OPEN', 'CLOSE', 'READ', 'WRITE'];
32  private fileStatisticsSortKey: string = '';
33  private fileStatisticsSortType: number = 0;
34
35  set data(fileStatisticsSelection: SelectionParam | unknown) {
36    if (fileStatisticsSelection === this.selectionParam) {
37      return;
38    }
39    this.fileStatisticsProgressEL!.loading = true; // @ts-ignore
40    this.fileStatisticsLoadingPage.style.visibility = 'visible'; // @ts-ignore
41    this.selectionParam = fileStatisticsSelection;
42    // @ts-ignore
43    this.fileStatisticsTbl!.shadowRoot!.querySelector('.table').style.height = `${this.parentElement!.clientHeight - 25
44      }px`;
45    this.queryDataByDB(fileStatisticsSelection);
46  }
47
48  initElements(): void {
49    this.fileStatisticsProgressEL = this.shadowRoot!.querySelector<LitProgressBar>('.file-statistics-progress');
50    this.fileStatisticsLoadingPage = this.shadowRoot!.querySelector('.file-statistics-loading');
51    this.fileStatisticsTbl = this.shadowRoot!.querySelector<LitTable>('#tb-file-statistics');
52    this.fileStatisticsTbl!.addEventListener('column-click', (evt: Event): void => {
53      // @ts-ignore
54      this.fileStatisticsSortKey = evt.detail.key;
55      // @ts-ignore
56      this.fileStatisticsSortType = evt.detail.sort;
57      if (this.fileStatisticsSortType !== 0 && this.fileStatisticsSource.length > 0) {
58        this.sortTable(this.fileStatisticsSource[0], this.fileStatisticsSortKey);
59      }
60      this.fileStatisticsTbl!.recycleDataSource = this.fileStatisticsSource;
61    });
62  }
63
64  connectedCallback(): void {
65    super.connectedCallback();
66    new ResizeObserver((): void => {
67      if (this.parentElement!.clientHeight !== 0) {
68        // @ts-ignore
69        this.fileStatisticsTbl!.shadowRoot!.querySelector('.table').style.height = `${this.parentElement!.clientHeight - 25
70          }px`;
71        this.fileStatisticsTbl!.reMeauseHeight(); // @ts-ignore
72        this.fileStatisticsLoadingPage.style.height = `${this.parentElement!.clientHeight - 24}px`;
73      }
74    }).observe(this.parentElement!);
75  }
76
77  getInitData(item: unknown): unknown {
78    return {
79      // @ts-ignore
80      ...item, // @ts-ignore
81      title: `${item.name}(${item.pid})`, // @ts-ignore
82      logicalWrites: Utils.getBinaryByteWithUnit(item.logicalWrites), // @ts-ignore
83      logicalReads: Utils.getBinaryByteWithUnit(item.logicalReads), // @ts-ignore
84      otherFile: Utils.getBinaryByteWithUnit(item.otherFile), // @ts-ignore
85      allDuration: Utils.getProbablyTime(item.allDuration), // @ts-ignore
86      minDuration: Utils.getProbablyTime(item.minDuration), // @ts-ignore
87      maxDuration: Utils.getProbablyTime(item.maxDuration), // @ts-ignore
88      avgDuration: Utils.getProbablyTime(item.avgDuration), // @ts-ignore
89      node: { ...item, children: [] },
90    };
91  }
92
93  queryDataByDB(val: SelectionParam | unknown): void {
94    this.fileStatisticsLoadingList.push(1);
95    this.fileStatisticsProgressEL!.loading = true; // @ts-ignore
96    this.fileStatisticsLoadingPage.style.visibility = 'visible';
97    getTabPaneFilesystemStatistics(
98      // @ts-ignore
99      val.leftNs + val.recordStartNs, // @ts-ignore
100      val.rightNs + val.recordStartNs, // @ts-ignore
101      val.fileSystemType
102    ).then((result): void => {
103      this.fileStatisticsLoadingList.splice(0, 1);
104      if (this.fileStatisticsLoadingList.length === 0) {
105        this.fileStatisticsProgressEL!.loading = false; // @ts-ignore
106        this.fileStatisticsLoadingPage.style.visibility = 'hidden';
107      }
108      let fileStatisticsFatherMap = new Map<unknown, unknown>();
109      let fileStatisticsAllNode: unknown = {
110        title: 'All',
111        count: 0,
112        logicalReads: 0,
113        logicalWrites: 0,
114        otherFile: 0,
115        allDuration: 0,
116        minDuration: 0,
117        maxDuration: 0,
118        avgDuration: '',
119        children: [],
120      };
121      this.handleResult(result, fileStatisticsFatherMap, fileStatisticsAllNode);
122      fileStatisticsFatherMap.forEach((item): void => {
123        // @ts-ignore
124        item.avgDuration = item.allDuration / item.count;
125        let node = this.getInitData(item); // @ts-ignore
126        if (item.type < 4) {
127          // @ts-ignore
128          node.title = this.typeList[item.type];
129        } else {
130          // @ts-ignore
131          node.title = item.type;
132        } // @ts-ignore
133        fileStatisticsAllNode.children.push(node);
134      }); // @ts-ignore
135      fileStatisticsAllNode.avgDuration = fileStatisticsAllNode.allDuration / fileStatisticsAllNode.count;
136      fileStatisticsAllNode = this.getInitData(fileStatisticsAllNode); // @ts-ignore
137      fileStatisticsAllNode.title = 'All';
138      this.fileStatisticsSource = result.length > 0 ? [fileStatisticsAllNode] : [];
139      if (this.fileStatisticsSortType !== 0 && result.length > 0) {
140        this.sortTable(this.fileStatisticsSource[0], this.fileStatisticsSortKey);
141      }
142      this.theadClick(this.fileStatisticsSource);
143      this.fileStatisticsTbl!.recycleDataSource = this.fileStatisticsSource;
144    });
145  }
146  private theadClick(res: Array<unknown>): void {
147    let labels = this.fileStatisticsTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label');
148    if (labels) {
149      for (let i = 0; i < labels.length; i++) {
150        let label = labels[i].innerHTML;
151        labels[i].addEventListener('click', (): void => {
152          if (label.includes('Syscall') && i === 0) {
153            this.fileStatisticsTbl!.setStatus(res, false, 0, 1);
154            this.fileStatisticsTbl!.recycleDs = this.fileStatisticsTbl!.meauseTreeRowElement(
155              res,
156              RedrawTreeForm.Retract
157            );
158          } else if (label.includes('Process') && i === 1) {
159            this.fileStatisticsTbl!.setStatus(res, true);
160            this.fileStatisticsTbl!.recycleDs = this.fileStatisticsTbl!.meauseTreeRowElement(
161              res,
162              RedrawTreeForm.Retract
163            );
164          }
165        });
166      }
167    }
168  }
169
170  private handleResult(
171    result: Array<unknown>,
172    fileStatisticsFatherMap: Map<unknown, unknown>,
173    fileStatisticsAllNode: unknown
174  ): void {
175    result.forEach((item, idx): void => {
176      // @ts-ignore
177      if (fileStatisticsFatherMap.has(item.type)) {
178        // @ts-ignore
179        let fileStatisticsObj = fileStatisticsFatherMap.get(item.type); // @ts-ignore
180        fileStatisticsObj.count += item.count; // @ts-ignore
181        fileStatisticsObj.logicalReads += item.logicalReads; // @ts-ignore
182        fileStatisticsObj.logicalWrites += item.logicalWrites; // @ts-ignore
183        fileStatisticsObj.otherFile += item.otherFile; // @ts-ignore
184        fileStatisticsObj.allDuration += item.allDuration; // @ts-ignore
185        fileStatisticsObj.minDuration = // @ts-ignore
186          fileStatisticsObj.minDuration <= item.minDuration ? fileStatisticsObj.minDuration : item.minDuration; // @ts-ignore
187        fileStatisticsObj.maxDuration = // @ts-ignore
188          fileStatisticsObj.maxDuration >= item.maxDuration ? fileStatisticsObj.maxDuration : item.maxDuration; // @ts-ignore
189        fileStatisticsObj.children.push(this.getInitData(item));
190      } else {
191        // @ts-ignore
192        fileStatisticsFatherMap.set(item.type, {
193          // @ts-ignore
194          type: item.type, // @ts-ignore
195          count: item.count, // @ts-ignore
196          logicalReads: item.logicalReads, // @ts-ignore
197          logicalWrites: item.logicalWrites, // @ts-ignore
198          otherFile: item.otherFile, // @ts-ignore
199          allDuration: item.allDuration, // @ts-ignore
200          minDuration: item.minDuration, // @ts-ignore
201          maxDuration: item.maxDuration, // @ts-ignore
202          children: [this.getInitData(item)],
203        });
204      }
205      if (idx === 0) {
206        // @ts-ignore
207        fileStatisticsAllNode.minDuration = item.minDuration;
208      } else {
209        // @ts-ignore
210        fileStatisticsAllNode.minDuration = // @ts-ignore
211          fileStatisticsAllNode.minDuration <= item.minDuration ? fileStatisticsAllNode.minDuration : item.minDuration;
212      } // @ts-ignore
213      fileStatisticsAllNode.count += item.count; // @ts-ignore
214      fileStatisticsAllNode.logicalReads += item.logicalReads; // @ts-ignore
215      fileStatisticsAllNode.logicalWrites += item.logicalWrites; // @ts-ignore
216      fileStatisticsAllNode.otherFile += item.otherFile; // @ts-ignore
217      fileStatisticsAllNode.allDuration += item.allDuration; // @ts-ignore
218      fileStatisticsAllNode.maxDuration = // @ts-ignore
219        fileStatisticsAllNode.maxDuration >= item.maxDuration ? fileStatisticsAllNode.maxDuration : item.maxDuration;
220    });
221  }
222
223  sortTable(fileStatisticsAllNode: unknown, key: string): void {
224    // @ts-ignore
225    fileStatisticsAllNode.children.sort((fileStatisticsA: unknown, fileStatisticsB: unknown) => {
226      return this.fileStatisticsSortType === 1 ?
227        // @ts-ignore
228        fileStatisticsA.node[key] - fileStatisticsB.node[key] :
229        this.fileStatisticsSortType === 2 ?
230          // @ts-ignore
231          fileStatisticsB.node[key] - fileStatisticsA.node[key] : 0;
232    }); // @ts-ignore
233    fileStatisticsAllNode.children.forEach((item: unknown): void => {
234      // @ts-ignore
235      item.children.sort((fileStatisticsA: unknown, fileStatisticsB: unknown) => {
236        return this.fileStatisticsSortType === 1 ?
237          // @ts-ignore
238          fileStatisticsA.node[key] - fileStatisticsB.node[key] :
239          this.fileStatisticsSortType === 2 ?
240            // @ts-ignore
241            fileStatisticsB.node[key] - fileStatisticsA.node[key] : 0;
242      });
243    });
244  }
245
246  initHtml(): string {
247    return `
248        <style>
249        :host{
250            display: flex;
251            flex-direction: column;
252            padding: 10px 10px;
253        }
254        .file-statistics-progress{
255            bottom: 5px;
256            position: absolute;
257            height: 1px;
258            left: 0;
259            right: 0;
260        }
261        .file-statistics-loading{
262            bottom: 0;
263            position: absolute;
264            left: 0;
265            right: 0;
266            width:100%;
267            background:transparent;
268            z-index: 999999;
269        }
270        </style>
271        <lit-table id="tb-file-statistics" style="height: auto" tree>
272            <lit-table-column class="fs-stat-column" width="20%" title="Syscall/Process" data-index="title" key="title" align="flex-start" retract>
273            </lit-table-column>
274            <lit-table-column class="fs-stat-column" width="1fr" title="Count" data-index="count" key="count" align="flex-start" order>
275            </lit-table-column>
276            <lit-table-column class="fs-stat-column" width="1fr" title="Logical Writes" data-index="logicalWrites" key="logicalWrites" align="flex-start" order>
277            </lit-table-column>
278            <lit-table-column class="fs-stat-column" width="1fr" title="Logical Reads" data-index="logicalReads" key="logicalReads" align="flex-start" order>
279            </lit-table-column>
280            <lit-table-column class="fs-stat-column" width="1fr" title="Other Filesystem Bytes" data-index="otherFile" key="otherFile" align="flex-start" order>
281            </lit-table-column>
282            <lit-table-column class="fs-stat-column" width="1fr" title="Duration" data-index="allDuration" key="allDuration" align="flex-start" order>
283            </lit-table-column>
284            <lit-table-column class="fs-stat-column" width="1fr" title="Min Duration" data-index="minDuration" key="minDuration" align="flex-start" order>
285            </lit-table-column>
286            <lit-table-column class="fs-stat-column" width="1fr" title="Avg Duration" data-index="avgDuration" key="avgDuration" align="flex-start" order>
287            </lit-table-column>
288            <lit-table-column class="fs-stat-column" width="1fr" title="Max Duration" data-index="maxDuration" key="maxDuration" align="flex-start" order>
289            </lit-table-column>
290        </lit-table>
291        <lit-progress-bar class="file-statistics-progress"></lit-progress-bar>
292        <div class="file-statistics-loading"></div>
293        `;
294  }
295}
296