• 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 data 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 */
15import { element } from '../../../../../base-ui/BaseElement';
16import { type LitSelect } from '../../../../../base-ui/select/LitSelect';
17import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption';
18import { type LitTable } from '../../../../../base-ui/table/lit-table';
19import { type SelectionParam } from '../../../../bean/BoxSelection';
20import { resizeObserverFromMemory } from '../SheetUtils';
21import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter';
22import { TabPaneSmapsStatistics } from './TabPaneSmapsStatistics';
23import { type SmapsType } from '../../../../bean/SmapsStruct';
24import { getTabSmapsStatisticData } from '../../../../database/sql/Smaps.sql';
25
26@element('tabpane-smaps-comparison')
27export class TabPaneSmapsComparison extends TabPaneSmapsStatistics {
28  private smapsCompariosnTable: LitTable | null | undefined;
29  private filterEl: TabPaneJsMemoryFilter | undefined | null;
30  private selectEl: LitSelect | undefined | null;
31  private selectionParam: SelectionParam | undefined;
32
33  public initElements(): void {
34    this.smapsCompariosnTable = this.shadowRoot?.querySelector<LitTable>('#tb-smaps-comparison');
35    this.filterEl = this.shadowRoot!.querySelector<TabPaneJsMemoryFilter>('#filter');
36    this.selectEl = this.filterEl?.shadowRoot?.querySelector<LitSelect>('lit-select');
37    this.tabTitle = this.smapsCompariosnTable!.shadowRoot?.querySelector('.thead') as HTMLDivElement;
38    this.smapsCompariosnTable!.addEventListener('column-click', (evt) => {
39      // @ts-ignore
40      this.sortByColumn(evt.detail.key, evt.detail.sort, this.smapsCompariosnTable);
41    });
42  }
43  public setData(data: SelectionParam | unknown, dataList: unknown): void {
44    if (data == this.selectionParam) {
45      return;
46    } // @ts-ignore
47    this.selectionParam = data;
48    //@ts-ignore
49    this.smapsCompariosnTable?.shadowRoot?.querySelector('.table')?.style?.height = `${
50      this.parentElement!.clientHeight - 45
51    }px`;
52    this.smapsCompariosnTable!.loading = true;
53    this.init(this.tabTitle!);
54    let fileArr: unknown[] = []; // @ts-ignore
55    for (let file of dataList) {
56      // @ts-ignore
57      if (file.startNs !== data.leftNs) {
58        fileArr.push(file);
59      }
60    }
61    fileArr = fileArr.sort(); // @ts-ignore
62    this.initSelect(data.leftNs, fileArr); // @ts-ignore
63    this.querySmapsData(data.leftNs, fileArr[0].startNs);
64  }
65  private initSelect(fileStartNs: number, smapsComFileArr: Array<unknown>): void {
66    let input = this.selectEl!.shadowRoot?.querySelector('input') as HTMLInputElement;
67    this.selectEl!.innerHTML = '';
68    let option = new LitSelectOption();
69    option.innerHTML = 'File Name';
70    option.setAttribute('disabled', 'disabled');
71    this.selectEl?.appendChild(option); // @ts-ignore
72    if (smapsComFileArr[0].name) {
73      // @ts-ignore
74      option.setAttribute('value', smapsComFileArr[0].name);
75    } // @ts-ignore
76    this.selectEl!.defaultValue = smapsComFileArr[0].name; // @ts-ignore
77    this.selectEl!.placeholder = smapsComFileArr[0].name;
78    this.selectEl!.dataSource = smapsComFileArr;
79    this.selectEl!.querySelectorAll('lit-select-option').forEach((a) => {
80      a.addEventListener('onSelected', (e: unknown) => {
81        for (let f of smapsComFileArr) {
82          // @ts-ignore
83          if (input.value === f.name) {
84            // @ts-ignore
85            this.querySmapsData(fileStartNs, f.startNs);
86          }
87        } // @ts-ignore
88        e.stopPropagation();
89      });
90    });
91  }
92
93  private async querySmapsData(baseTime: number, targetTime: number): Promise<void> {
94    const baseArr: SmapsCompareStruct[] = [];
95    const targetArr: SmapsCompareStruct[] = [];
96    // 点击的
97    await getTabSmapsStatisticData(baseTime).then(async (smapsComResults) => {
98      this.smapsCompariosnTable!.loading = false;
99      for (let i = 0; i < smapsComResults.length; i++) {
100        baseArr.push(
101          new SmapsCompareStruct(
102            smapsComResults[i].type,
103            smapsComResults[i].path,
104            smapsComResults[i].size,
105            smapsComResults[i].count,
106            smapsComResults[i].rss,
107            smapsComResults[i].pss,
108            smapsComResults[i].sharedClean,
109            smapsComResults[i].sharedDirty,
110            smapsComResults[i].privateClean,
111            smapsComResults[i].privateDirty,
112            smapsComResults[i].swap,
113            smapsComResults[i].swapPss
114          )
115        );
116      }
117      // 被比较的
118      await getTabSmapsStatisticData(targetTime).then((results) => {
119        for (let i = 0; i < results.length; i++) {
120          targetArr.push(
121            new SmapsCompareStruct(
122              results[i].type,
123              results[i].path,
124              results[i].size,
125              results[i].count,
126              results[i].rss,
127              results[i].pss,
128              results[i].sharedClean,
129              results[i].sharedDirty,
130              results[i].privateClean,
131              results[i].privateDirty,
132              results[i].swap,
133              results[i].swapPss
134            )
135          );
136        }
137        let compareData = this.compare(baseArr, targetArr);
138        this.filteredData(compareData, this.smapsCompariosnTable!);
139      });
140    });
141  }
142
143  private compare(base: Array<SmapsCompareStruct>, target: Array<SmapsCompareStruct>): Array<SmapsCompareStruct> {
144    const diffMap = new Map<string, SmapsCompareStruct>();
145
146    for (const item of base) {
147      diffMap.set(item.type + ' ' + item.path, item.clone(true));
148    }
149
150    for (const item of target) {
151      if (diffMap.has(item.type + ' ' + item.path)) {
152        const diffItem = diffMap.get(item.type + ' ' + item.path);
153        diffItem!.size = diffItem!.size - item.size;
154        diffItem!.count = diffItem!.count - item.count;
155        diffItem!.rss = diffItem!.rss - item.rss;
156        diffItem!.pss = diffItem!.pss - item.pss;
157        diffItem!.sharedClean = diffItem!.sharedClean - item.sharedClean;
158        diffItem!.sharedDirty = diffItem!.sharedDirty - item.sharedDirty;
159        diffItem!.privateClean = diffItem!.privateClean - item.privateClean;
160        diffItem!.privateDirty = diffItem!.privateDirty - item.privateDirty;
161        diffItem!.swap = diffItem!.swap - item.swap;
162        diffItem!.swapPss = diffItem!.swapPss - item.swapPss;
163      } else {
164        diffMap.set(item.type + ' ' + item.path, item.clone());
165      }
166    }
167    return Array.from(diffMap.values());
168  }
169
170  public connectedCallback(): void {
171    super.connectedCallback();
172    resizeObserverFromMemory(this.parentElement!, this.smapsCompariosnTable!, this.filterEl!);
173  }
174  public initHtml(): string {
175    return `
176    <style>
177        :host{
178            display: flex;
179            flex-direction: column;
180            padding: 10px 10px;
181        }
182    </style>
183    <div style="overflow: auto;" class="d-box">
184        <lit-table id="tb-smaps-comparison" class="smaps-comparison-table" style="height: auto;" tree>
185            <lit-table-column width="250px" title="Type" data-index="typeName" key="typeName" align="flex-start" order retract>
186            </lit-table-column>
187            <lit-table-column width="150px" title="Path" data-index="path" key="path" align="flex-start" >
188            </lit-table-column>
189            <lit-table-column  width="150px" title="SizeDelta" data-index="sizeStr" key="sizeStr" align="flex-start" order>
190            </lit-table-column>
191            <lit-table-column  width="150px" title="Count" data-index="count" key="count" align="flex-start" order>
192            </lit-table-column>
193            <lit-table-column width="150px" title="RssDelta" data-index="rssStr" key="rssStr" align="flex-start" order>
194            </lit-table-column>
195            <lit-table-column width="150px" title="PssDelta" data-index="pssStr" key="pssStr" align="flex-start" order>
196            </lit-table-column>
197            <lit-table-column  width="150px" title="SharedCleanDelta" data-index="sharedCleanStr" key="sharedCleanStr" align="flex-start" order>
198            </lit-table-column>
199            <lit-table-column width="150px" title="SharedDirtyDelta" data-index="sharedDirtyStr" key="sharedDirtyStr" align="flex-start" order>
200            </lit-table-column>
201            <lit-table-column width="150px" title="PrivateCleanDelta" data-index="privateCleanStr" key="privateCleanStr" align="flex-start" order>
202            </lit-table-column>
203            <lit-table-column width="150px" title="PrivateDirtyDelta" data-index="privateDirtyStr" key="privateDirtyStr" align="flex-start" order>
204            </lit-table-column>
205            <lit-table-column width="150px" title="SwapDelta" data-index="swapStr" key="swapStr" align="flex-start" order>
206            </lit-table-column>
207            <lit-table-column width="150px" title="SwapPssDelta" data-index="swapPssStr" key="swapPssStr" align="flex-start" order>
208            </lit-table-column>
209        </lit-table>
210        <tab-pane-js-memory-filter id="filter" first hideFilter></tab-pane-js-memory-filter>
211    </div>`;
212  }
213}
214
215class SmapsCompareStruct {
216  type: SmapsType;
217  path: string;
218  size: number;
219  count: number;
220  rss: number;
221  pss: number;
222  sharedClean: number;
223  sharedDirty: number;
224  privateClean: number;
225  privateDirty: number;
226  swap: number;
227  swapPss: number;
228
229  constructor(
230    type: SmapsType,
231    path: string,
232    size: number,
233    count: number,
234    rss: number,
235    pss: number,
236    sharedClean: number,
237    sharedDirty: number,
238    privateClean: number,
239    privateDirty: number,
240    swap: number,
241    swapPss: number
242  ) {
243    this.type = type;
244    this.path = path;
245    this.size = size;
246    this.count = count;
247    this.rss = rss;
248    this.pss = pss;
249    this.sharedClean = sharedClean;
250    this.sharedDirty = sharedDirty;
251    this.privateClean = privateClean;
252    this.privateDirty = privateDirty;
253    this.swap = swap;
254    this.swapPss = swapPss;
255  }
256
257  clone(isBase?: boolean): SmapsCompareStruct {
258    if (isBase) {
259      return new SmapsCompareStruct(
260        this.type,
261        this.path,
262        this.size,
263        this.count,
264        this.rss,
265        this.pss,
266        this.sharedClean,
267        this.sharedDirty,
268        this.privateClean,
269        this.privateDirty,
270        this.swap,
271        this.swapPss
272      );
273    } else {
274      return new SmapsCompareStruct(
275        this.type,
276        this.path,
277        -this.size,
278        -this.count,
279        -this.rss,
280        -this.pss,
281        -this.sharedClean,
282        -this.sharedDirty,
283        -this.privateClean,
284        -this.privateDirty,
285        -this.swap,
286        -this.swapPss
287      );
288    }
289  }
290}
291