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