• 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 } from '../../../../../base-ui/table/lit-table';
18import { SelectionParam } from '../../../../bean/BoxSelection';
19import '../../../../../base-ui/slicer/lit-slicer';
20import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar';
21import { procedurePool } from '../../../../database/Procedure';
22import { VirtualMemoryEvent, VM_TYPE_MAP } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem';
23import { FilterData, TabPaneFilter } from '../TabPaneFilter';
24import { getTabVirtualMemoryType } from '../../../../database/sql/Memory.sql';
25import { TabPaneVMEventsHtml } from './TabPaneVMEvents.html';
26
27@element('tabpane-virtualmemory-event')
28export class TabPaneVirtualMemoryEvents extends BaseElement {
29  // @ts-ignore
30  private defaultNativeTypes = ['All', ...Object.values(VM_TYPE_MAP)];
31  private nativeType: Array<string> = [...this.defaultNativeTypes];
32  private vmEventTbl: LitTable | null | undefined;
33  private vmEventTblData: LitTable | null | undefined;
34  private vmEventProgressEL: LitProgressBar | null | undefined;
35  private loadingList: number[] = [];
36  private loadingPage: unknown;
37  private vmEventSource: Array<VirtualMemoryEvent> = [];
38  private queryVmEventDataSource: Array<VirtualMemoryEvent> = [];
39  private currentSelection: SelectionParam | undefined | null;
40  private statsticsSelection: Array<unknown> = [];
41
42  set data(vmEventSelection: SelectionParam | null | undefined) {
43    if (vmEventSelection === this.currentSelection) {
44      return;
45    }
46    this.currentSelection = vmEventSelection;
47    this.initFilterTypes(vmEventSelection!).then(() => {
48      this.queryData(vmEventSelection!);
49    });
50    if (this.vmEventTbl) {
51      // @ts-ignore
52      this.vmEventTbl.shadowRoot.querySelector('.table').style.height =
53        this.parentElement!.clientHeight - 20 - 31 + 'px';
54      this.vmEventTbl.recycleDataSource = [];
55    }
56    if (this.vmEventTblData) {
57      // @ts-ignore
58      this.vmEventTblData.shadowRoot.querySelector('.table').style.height =
59        this.parentElement!.clientHeight - 20 - 31 + 'px';
60      this.vmEventTblData.recycleDataSource = [];
61    }
62  }
63
64  connectedCallback(): void {
65    new ResizeObserver((entries) => {
66      if (this.parentElement?.clientHeight !== 0) {
67        if (this.vmEventTbl) {
68          // @ts-ignore
69          this.vmEventTbl.shadowRoot.querySelector('.table').style.height =
70            this.parentElement!.clientHeight - 10 - 33 + 'px';
71          this.vmEventTbl.reMeauseHeight();
72        }
73        if (this.vmEventTblData) {
74          // @ts-ignore
75          this.vmEventTblData.shadowRoot.querySelector('.table').style.height =
76            this.parentElement!.clientHeight - 10 - 33 + 'px';
77          this.vmEventTblData.reMeauseHeight();
78        } // @ts-ignore
79        this.loadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px';
80      }
81    }).observe(this.parentElement!);
82  }
83
84  initElements(): void {
85    this.loadingPage = this.shadowRoot?.querySelector('.loading');
86    this.vmEventProgressEL = this.shadowRoot?.querySelector('.vm-event-progress') as LitProgressBar;
87    this.vmEventTbl = this.shadowRoot?.querySelector<LitTable>('#vm-event-tbl');
88    this.vmEventTblData = this.shadowRoot?.querySelector<LitTable>('#vm-event-tbr');
89    this.vmEventTbl!.addEventListener('row-click', (vmEventRowClick) => {
90      // @ts-ignore
91      let data = vmEventRowClick.detail.data; // @ts-ignore
92      (data as unknown).isSelected = true;
93      // @ts-ignore
94      if ((vmEventRowClick.detail as unknown).callBack) {
95        // @ts-ignore
96        (vmEventRowClick.detail as unknown).callBack(true);
97      }
98      procedurePool.submitWithName(
99        'logic0',
100        'fileSystem-queryStack',
101        { callchainId: data.callchainId },
102        undefined,
103        (res: unknown) => {
104          // @ts-ignore
105          this.vmEventTblData!.recycleDataSource = res;
106        }
107      );
108    });
109    this.vmEventTbl!.addEventListener('column-click', (evt) => {
110      // @ts-ignore
111      this.vmEventSortKey = evt.detail.key;
112      // @ts-ignore
113      this.vmEventSortType = evt.detail.sort;
114      // @ts-ignore
115      this.sortVmEventTable(evt.detail.key, evt.detail.sort);
116    });
117    this.shadowRoot?.querySelector<TabPaneFilter>('#vm-event-filter')!.getFilterData((data: FilterData) => {
118      let index = parseInt(data.firstSelect || '0');
119      if (index > this.defaultNativeTypes.length - 1) {
120        this.filterTypeData(this.statsticsSelection[index - this.defaultNativeTypes.length]);
121      } else {
122        this.filterTypeData(undefined);
123      }
124      this.vmEventTbl!.recycleDataSource = this.vmEventSource;
125    });
126  }
127
128  async initFilterTypes(vmEventParam: SelectionParam): Promise<void> {
129    let filter = this.shadowRoot?.querySelector<TabPaneFilter>('#vm-event-filter');
130    let typeKeys = await getTabVirtualMemoryType(vmEventParam.leftNs, vmEventParam.rightNs);
131    this.defaultNativeTypes = ['All'];
132    this.statsticsSelection = [];
133    typeKeys.forEach((item) => {
134      // @ts-ignore
135      this.defaultNativeTypes.push(VM_TYPE_MAP[item.type + '']);
136    });
137    this.nativeType = [...this.defaultNativeTypes];
138    filter!.setSelectList([...this.defaultNativeTypes], null, 'Operation Type');
139    filter!.firstSelect = '0';
140  }
141
142  async fromStastics(vmEventParam: SelectionParam | unknown): Promise<void> {
143    // @ts-ignore
144    if (vmEventParam.fileSystemVMData === undefined) {
145      return;
146    }
147    this.vmEventTblData!.recycleDataSource = [];
148    this.vmEventTblData?.clearAllSelection(undefined);
149    let filter = this.shadowRoot?.querySelector<TabPaneFilter>('#vm-event-filter');
150    if (this.currentSelection !== vmEventParam) {
151      // @ts-ignore
152      await this.initFilterTypes(vmEventParam);
153    } // @ts-ignore
154    let typeIndexOf = this.nativeType.indexOf(vmEventParam.fileSystemVMData.path.value);
155    if (typeIndexOf === -1) {
156      // @ts-ignore
157      this.statsticsSelection.push(vmEventParam.fileSystemVMData.path); // @ts-ignore
158      this.nativeType.push(vmEventParam.fileSystemVMData.path.value);
159      typeIndexOf = this.nativeType.length - 1;
160    }
161    if (this.currentSelection !== vmEventParam) {
162      // @ts-ignore
163      this.currentSelection = vmEventParam;
164      filter!.setSelectList(this.nativeType, null, 'Operation Type');
165      filter!.firstSelect = typeIndexOf + ''; // @ts-ignore
166      this.queryData(vmEventParam);
167    } else {
168      if (typeIndexOf === parseInt(filter!.firstSelect)) {
169        return;
170      }
171      filter!.setSelectList(this.nativeType, null, 'Operation Type');
172      filter!.firstSelect = typeIndexOf + ''; // @ts-ignore
173      this.filterTypeData(vmEventParam?.fileSystemVMData?.path || undefined); // @ts-ignore
174      vmEventParam.fileSystemVMData = undefined;
175      this.vmEventTbl!.recycleDataSource = this.vmEventSource;
176    }
177  }
178
179  queryData(vmEventParam: SelectionParam): void {
180    this.loadingList.push(1);
181    this.vmEventProgressEL!.loading = true; // @ts-ignore
182    this.loadingPage.style.visibility = 'visible';
183    this.vmEventSource = [];
184    this.queryVmEventDataSource = [];
185    procedurePool.submitWithName(
186      'logic0',
187      'fileSystem-queryVMEvents',
188      {
189        leftNs: vmEventParam.leftNs,
190        rightNs: vmEventParam.rightNs,
191        typeArr: vmEventParam.fileSystemType,
192      },
193      undefined,
194      (res: unknown) => {
195        // @ts-ignore
196        this.vmEventSource = this.vmEventSource.concat(res.data); // @ts-ignore
197        this.queryVmEventDataSource = this.queryVmEventDataSource.concat(res.data);
198        // @ts-ignore
199        this.filterTypeData(vmEventParam?.fileSystemVMData?.path || undefined);
200        vmEventParam.fileSystemVMData = undefined; // @ts-ignore
201        res.data = null; // @ts-ignore
202        if (!res.isSending) {
203          this.vmEventTbl!.recycleDataSource = this.vmEventSource;
204          this.loadingList.splice(0, 1);
205          if (this.loadingList.length === 0) {
206            this.vmEventProgressEL!.loading = false; // @ts-ignore
207            this.loadingPage.style.visibility = 'hidden';
208          }
209        }
210      }
211    );
212  }
213
214  filterTypeData(pathData: unknown): void {
215    let filter = this.shadowRoot?.querySelector<TabPaneFilter>('#vm-event-filter');
216    let firstSelect = filter!.firstSelect;
217    let type = -1;
218    let tid = -1;
219    let pid = -1;
220    if (parseInt(firstSelect) <= this.defaultNativeTypes.length - 1) {
221      // @ts-ignore
222      let typeEntry = Object.entries(VM_TYPE_MAP).find((entry) => {
223        return entry[1] === this.defaultNativeTypes[parseInt(firstSelect)];
224      });
225      type = typeEntry ? parseInt(typeEntry[0]) : 0;
226    } else if (pathData !== undefined) {
227      // @ts-ignore
228      type = parseInt(pathData.type || 0); // @ts-ignore
229      tid = pathData.tid || -1; // @ts-ignore
230      pid = pathData.pid || -1;
231    } else if (pathData === undefined) {
232      return;
233    }
234    let isTidFilter = false;
235    let isPidFilter = false;
236    let isTypeFilter = false;
237    this.vmEventSource = this.queryVmEventDataSource.filter((item) => {
238      if (tid === -1) {
239        isTidFilter = true;
240      } else {
241        isTidFilter = item.tid === tid;
242      }
243      if (pid === -1) {
244        isPidFilter = true;
245      } else {
246        isPidFilter = item.pid === pid;
247      }
248      isTypeFilter = type === 0 || item.type === type;
249      return isTidFilter && isPidFilter && isTypeFilter;
250    });
251  }
252
253  sortVmEventTable(key: string, type: number): void {
254    if (type === 0) {
255      this.vmEventTbl!.recycleDataSource = this.vmEventSource;
256    } else {
257      let arr = Array.from(this.vmEventSource);
258      arr.sort((vmEventA, vmEventB): number => {
259        if (key === 'startTsStr') {
260          if (type === 1) {
261            return vmEventA.startTs - vmEventB.startTs;
262          } else {
263            return vmEventB.startTs - vmEventA.startTs;
264          }
265        } else if (key === 'durStr') {
266          if (type === 1) {
267            return vmEventA.dur - vmEventB.dur;
268          } else {
269            return vmEventB.dur - vmEventA.dur;
270          }
271        } else if (key === 'thread') {
272          if (vmEventA.thread > vmEventB.thread) {
273            return type === 2 ? 1 : -1;
274          } else if (vmEventA.thread === vmEventB.thread) {
275            return 0;
276          } else {
277            return type === 2 ? -1 : 1;
278          }
279        } else if (key === 'sizeStr') {
280          if (type === 1) {
281            return vmEventA.size - vmEventB.size;
282          } else {
283            return vmEventB.size - vmEventA.size;
284          }
285        } else {
286          return 0;
287        }
288      });
289      this.vmEventTbl!.recycleDataSource = arr;
290    }
291  }
292
293  initHtml(): string {
294    return TabPaneVMEventsHtml;
295  }
296}
297