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