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