• 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 { type LitTable } from '../../../../../base-ui/table/lit-table';
18import { type SelectionParam } from '../../../../bean/BoxSelection';
19import { MemoryConfig } from '../../../../bean/MemoryConfig';
20import { Utils } from '../../base/Utils';
21import { resizeObserver } from '../SheetUtils';
22import { querySysPurgeableTab } from '../../../../database/sql/Ability.sql';
23import { queryProcessPurgeableTab } from '../../../../database/sql/ProcessThread.sql';
24
25@element('tabpane-purg-total')
26export class TabPanePurgTotal extends BaseElement {
27  private purgeableTotalTable: LitTable | null | undefined;
28  private purgeableTotalSource: Array<PurgeableTabStruct> = [];
29  private tabTitle: HTMLDivElement | undefined | null;
30  private purgTotalTimeRange: HTMLLabelElement | undefined | null;
31  private sortKey = 'avgSize';
32  private sortType = 2;
33
34  set data(selection: SelectionParam) {
35    if (this.purgeableTotalTable) {
36      //@ts-ignore
37      this.purgeableTotalTable.shadowRoot.querySelector('.table').style.height = `${
38        this.parentElement!.clientHeight - 45
39      }px`;
40    }
41    this.init();
42    this.purgTotalTimeRange!.textContent =
43      'Selected range: ' + ((selection.rightNs - selection.leftNs) / 1000000.0).toFixed(5) + ' ms';
44    this.purgeableTotalTable!.loading = true;
45    this.purgeableTotalTable!.recycleDataSource = [];
46    // 框选了 Purgeable Total
47    if (selection.purgeableTotalAbility.length > 0) {
48      this.purgeableTotalSource = [];
49      querySysPurgeableTab(
50        selection.leftNs,
51        selection.rightNs,
52        (MemoryConfig.getInstance().interval * 1000000) / 5
53      ).then((purgeTotalResults) => {
54        this.purgeableTotalTable!.loading = false;
55        this.getPurgeableTotalSource(purgeTotalResults);
56      });
57    } else if (selection.purgeableTotalVM.length > 0) {
58      this.purgeableTotalSource = [];
59      queryProcessPurgeableTab(
60        selection.leftNs,
61        selection.rightNs,
62        (MemoryConfig.getInstance().interval * 1000000) / 5,
63        MemoryConfig.getInstance().iPid
64      ).then((results) => {
65        this.purgeableTotalTable!.loading = false;
66        this.getPurgeableTotalSource(results);
67      });
68    }
69  }
70
71  getPurgeableTotalSource(results: any): void {
72    if (results.length > 0) {
73      for (let i = 0; i < results.length; i++) {
74        this.purgeableTotalSource.push(
75          this.toTabStruct(results[i].name, results[i].maxSize, results[i].minSize, results[i].avgSize)
76        );
77      }
78      this.sortByColumn({key: this.sortKey, sort: this.sortType});
79      let total = this.totalData(this.purgeableTotalSource);
80      this.purgeableTotalSource.unshift(total);
81      this.purgeableTotalTable!.recycleDataSource = this.purgeableTotalSource;
82      this.purgeableTotalSource.shift();
83    } else {
84      this.purgeableTotalSource = [];
85      this.purgeableTotalTable!.recycleDataSource = [];
86    }
87  }
88
89  private init(): void {
90    const thTable = this.tabTitle!.querySelector('.th');
91    const purgeTotalTblNode = thTable!.querySelectorAll('div');
92    if (this.tabTitle!.hasAttribute('sort')) {
93      this.tabTitle!.removeAttribute('sort');
94      purgeTotalTblNode.forEach((item) => {
95        item.querySelectorAll('svg').forEach((svg) => {
96          svg.style.display = 'none';
97        });
98      });
99    }
100    this.sortKey = 'avgSize';
101    this.sortType = 2;
102  }
103
104  private toTabStruct(type: string, maxSize: number, minSize: number, avgSize: number): PurgeableTabStruct {
105    const tabStruct = new PurgeableTabStruct(
106      type,
107      maxSize,
108      minSize,
109      avgSize,
110      Utils.getBinaryByteWithUnit(avgSize),
111      Utils.getBinaryByteWithUnit(maxSize),
112      Utils.getBinaryByteWithUnit(minSize)
113    );
114    return tabStruct;
115  }
116
117  private totalData(source: Array<PurgeableTabStruct>): PurgeableTabStruct {
118    // 计算总的time作为表格的第一行显示
119    let totalAvg = 0;
120    let totalMax = 0;
121    let totalMin = 0;
122    for (let item of source) {
123      totalAvg += item.avgSize;
124      totalMax += item.maxSize;
125      totalMin += item.minSize;
126    }
127    let totalData = this.toTabStruct('Total', totalAvg, totalMax, totalMin);
128    return totalData;
129  }
130
131  private sortByColumn(detail: any): void {
132    // @ts-ignore
133    function compare(key, sort, type) {
134      return function (purgeTotalLeftData: any, purgeTotalRightData: any) {
135        // 不管哪一列的排序方式是0(默认排序),都按照avgSize列从大到小排序
136        if (sort === 0) {
137          sort = 2;
138          key = 'avgSize';
139          type = 'number';
140        }
141        if (type === 'number') {
142          // @ts-ignore
143          return sort === 2
144            ? parseFloat(purgeTotalRightData[key]) - parseFloat(purgeTotalLeftData[key])
145            : parseFloat(purgeTotalLeftData[key]) - parseFloat(purgeTotalRightData[key]);
146        } else {
147          if (sort === 2) {
148            return purgeTotalRightData[key].toString().localeCompare(purgeTotalLeftData[key].toString());
149          } else {
150            return purgeTotalLeftData[key].toString().localeCompare(purgeTotalRightData[key].toString());
151          }
152        }
153      };
154    }
155
156    if (detail.key === 'type') {
157      this.purgeableTotalSource.sort(compare(detail.key, detail.sort, 'string'));
158    } else {
159      this.purgeableTotalSource.sort(compare(detail.key, detail.sort, 'number'));
160    }
161    let total = this.totalData(this.purgeableTotalSource);
162    this.purgeableTotalSource.unshift(total);
163    this.purgeableTotalTable!.recycleDataSource = this.purgeableTotalSource;
164    this.purgeableTotalSource.shift();
165  }
166
167  initElements(): void {
168    this.purgeableTotalTable = this.shadowRoot?.querySelector<LitTable>('#tb-purgeable-total');
169    this.tabTitle = this.purgeableTotalTable!.shadowRoot?.querySelector('.thead') as HTMLDivElement;
170    this.purgTotalTimeRange = this.shadowRoot?.querySelector('#purg-total-time-range') as HTMLLabelElement;
171    this.purgeableTotalTable!.addEventListener('column-click', (evt: any) => {
172      this.sortKey = evt.detail.key;
173      this.sortType = evt.detail.sort;
174      // @ts-ignore
175      this.sortByColumn(evt.detail);
176    });
177  }
178
179  connectedCallback(): void {
180    super.connectedCallback();
181    resizeObserver(this.parentElement!, this.purgeableTotalTable!);
182  }
183
184  initHtml(): string {
185    return `
186        <style>
187        :host{
188            display: flex;
189            flex-direction: column;
190            padding: 10px 10px;
191        }
192        .purg-total-label{
193            display: flex;
194            height: 20px;
195            align-items: center;
196            flex-direction: row;
197            margin-bottom: 5px;
198        }
199        #purg-total-time-range{
200            width: auto;
201            text-align: end;
202            font-size: 10pt;
203        }
204        </style>
205        <div class="purg-total-label">
206            <div style="flex: 1"></div>
207            <label id="purg-total-time-range">Selected range:0.0 ms</label>
208        </div>
209        <lit-table id="tb-purgeable-total" style="height: auto">
210            <lit-table-column width="1fr" title="Type" data-index="type" key="type"  align="flex-start" order>
211            </lit-table-column>
212            <lit-table-column width="1fr" title="AvgSize" data-index="avgSizeStr" key="avgSize"  align="flex-start" order>
213            </lit-table-column>
214            <lit-table-column width="1fr" title="MaxSize" data-index="maxSizeStr" key="maxSize"  align="flex-start" order>
215            </lit-table-column>
216            <lit-table-column width="1fr" title="MinSize" data-index="minSizeStr" key="minSize"  align="flex-start" order>
217            </lit-table-column>
218        </lit-table>
219        `;
220  }
221}
222
223export class PurgeableTabStruct {
224  type: string;
225  avgSize: number;
226  maxSize: number;
227  minSize: number;
228  avgSizeStr: string;
229  maxSizeStr: string;
230  minSizeStr: string;
231
232  constructor(
233    type: string,
234    avgSize: number,
235    maxSize: number,
236    minSize: number,
237    avgSizeStr: string,
238    maxSizeStr: string,
239    minSizeStr: string
240  ) {
241    this.type = type;
242    this.avgSize = avgSize;
243    this.maxSize = maxSize;
244    this.minSize = minSize;
245    this.avgSizeStr = avgSizeStr;
246    this.maxSizeStr = maxSizeStr;
247    this.minSizeStr = minSizeStr;
248  }
249}
250