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