• 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 {SpSystemTrace} from "../SpSystemTrace.js";
17import {TraceRow} from "../trace/base/TraceRow.js";
18import {procedurePool} from "../../database/Procedure.js";
19import {
20    getDiskIOLatencyChartDataByProcess,
21    getDiskIOProcess,
22    getFileSysChartDataByType, getFileSysVirtualMemoryChartData,
23    hasFileSysData
24} from "../../database/SqlLite.js";
25import {FileSysChartStruct} from "../../database/ui-worker/ProcedureWorkerFileSystem.js";
26import { ColorUtils } from "../trace/base/ColorUtils.js";
27
28export class SpFileSystemChart {
29    private trace: SpSystemTrace;
30    static hoverFileSysStruct: FileSysChartStruct | undefined;
31
32    constructor(trace: SpSystemTrace) {
33        this.trace = trace;
34    }
35
36    async init() {
37        let sys = await hasFileSysData();
38        if(sys.length > 0){
39            let fsCount = sys[0]['fsCount'] ?? 0;
40            let vmCount = sys[0]['vmCount'] ?? 0;
41            let ioCount = sys[0]['ioCount'] ?? 0;
42            if(sys && sys.length > 0 && (fsCount > 0 || vmCount > 0 || ioCount > 0)){
43                let folder = await this.initFolder();
44                await this.initFileCallchain()
45                if(fsCount > 0){
46                    await this.initLogicalRead(folder);
47                    await this.initLogicalWrite(folder);
48                }
49                if(vmCount > 0){
50                    await this.initVirtualMemoryTrace(folder);
51                }
52            }
53        }
54    }
55
56    async initFileCallchain(){
57        return new Promise<any>((resolve, reject) => {
58            procedurePool.submitWithName("logic0","fileSystem-init",SpSystemTrace.DATA_DICT,undefined,(res:any)=>{
59                resolve(res)
60            })
61        })
62    }
63
64    async initFolder():Promise<TraceRow<any>>{
65        let folder = new TraceRow();
66        folder.rowId = `FileSystem`;
67        folder.index = 0;
68        folder.rowType = TraceRow.ROW_TYPE_FILE_SYSTEM_GROUP
69        folder.rowParentId = '';
70        folder.folder = true;
71        folder.name = `EBPF` ;/* & I/O Latency */
72        folder.supplier = () => new Promise<Array<any>>((resolve) => resolve([]));
73        folder.favoriteChangeHandler = this.trace.favoriteChangeHandler;
74        folder.selectChangeHandler = this.trace.selectChangeHandler;
75        folder.onThreadHandler = (useCache) => {
76            procedurePool.submitWithName(`process${folder.index}`, `${TraceRow.ROW_TYPE_FILE_SYSTEM_GROUP}`, folder.buildArgs({
77                flagMoveInfo: this.trace.hoverFlag,
78                flagSelectedInfo: this.trace.selectFlag,
79                useCache: useCache,
80                scale: TraceRow.range?.scale || 50,
81            }), !folder.isTransferCanvas ? folder.offscreen[0] : undefined, (res: any) => {
82                folder.must = false;
83            })
84            folder.isTransferCanvas = true;
85        }
86        this.trace.rowsEL?.appendChild(folder)
87        return folder;
88    }
89
90    async initLogicalRead(folder:TraceRow<any>){
91        let row = new TraceRow();
92        row.rowId = `FileSystemLogicalRead`;
93        row.index = 1;
94        row.rowType = TraceRow.ROW_TYPE_FILE_SYSTEM
95        row.rowParentId = folder.rowId;
96        row.rowHidden = !folder.expansion
97        row.rangeSelect = true;
98        row.isHover = true;
99        row.style.height = '40px'
100        row.style.width = `100%`;
101        row.setAttribute('children', '');
102        row.name = `FileSystem Logical Read`;
103        row.supplier = () => getFileSysChartDataByType(2);
104        row.favoriteChangeHandler = this.trace.favoriteChangeHandler;
105        row.selectChangeHandler = this.trace.selectChangeHandler;
106        row.onThreadHandler = (useCache) => {
107            procedurePool.submitWithName(`process${(row.index) % procedurePool.processLen.length}`, `${TraceRow.ROW_TYPE_FILE_SYSTEM}-logical-read`, row.buildArgs({
108                flagMoveInfo: this.trace.hoverFlag,
109                flagSelectedInfo: this.trace.selectFlag,
110                useCache: useCache,
111                chartColor:ColorUtils.MD_PALETTE[0],
112                lineColor: row.getLineColor(),
113                scale: TraceRow.range?.scale || 50,
114            }), row.getTransferArray(), (res: any,hover: any) => {
115                row.must = false;
116                if (row.isHover) {
117                    SpFileSystemChart.hoverFileSysStruct = hover;
118                }
119            })
120            row.isTransferCanvas = true;
121        }
122        this.trace.rowsEL?.appendChild(row)
123    }
124
125    async initLogicalWrite(folder:TraceRow<any>){
126        let row = new TraceRow();
127        row.rowId = `FileSystemLogicalWrite`;
128        row.index = 2;
129        row.rowType = TraceRow.ROW_TYPE_FILE_SYSTEM
130        row.rowParentId = folder.rowId;
131        row.rowHidden = !folder.expansion;
132        row.rangeSelect = true;
133        row.isHover = true;
134        row.style.height = '40px'
135        row.style.width = `100%`;
136        row.setAttribute('children', '');
137        row.name = `FileSystem Logical Write`;
138        row.supplier = () => getFileSysChartDataByType(3);
139        row.favoriteChangeHandler = this.trace.favoriteChangeHandler;
140        row.selectChangeHandler = this.trace.selectChangeHandler;
141        row.onThreadHandler = (useCache) => {
142            procedurePool.submitWithName(`process${(row.index) % procedurePool.processLen.length}`, `${TraceRow.ROW_TYPE_FILE_SYSTEM}-logical-write`, row.buildArgs({
143                flagMoveInfo: this.trace.hoverFlag,
144                flagSelectedInfo: this.trace.selectFlag,
145                useCache: useCache,
146                lineColor: row.getLineColor(),
147                chartColor:ColorUtils.MD_PALETTE[8],
148                scale: TraceRow.range?.scale || 50,
149            }),  row.getTransferArray(), (res: any,hover: any) => {
150                row.must = false;
151                if (row.isHover) {
152                    SpFileSystemChart.hoverFileSysStruct = hover;
153                }
154            })
155            row.isTransferCanvas = true;
156        }
157        this.trace.rowsEL?.appendChild(row)
158    }
159
160    async initDiskIOLatency(folder:TraceRow<any>){
161        let row = new TraceRow();
162        row.rowId = `FileSystemDiskIOLatency`;
163        row.index = 4;
164        row.rowType = TraceRow.ROW_TYPE_FILE_SYSTEM
165        row.rowParentId = folder.rowId;
166        row.rowHidden = !folder.expansion
167        row.style.height = '40px'
168        row.style.width = `100%`;
169        row.setAttribute('children', '');
170        row.name = `Disk I/O Latency`;
171        row.supplier = () => getDiskIOLatencyChartDataByProcess(true,0,[2,3]);
172        row.favoriteChangeHandler = this.trace.favoriteChangeHandler;
173        row.selectChangeHandler = this.trace.selectChangeHandler;
174        row.onThreadHandler = (useCache) => {
175            procedurePool.submitWithName(`process${(row.index) % procedurePool.processLen.length}`, `${TraceRow.ROW_TYPE_FILE_SYSTEM}-disk-io`, row.buildArgs({
176                flagMoveInfo: this.trace.hoverFlag,
177                flagSelectedInfo: this.trace.selectFlag,
178                chartColor:ColorUtils.MD_PALETTE[0],
179                useCache: useCache,
180                scale: TraceRow.range?.scale || 50,
181            }),  row.getTransferArray(), (res: any,hover: any) => {
182                row.must = false;
183                if (row.isHover) {
184                    SpFileSystemChart.hoverFileSysStruct = hover;
185                }
186            })
187            row.isTransferCanvas = true;
188        }
189        this.trace.rowsEL?.appendChild(row)
190    }
191
192    async initProcessDiskIOLatency(folder:TraceRow<any>){
193        let processes = await getDiskIOProcess() || [];
194        for (let i = 0,len = processes.length; i < len; i++) {
195            let process = processes[i];
196            let rowRead = new TraceRow();
197            rowRead.index = 5 + 2 * i;
198            rowRead.rowId = `FileSystemDiskIOLatency-read-${process['ipid']}`;
199            rowRead.rowType = TraceRow.ROW_TYPE_FILE_SYSTEM
200            rowRead.rowParentId = folder.rowId;
201            rowRead.rowHidden = !folder.expansion
202            rowRead.style.height = '40px'
203            rowRead.style.width = `100%`;
204            rowRead.setAttribute('children', '');
205            rowRead.name = `${process['name'] ?? 'Process'}(${process['pid']}) Max Read Latency`;
206            rowRead.supplier = () => getDiskIOLatencyChartDataByProcess(false,process['ipid'],[2]);
207            rowRead.favoriteChangeHandler = this.trace.favoriteChangeHandler;
208            rowRead.selectChangeHandler = this.trace.selectChangeHandler;
209            rowRead.onThreadHandler = (useCache) => {
210                procedurePool.submitWithName(`process${(rowRead.index) % procedurePool.processLen.length}`,
211                    `${TraceRow.ROW_TYPE_FILE_SYSTEM}-disk-io-process-read-${process['pid']}`, rowRead.buildArgs({
212                    flagMoveInfo: this.trace.hoverFlag,
213                    flagSelectedInfo: this.trace.selectFlag,
214                    chartColor:ColorUtils.MD_PALETTE[0],
215                    useCache: useCache,
216                    scale: TraceRow.range?.scale || 50,
217                }),  rowRead.getTransferArray(), (res: any,hover: any) => {
218                    rowRead.must = false;
219                    if (rowRead.isHover) {
220                        SpFileSystemChart.hoverFileSysStruct = hover;
221                    }
222                })
223                rowRead.isTransferCanvas = true;
224            }
225            this.trace.rowsEL?.appendChild(rowRead)
226            let rowWrite = new TraceRow();
227            rowWrite.index = 5 + 2 * i + 1;
228            rowWrite.rowId = `FileSystemDiskIOLatency-write-${process['ipid']}`;
229            rowWrite.rowType = TraceRow.ROW_TYPE_FILE_SYSTEM
230            rowWrite.rowParentId = folder.rowId;
231            rowWrite.rowHidden = !folder.expansion
232            rowWrite.style.height = '40px'
233            rowWrite.style.width = `100%`;
234            rowWrite.setAttribute('children', '');
235            rowWrite.name = `${process['name'] ?? 'Process'}(${process['pid']}) Max Write Latency`;
236            rowWrite.supplier = () => getDiskIOLatencyChartDataByProcess(false,process['ipid'],[3]);
237            rowWrite.favoriteChangeHandler = this.trace.favoriteChangeHandler;
238            rowWrite.selectChangeHandler = this.trace.selectChangeHandler;
239            rowWrite.onThreadHandler = (useCache) => {
240                procedurePool.submitWithName(`process${(rowWrite.index) % procedurePool.processLen.length}`,
241                    `${TraceRow.ROW_TYPE_FILE_SYSTEM}-disk-io-process-write-${process['pid']}`, rowWrite.buildArgs({
242                    flagMoveInfo: this.trace.hoverFlag,
243                    flagSelectedInfo: this.trace.selectFlag,
244                    chartColor:ColorUtils.MD_PALETTE[8],
245                    useCache: useCache,
246                    scale: TraceRow.range?.scale || 50,
247                }),  rowWrite.getTransferArray(), (res: any,hover: any) => {
248                    rowWrite.must = false;
249                    if (rowWrite.isHover) {
250                        SpFileSystemChart.hoverFileSysStruct = hover;
251                    }
252                })
253                rowWrite.isTransferCanvas = true;
254            }
255            this.trace.rowsEL?.appendChild(rowWrite)
256        }
257    }
258
259    async initVirtualMemoryTrace(folder:TraceRow<any>){
260        let row = new TraceRow();
261        row.rowId = `FileSystemVirtualMemory`;
262        row.index = 3;
263        row.rowType = TraceRow.ROW_TYPE_FILE_SYSTEM
264        row.rowParentId = folder.rowId;
265        row.rowHidden = !folder.expansion
266        row.rangeSelect = true;
267        row.style.height = '40px'
268        row.style.width = `100%`;
269        row.setAttribute('children', '');
270        row.name = `Virtual Memory Trace`;
271        row.supplier = () => getFileSysVirtualMemoryChartData();
272        row.favoriteChangeHandler = this.trace.favoriteChangeHandler;
273        row.selectChangeHandler = this.trace.selectChangeHandler;
274        row.onThreadHandler = (useCache) => {
275            procedurePool.submitWithName(`process${(row.index) % procedurePool.processLen.length}`, `${TraceRow.ROW_TYPE_FILE_SYSTEM}-virtual-memory`, row.buildArgs({
276                flagMoveInfo: this.trace.hoverFlag,
277                flagSelectedInfo: this.trace.selectFlag,
278                chartColor:ColorUtils.MD_PALETTE[0],
279                useCache: useCache,
280                scale: TraceRow.range?.scale || 50,
281            }),  row.getTransferArray(), (res: any,hover: any) => {
282                row.must = false;
283                if (row.isHover) {
284                    SpFileSystemChart.hoverFileSysStruct = hover;
285                }
286            })
287            row.isTransferCanvas = true;
288        }
289        this.trace.rowsEL?.appendChild(row)
290    }
291}