• 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 {BaseStruct} from "./ProcedureWorkerCommon.js";
17
18export function hiPerfCpu(arr: Array<any>, arr2: any, type: string, res: Array<any>, startNS: number, endNS: number, totalNS: number, frame: any, groupBy10MS: boolean, maxCpu: number | undefined, intervalPerf: number, use: boolean) {
19    if (use && res.length > 0 && !groupBy10MS) {
20        let pns = (endNS - startNS) / frame.width;
21        let y = frame.y;
22        for (let i = 0; i < res.length; i++) {
23            let it = res[i];
24            if((it.startNS || 0) + (it.dur || 0) > startNS && (it.startNS || 0) < endNS){
25                if (!it.frame) {
26                    it.frame = {};
27                    it.frame.y = y;
28                }
29                it.frame.height = it.height;
30                HiPerfCpuStruct.setFrame(it, pns, startNS, endNS, frame);
31            }else{
32                it.frame = null;
33            }
34        }
35        return;
36    }
37    res.length = 0;
38    if (arr) {
39        let list: Array<any>;
40        if (groupBy10MS) {
41            if (arr2[type] && arr2[type].length > 0) {
42                list = arr2[type];
43            } else {
44                list = HiPerfCpuStruct.groupBy10MS(arr, maxCpu, intervalPerf);
45                arr2[type] = list;
46            }
47        } else {
48            list = arr;
49        }
50        let pns = (endNS - startNS) / frame.width;
51        let y = frame.y;
52
53        let groups = list.filter(it => (it.startNS || 0) + (it.dur || 0) > startNS && (it.startNS || 0) < endNS).map(it => {
54            if (!it.frame) {
55                it.frame = {};
56                it.frame.y = y;
57            }
58            it.frame.height = it.height;
59            HiPerfCpuStruct.setFrame(it, pns, startNS, endNS, frame);
60            return it;
61        }).reduce((pre, current, index, arr) => {
62            if (!pre[`${current.frame.x}`]) {
63                pre[`${current.frame.x}`] = [];
64                pre[`${current.frame.x}`].push(current);
65                if (groupBy10MS) {
66                    res.push(current);
67                } else {
68                    if (res.length == 0) {
69                        res.push(current);
70                    }
71                    if (res[res.length - 1] && Math.abs(current.frame.x - res[res.length - 1].frame.x) > 4) {
72                        res.push(current);
73                    }
74                }
75            }
76            return pre;
77        }, {});
78    }
79}
80
81export class HiPerfCpuStruct extends BaseStruct {
82    static hoverStruct: HiPerfCpuStruct | undefined;
83    static selectStruct: HiPerfCpuStruct | undefined;
84    static path = new Path2D('M 100,100 h 50 v 50 h 50');
85    id: number | undefined;
86    sample_id: number | undefined;
87    timestamp: number | undefined;
88    thread_id: number | undefined;
89    event_count: number | undefined;
90    event_type_id: number | undefined;
91    cpu_id: number | undefined;
92    thread_state: string | undefined;
93    //------------------------------------------------------
94    startNS: number | undefined;
95    endNS: number | undefined;
96    dur: number | undefined;
97    height: number | undefined;
98    cpu: number | undefined;
99
100    static draw(ctx: CanvasRenderingContext2D, path: Path2D, data: HiPerfCpuStruct, groupBy10MS: boolean) {
101        if (data.frame) {
102            if (groupBy10MS) {
103                let width = data.frame.width;
104                path.rect(data.frame.x, 40 - (data.height || 0), width, data.height || 0)
105            } else {
106                path.moveTo(data.frame.x + 7, 20);
107                HiPerfCpuStruct.drawRoundRectPath(path, data.frame.x - 7, 20 - 7, 14, 14, 3)
108                path.moveTo(data.frame.x, 27);
109                path.lineTo(data.frame.x, 33);
110            }
111        }
112    }
113
114    static drawRoundRectPath(cxt: Path2D, x: number, y: number, width: number, height: number, radius: number) {
115        cxt.arc(x + width - radius, y + height - radius, radius, 0, Math.PI / 2);
116        cxt.lineTo(x + radius, y + height);
117        cxt.arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI);
118        cxt.lineTo(x + 0, y + radius);
119        cxt.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
120        cxt.lineTo(x + width - radius, y + 0);
121        cxt.arc(x + width - radius, y + radius, radius, Math.PI * 3 / 2, Math.PI * 2);
122        cxt.lineTo(x + width, y + height - radius);
123        cxt.moveTo(x + width / 3, y + height / 5);
124        cxt.lineTo(x + width / 3, y + height / 5 * 4);
125        cxt.moveTo(x + width / 3, y + height / 5);
126        cxt.bezierCurveTo(x + width / 3 + 7, y + height / 5 - 2, x + width / 3 + 7, y + height / 5 + 6, x + width / 3, y + height / 5 + 4);
127    }
128
129    static setFrame(node: any, pns: number, startNS: number, endNS: number, frame: any) {
130        if ((node.startNS || 0) < startNS) {
131            node.frame.x = 0;
132        } else {
133            node.frame.x = Math.floor(((node.startNS || 0) - startNS) / pns);
134        }
135        if ((node.startNS || 0) + (node.dur || 0) > endNS) {
136            node.frame.width = frame.width - node.frame.x;
137        } else {
138            node.frame.width = Math.ceil(((node.startNS || 0) + (node.dur || 0) - startNS) / pns - node.frame.x);
139        }
140        if (node.frame.width < 1) {
141            node.frame.width = 1;
142        }
143    }
144
145    static groupBy10MS(array: Array<any>, maxCpu: number | undefined, intervalPerf: number): Array<any> {
146        let obj = array.map(it => {
147            it.timestamp_group = Math.trunc(it.startNS / 1_000_000_0) * 1_000_000_0;
148            return it;
149        }).reduce((pre, current) => {
150            (pre[current["timestamp_group"]] = pre[current["timestamp_group"]] || []).push(current);
151            return pre;
152        }, {});
153        let arr: any[] = [];
154        for (let aKey in obj) {
155            let ns = parseInt(aKey);
156            let height: number = 0;
157            if (maxCpu != undefined) {
158                height = Math.floor(obj[aKey].length / (10 / intervalPerf) / maxCpu * 40);
159            } else {
160                height = Math.floor(obj[aKey].length / (10 / intervalPerf) * 40);
161            }
162            arr.push({
163                startNS: ns,
164                dur: 1_000_000_0,
165                height: height,
166            })
167        }
168        return arr;
169    }
170}