• 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.js";
17import {LitTable} from "../../../../../base-ui/table/lit-table.js";
18import {SelectionParam} from "../../../../bean/BoxSelection.js";
19import {
20    getTabPaneVirtualMemoryStatisticsData,
21} from "../../../../database/SqlLite.js";
22import {Utils} from "../../base/Utils.js";
23import {LitProgressBar} from "../../../../../base-ui/progress-bar/LitProgressBar.js";
24import {TabPaneFilter} from "../TabPaneFilter.js";
25import  "../TabPaneFilter.js";
26import {VM_TYPE_MAP} from "../../../../database/logic-worker/ProcedureLogicWorkerFileSystem.js";
27
28@element('tabpane-virtual-memory-statistics')
29export class TabPaneVirtualMemoryStatistics extends BaseElement {
30    private tbl: LitTable | null | undefined;
31    private range: HTMLLabelElement | null | undefined;
32    private loadDataInCache: boolean = true;
33    private selectionParam:SelectionParam | null | undefined;
34    private progressEL:LitProgressBar | null | undefined;
35    private filter: TabPaneFilter | null | undefined;
36    private loadingPage:any;
37    private loadingList:number[] = [];
38    private source: Array<any> = [];
39    private typeList: Array<string> = ["OPEN", "CLOSE", "READ" , "WRITE"];
40    private sortKey: string = "";
41    private sortType: number = 0;
42    private resultData: Array<any> = [];
43
44    set data(val: SelectionParam | any) {
45        if(val == this.selectionParam){
46            return;
47        }
48        this.progressEL!.loading = true
49        this.loadingPage.style.visibility = "visible"
50        this.selectionParam = val;
51        // @ts-ignore
52        this.tbl!.shadowRoot!.querySelector(".table").style.height = (this.parentElement!.clientHeight - 20) + "px"
53        this.queryDataByDB(val)
54    }
55
56    initElements(): void {
57        this.progressEL = this.shadowRoot!.querySelector<LitProgressBar>('.progress')
58        this.loadingPage = this.shadowRoot!.querySelector('.loading');
59        this.tbl = this.shadowRoot!.querySelector<LitTable>('#tb-states');
60        this.tbl!.addEventListener('column-click', (evt) => {
61            // @ts-ignore
62            this.sortKey = evt.detail.key
63            // @ts-ignore
64            this.sortType = evt.detail.sort;
65
66            let newSource = JSON.parse(JSON.stringify(this.source));
67            if (this.sortType != 0 && newSource.length > 0) this.sortTable(newSource[0],this.sortKey);
68            this.tbl!.recycleDataSource = newSource;
69        })
70        this.filter = this.shadowRoot!.querySelector<TabPaneFilter>("#filter");
71        this.filter!.getStatisticsTypeData((type)=>{
72            if (type=="operation") {
73                this.sortStatus(this.resultData,"ipid","itid")
74            }else {
75                this.sortStatus(this.resultData,"type","ipid")
76            }
77            this.tbl!.shadowRoot!.querySelector("div > div.thead > div > div:nth-child(1) > label")!.textContent = type=="operation"?"Process/Thread/Operation":"Operation/Process/Thread"
78        })
79
80    }
81
82    connectedCallback() {
83        super.connectedCallback();
84        new ResizeObserver((entries) => {
85            if (this.parentElement!.clientHeight != 0) {
86                // @ts-ignore
87                this.tbl!.shadowRoot!.querySelector(".table").style.height = (this.parentElement!.clientHeight - 10 -31) + "px"
88                this.tbl!.reMeauseHeight()
89                this.loadingPage.style.height = (this.parentElement!.clientHeight - 24) + "px"
90            }
91        }).observe(this.parentElement!);
92    }
93
94    getInitData(item:any,nameTitle:any = "pname",subtitle:any = null){
95        // @ts-ignore
96        let title = (nameTitle == "type")?VM_TYPE_MAP[item[nameTitle]]:item[nameTitle];
97        return {
98            ...item,
99            title : title+(subtitle?("("+item[subtitle]+")"):""),
100            allDuration : Utils.getProbablyTime(item.allDuration),
101            minDuration : Utils.getProbablyTime(item.minDuration),
102            maxDuration : Utils.getProbablyTime(item.maxDuration),
103            avgDuration : Utils.getProbablyTime(item.avgDuration),
104            node:{...item,children:[]},
105        }
106    }
107
108    queryDataByDB(val: SelectionParam | any) {
109        this.loadingList.push(1)
110        this.progressEL!.loading = true
111        this.loadingPage.style.visibility = "visible";
112        getTabPaneVirtualMemoryStatisticsData(val.leftNs + val.recordStartNs,val.rightNs + val.recordStartNs).then(result => {
113            this.loadingList.splice(0,1)
114            if(this.loadingList.length == 0) {
115                this.progressEL!.loading = false
116                this.loadingPage.style.visibility = "hidden"
117            }
118            this.resultData = JSON.parse(JSON.stringify(result));
119            this.sortStatus(result,"type","ipid")
120        })
121    }
122
123    sortStatus(result:Array<any>,firstLevel:string,secondLevel:string){
124        let fatherMap = new Map<any,any>();
125        let childMap = new Map<any,any>();
126        let allNode:any = {
127            title:"All",
128            count:0,
129            allDuration:0,
130            minDuration:0,
131            maxDuration:0,
132            avgDuration:"",
133            children:[],
134        };
135        result.forEach((item,idx)=>{
136            if (childMap.has(item[firstLevel]+"_"+item[secondLevel])) {
137                let obj1 = childMap.get(item[firstLevel]+"_"+item[secondLevel]);
138                obj1.count += item.count;
139                obj1.allDuration += item.allDuration;
140                obj1.minDuration = obj1.minDuration<=item.minDuration?obj1.minDuration:item.minDuration;
141                obj1.maxDuration = obj1.maxDuration>=item.maxDuration?obj1.maxDuration:item.maxDuration;
142                obj1.children.push(this.getInitData(item,firstLevel=="type"?"tname":"type",firstLevel=="type"?"tid":null));
143            }else {
144                childMap.set(item[firstLevel]+"_"+item[secondLevel],{
145                    ...item,
146                    children:[this.getInitData(item,firstLevel=="type"?"tname":"type",firstLevel=="type"?"tid":null)]
147                })
148            }
149
150            if (fatherMap.has(item[firstLevel])) {
151                let obj1 = fatherMap.get(item[firstLevel]);
152                obj1.count += item.count;
153                obj1.allDuration += item.allDuration;
154                obj1.minDuration = obj1.minDuration<=item.minDuration?obj1.minDuration:item.minDuration;
155                obj1.maxDuration = obj1.maxDuration>=item.maxDuration?obj1.maxDuration:item.maxDuration;
156                obj1.children.push(this.getInitData(item));
157            }else {
158                fatherMap.set(item[firstLevel],{
159                    ...item,
160                    children:[this.getInitData(item)]
161                })
162            }
163            if (idx == 0) {
164                allNode.minDuration = item.minDuration;
165            }else {
166                allNode.minDuration = allNode.minDuration<=item.minDuration?allNode.minDuration:item.minDuration;
167            }
168            allNode.count += item.count;
169            allNode.allDuration += item.allDuration;
170            allNode.maxDuration = allNode.maxDuration>=item.maxDuration?allNode.maxDuration:item.maxDuration;
171        })
172
173        for (let ks of fatherMap.keys()) {
174            let sp = fatherMap.get(ks)
175            sp!.children = [];
176            sp.avgDuration = sp.allDuration/sp.count;
177            let node = this.getInitData(sp,firstLevel=="type"?"type":"pname",firstLevel=="type"?null:"pid");
178            node.path = {type:null,tid:null,pid:null,value:node.title}
179            node.path[firstLevel=="type"?"type":"pid"] = node[firstLevel=="type"?"type":"pid"];
180            for (let kst of childMap.keys()) {
181                if (kst.startsWith(ks + "_")) {
182                    let spt = childMap.get(kst)
183                    let data = this.getInitData(spt!,firstLevel=="type"?"pname":"tname",firstLevel=="type"?"pid":"tid")
184                    data.path = {type:null,tid:null,pid:null,value:"All-"+node.title+"-"+data.title}
185                    data.path[firstLevel=="type"?"type":"pid"] = node[firstLevel=="type"?"type":"pid"];
186                    data.path[firstLevel=="type"?"pid":"tid"] = data[firstLevel=="type"?"pid":"tid"];
187                    data.children.forEach((e:any)=>{
188                        e.path = {type:null,tid:null,pid:null,value:"All-"+node.title+"-"+data.title+"-"+e.title}
189                        e.path[firstLevel=="type"?"type":"pid"] = node[firstLevel=="type"?"type":"pid"];
190                        e.path[firstLevel=="type"?"pid":"tid"] = data[firstLevel=="type"?"pid":"tid"];
191                        e.path[firstLevel=="type"?"tid":"type"] = e[firstLevel=="type"?"tid":"type"];
192                    })
193                    sp!.children.push(data);
194                }
195            }
196            allNode.children.push(node)
197        }
198
199        allNode.avgDuration = allNode.allDuration/allNode.count;
200        allNode = this.getInitData(allNode);
201        allNode.title = "All";
202        allNode.path = {type:null,tid:null,pid:null,value:"All"};
203        this.source = result.length > 0 ? [allNode] : [];
204        let newSource = JSON.parse(JSON.stringify(this.source));
205        if (this.sortType != 0 && result.length > 0) this.sortTable(newSource[0],this.sortKey);
206        this.tbl!.recycleDataSource = newSource;
207    }
208
209    sortTable(allNode:any,key:string){
210        allNode.children.sort((a:any, b:any) => {
211            if (this.sortType == 1) {
212                return a.node[key] - b.node[key]
213            }else if (this.sortType == 2) {
214                return b.node[key] - a.node[key]
215            }
216        });
217        allNode.children.forEach((item:any)=>{
218            item.children.sort((a:any, b:any) => {
219                if (this.sortType == 1) {
220                    return a.node[key] - b.node[key]
221                }else if (this.sortType == 2) {
222                    return b.node[key] - a.node[key]
223                }
224            })
225            item.children.forEach((i:any)=>{
226                i.children.sort((a:any, b:any) => {
227                    if (this.sortType == 1) {
228                        return a.node[key] - b.node[key]
229                    }else if (this.sortType == 2) {
230                        return b.node[key] - a.node[key]
231                    }
232                })
233            });
234        });
235    }
236
237    initHtml(): string {
238        return `
239        <style>
240        :host{
241            display: flex;
242            flex-direction: column;
243            padding: 10px 10px 0 10px;
244        }
245        .progress{
246            bottom: 5px;
247            position: absolute;
248            height: 1px;
249            left: 0;
250            right: 0;
251        }
252        .loading{
253            bottom: 0;
254            position: absolute;
255            left: 0;
256            right: 0;
257            width:100%;
258            background:transparent;
259            z-index: 999999;
260        }
261        </style>
262        <lit-table id="tb-states" style="height: auto" tree>
263            <lit-table-column width="20%" title="Operation/Process/Thread" data-index="title" key="title" align="flex-start">
264            </lit-table-column>
265            <lit-table-column width="1fr" title="Count" data-index="count" key="count" align="flex-start" order>
266            </lit-table-column>
267            <lit-table-column width="1fr" title="Duration" data-index="allDuration" key="allDuration" align="flex-start" order>
268            </lit-table-column>
269            <lit-table-column width="1fr" title="Min Duration" data-index="minDuration" key="minDuration" align="flex-start" order>
270            </lit-table-column>
271            <lit-table-column width="1fr" title="Avg Duration" data-index="avgDuration" key="avgDuration" align="flex-start" order>
272            </lit-table-column>
273            <lit-table-column width="1fr" title="Max Duration" data-index="maxDuration" key="maxDuration" align="flex-start" order>
274            </lit-table-column>
275        </lit-table>
276        <lit-progress-bar class="progress"></lit-progress-bar>
277        <tab-pane-filter id="filter" sort></tab-pane-filter>
278        <div class="loading"></div>
279        `;
280    }
281}
282