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