1fb726d48Sopenharmony_ci// Copyright (c) 2021 Huawei Device Co., Ltd. 2fb726d48Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 3fb726d48Sopenharmony_ci// you may not use this file except in compliance with the License. 4fb726d48Sopenharmony_ci// You may obtain a copy of the License at 5fb726d48Sopenharmony_ci// 6fb726d48Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 7fb726d48Sopenharmony_ci// 8fb726d48Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 9fb726d48Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 10fb726d48Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11fb726d48Sopenharmony_ci// See the License for the specific language governing permissions and 12fb726d48Sopenharmony_ci// limitations under the License. 13fb726d48Sopenharmony_ci 14fb726d48Sopenharmony_ciimport { TraficEnum } from '../utils/QueryEnum'; 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ciinterface HiPerfSampleType { 17fb726d48Sopenharmony_ci callchainId: number; 18fb726d48Sopenharmony_ci startTs: number; 19fb726d48Sopenharmony_ci eventCount: number; 20fb726d48Sopenharmony_ci threadId: number; 21fb726d48Sopenharmony_ci cpuId: number; 22fb726d48Sopenharmony_ci eventTypeId: number; 23fb726d48Sopenharmony_ci} 24fb726d48Sopenharmony_ci 25fb726d48Sopenharmony_ciconst dataCache: { 26fb726d48Sopenharmony_ci startTs: Array<number>; 27fb726d48Sopenharmony_ci dur: Array<number>; 28fb726d48Sopenharmony_ci depth: Array<number>; 29fb726d48Sopenharmony_ci eventCount: Array<number>; 30fb726d48Sopenharmony_ci symbolId: Array<number>; 31fb726d48Sopenharmony_ci fileId: Array<number>; 32fb726d48Sopenharmony_ci callchainId: Array<number>; 33fb726d48Sopenharmony_ci selfDur: Array<number>; 34fb726d48Sopenharmony_ci name: Array<number>; 35fb726d48Sopenharmony_ci callstack: Map<string, unknown>; 36fb726d48Sopenharmony_ci sampleList: Array<HiPerfSampleType>; 37fb726d48Sopenharmony_ci maxDepth: number; 38fb726d48Sopenharmony_ci} = { 39fb726d48Sopenharmony_ci callstack: new Map<string, unknown>(), 40fb726d48Sopenharmony_ci sampleList: [], 41fb726d48Sopenharmony_ci maxDepth: 1, 42fb726d48Sopenharmony_ci startTs: [], 43fb726d48Sopenharmony_ci dur: [], 44fb726d48Sopenharmony_ci depth: [], 45fb726d48Sopenharmony_ci eventCount: [], 46fb726d48Sopenharmony_ci symbolId: [], 47fb726d48Sopenharmony_ci fileId: [], 48fb726d48Sopenharmony_ci callchainId: [], 49fb726d48Sopenharmony_ci selfDur: [], 50fb726d48Sopenharmony_ci name: [], 51fb726d48Sopenharmony_ci}; 52fb726d48Sopenharmony_ci 53fb726d48Sopenharmony_ciexport const chartHiperfCallChartDataSql = (args: unknown): string => { 54fb726d48Sopenharmony_ci const sql = ` 55fb726d48Sopenharmony_ci select callchain_id as callchainId, 56fb726d48Sopenharmony_ci timestamp_trace - ${ 57fb726d48Sopenharmony_ci // @ts-ignore 58fb726d48Sopenharmony_ci args.recordStartNS 59fb726d48Sopenharmony_ci } as startTs, 60fb726d48Sopenharmony_ci event_count as eventCount, 61fb726d48Sopenharmony_ci A.thread_id as threadId, 62fb726d48Sopenharmony_ci cpu_id as cpuId, 63fb726d48Sopenharmony_ci event_type_id as eventTypeId 64fb726d48Sopenharmony_ci from perf_sample A 65fb726d48Sopenharmony_ci where callchain_id != -1 and A.thread_id != 0 66fb726d48Sopenharmony_ci order by cpuId, startTs`; 67fb726d48Sopenharmony_ci return sql; 68fb726d48Sopenharmony_ci}; 69fb726d48Sopenharmony_ci 70fb726d48Sopenharmony_ciexport function hiPerfCallChartDataHandler(data: unknown, proc: Function): void { 71fb726d48Sopenharmony_ci // @ts-ignore 72fb726d48Sopenharmony_ci if (data.params.isCache) { 73fb726d48Sopenharmony_ci // @ts-ignore 74fb726d48Sopenharmony_ci let res: Array<unknown> = proc(chartHiperfCallChartDataSql(data.params)); 75fb726d48Sopenharmony_ci for (let i = 0; i < res.length; i++) { 76fb726d48Sopenharmony_ci if (i > 0) { 77fb726d48Sopenharmony_ci // @ts-ignore 78fb726d48Sopenharmony_ci if (res[i].cpuId === res[i - 1].cpuId) { 79fb726d48Sopenharmony_ci // @ts-ignore 80fb726d48Sopenharmony_ci res[i - 1].dur = res[i].startTs - res[i - 1].startTs; 81fb726d48Sopenharmony_ci } else { 82fb726d48Sopenharmony_ci // @ts-ignore 83fb726d48Sopenharmony_ci res[i - 1].dur = data.params.recordEndNS - data.params.recordStartNS - res[i - 1].startTs; 84fb726d48Sopenharmony_ci } 85fb726d48Sopenharmony_ci } 86fb726d48Sopenharmony_ci if (i === res.length - 1) { 87fb726d48Sopenharmony_ci // @ts-ignore 88fb726d48Sopenharmony_ci res[i].dur = data.params.recordEndNS - data.params.recordStartNS - res[i].startTs; 89fb726d48Sopenharmony_ci } 90fb726d48Sopenharmony_ci } 91fb726d48Sopenharmony_ci // @ts-ignore 92fb726d48Sopenharmony_ci dataCache.sampleList = res; 93fb726d48Sopenharmony_ci (self as unknown as Worker).postMessage( 94fb726d48Sopenharmony_ci { 95fb726d48Sopenharmony_ci len: 0, 96fb726d48Sopenharmony_ci // @ts-ignore 97fb726d48Sopenharmony_ci id: data.id, 98fb726d48Sopenharmony_ci // @ts-ignore 99fb726d48Sopenharmony_ci action: data.action, 100fb726d48Sopenharmony_ci results: 'ok', 101fb726d48Sopenharmony_ci }, 102fb726d48Sopenharmony_ci [] 103fb726d48Sopenharmony_ci ); 104fb726d48Sopenharmony_ci } else { 105fb726d48Sopenharmony_ci let res: Array<unknown> = []; 106fb726d48Sopenharmony_ci // @ts-ignore 107fb726d48Sopenharmony_ci if (!data.params.isComplete) { 108fb726d48Sopenharmony_ci res = dataCache.sampleList.filter((it) => { 109fb726d48Sopenharmony_ci // @ts-ignore 110fb726d48Sopenharmony_ci let cpuThreadFilter = data.params.type === 0 ? it.cpuId === data.params.id : it.threadId === data.params.id; 111fb726d48Sopenharmony_ci // @ts-ignore 112fb726d48Sopenharmony_ci let eventTypeFilter = data.params.eventTypeId === -2 ? true : it.eventTypeId === data.params.eventTypeId; 113fb726d48Sopenharmony_ci return cpuThreadFilter && eventTypeFilter; 114fb726d48Sopenharmony_ci }); 115fb726d48Sopenharmony_ci } 116fb726d48Sopenharmony_ci // @ts-ignore 117fb726d48Sopenharmony_ci arrayBufferHandler(data, res, true, !data.params.isComplete); 118fb726d48Sopenharmony_ci } 119fb726d48Sopenharmony_ci} 120fb726d48Sopenharmony_ci 121fb726d48Sopenharmony_ciexport function hiPerfCallStackCacheHandler(data: unknown, proc: Function): void { 122fb726d48Sopenharmony_ci // @ts-ignore 123fb726d48Sopenharmony_ci if (data.params.isCache) { 124fb726d48Sopenharmony_ci hiPerfCallChartClearCache(true); 125fb726d48Sopenharmony_ci arrayBufferCallStackHandler(data, proc(hiPerfCallStackDataCacheSql())); 126fb726d48Sopenharmony_ci } 127fb726d48Sopenharmony_ci} 128fb726d48Sopenharmony_ci 129fb726d48Sopenharmony_cifunction arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean, loadData: boolean): void { 130fb726d48Sopenharmony_ci if (loadData) { 131fb726d48Sopenharmony_ci // @ts-ignore 132fb726d48Sopenharmony_ci if (data.params.type !== 0) { 133fb726d48Sopenharmony_ci // @ts-ignore 134fb726d48Sopenharmony_ci res.sort((a, b) => a.startTs - b.startTs); 135fb726d48Sopenharmony_ci for (let i = 0; i < res.length; i++) { 136fb726d48Sopenharmony_ci if (i < res.length - 1) { 137fb726d48Sopenharmony_ci // @ts-ignore 138fb726d48Sopenharmony_ci res[i].dur = res[i + 1].startTs - res[i].startTs; 139fb726d48Sopenharmony_ci } else { 140fb726d48Sopenharmony_ci // @ts-ignore 141fb726d48Sopenharmony_ci res[i].dur = data.params.endNS - data.params.startNS - res[i].startTs; 142fb726d48Sopenharmony_ci } 143fb726d48Sopenharmony_ci } 144fb726d48Sopenharmony_ci } 145fb726d48Sopenharmony_ci // @ts-ignore 146fb726d48Sopenharmony_ci let result = combinePerfSampleByCallChainId(res, data.params); 147fb726d48Sopenharmony_ci hiPerfCallChartClearCache(false); 148fb726d48Sopenharmony_ci const getArrayData = (combineData: Array<unknown>): void => { 149fb726d48Sopenharmony_ci for (let item of combineData) { 150fb726d48Sopenharmony_ci // @ts-ignore 151fb726d48Sopenharmony_ci if (item.depth > -1) { 152fb726d48Sopenharmony_ci // @ts-ignore 153fb726d48Sopenharmony_ci dataCache.startTs.push(item.startTime); 154fb726d48Sopenharmony_ci // @ts-ignore 155fb726d48Sopenharmony_ci dataCache.dur.push(item.totalTime); 156fb726d48Sopenharmony_ci // @ts-ignore 157fb726d48Sopenharmony_ci dataCache.depth.push(item.depth); 158fb726d48Sopenharmony_ci // @ts-ignore 159fb726d48Sopenharmony_ci dataCache.eventCount.push(item.eventCount); 160fb726d48Sopenharmony_ci // @ts-ignore 161fb726d48Sopenharmony_ci dataCache.symbolId.push(item.symbolId); 162fb726d48Sopenharmony_ci // @ts-ignore 163fb726d48Sopenharmony_ci dataCache.fileId.push(item.fileId); 164fb726d48Sopenharmony_ci // @ts-ignore 165fb726d48Sopenharmony_ci dataCache.callchainId.push(item.callchainId); 166fb726d48Sopenharmony_ci // @ts-ignore 167fb726d48Sopenharmony_ci dataCache.name.push(item.name); 168fb726d48Sopenharmony_ci // @ts-ignore 169fb726d48Sopenharmony_ci let self = item.totalTime || 0; 170fb726d48Sopenharmony_ci // @ts-ignore 171fb726d48Sopenharmony_ci if (item.children) { 172fb726d48Sopenharmony_ci // @ts-ignore 173fb726d48Sopenharmony_ci (item.children as Array<unknown>).forEach((child) => { 174fb726d48Sopenharmony_ci // @ts-ignore 175fb726d48Sopenharmony_ci self -= child.totalTime; 176fb726d48Sopenharmony_ci }); 177fb726d48Sopenharmony_ci } 178fb726d48Sopenharmony_ci dataCache.selfDur.push(self); 179fb726d48Sopenharmony_ci } 180fb726d48Sopenharmony_ci // @ts-ignore 181fb726d48Sopenharmony_ci if (item.depth + 1 > dataCache.maxDepth) { 182fb726d48Sopenharmony_ci // @ts-ignore 183fb726d48Sopenharmony_ci dataCache.maxDepth = item.depth + 1; 184fb726d48Sopenharmony_ci } 185fb726d48Sopenharmony_ci // @ts-ignore 186fb726d48Sopenharmony_ci if (item.children && item.children.length > 0) { 187fb726d48Sopenharmony_ci // @ts-ignore 188fb726d48Sopenharmony_ci getArrayData(item.children); 189fb726d48Sopenharmony_ci } 190fb726d48Sopenharmony_ci } 191fb726d48Sopenharmony_ci }; 192fb726d48Sopenharmony_ci getArrayData(result); 193fb726d48Sopenharmony_ci } 194fb726d48Sopenharmony_ci setTimeout((): void => { 195fb726d48Sopenharmony_ci arrayBufferCallback(data, transfer); 196fb726d48Sopenharmony_ci }, 150); 197fb726d48Sopenharmony_ci} 198fb726d48Sopenharmony_ci 199fb726d48Sopenharmony_cifunction arrayBufferCallback(data: unknown, transfer: boolean): void { 200fb726d48Sopenharmony_ci // @ts-ignore 201fb726d48Sopenharmony_ci let params = data.params; 202fb726d48Sopenharmony_ci let dataFilter = filterPerfCallChartData(params.startNS, params.endNS, params.totalNS, params.frame, params.expand); 203fb726d48Sopenharmony_ci let len = dataFilter.startTs.length; 204fb726d48Sopenharmony_ci let perfCallChart = new PerfCallChart(len); 205fb726d48Sopenharmony_ci for (let i = 0; i < len; i++) { 206fb726d48Sopenharmony_ci perfCallChart.startTs[i] = dataFilter.startTs[i]; 207fb726d48Sopenharmony_ci perfCallChart.dur[i] = dataFilter.dur[i]; 208fb726d48Sopenharmony_ci perfCallChart.depth[i] = dataFilter.depth[i]; 209fb726d48Sopenharmony_ci perfCallChart.eventCount[i] = dataFilter.eventCount[i]; 210fb726d48Sopenharmony_ci perfCallChart.symbolId[i] = dataFilter.symbolId[i]; 211fb726d48Sopenharmony_ci perfCallChart.fileId[i] = dataFilter.fileId[i]; 212fb726d48Sopenharmony_ci perfCallChart.callchainId[i] = dataFilter.callchainId[i]; 213fb726d48Sopenharmony_ci perfCallChart.selfDur[i] = dataFilter.selfDur[i]; 214fb726d48Sopenharmony_ci perfCallChart.name[i] = dataFilter.name[i]; 215fb726d48Sopenharmony_ci } 216fb726d48Sopenharmony_ci postPerfCallChartMessage(data, transfer, perfCallChart, len); 217fb726d48Sopenharmony_ci} 218fb726d48Sopenharmony_cifunction postPerfCallChartMessage(data: unknown, transfer: boolean, perfCallChart: PerfCallChart, len: number): void { 219fb726d48Sopenharmony_ci (self as unknown as Worker).postMessage( 220fb726d48Sopenharmony_ci { 221fb726d48Sopenharmony_ci // @ts-ignore 222fb726d48Sopenharmony_ci id: data.id, 223fb726d48Sopenharmony_ci // @ts-ignore 224fb726d48Sopenharmony_ci action: data.action, 225fb726d48Sopenharmony_ci results: transfer 226fb726d48Sopenharmony_ci ? { 227fb726d48Sopenharmony_ci startTs: perfCallChart.startTs.buffer, 228fb726d48Sopenharmony_ci dur: perfCallChart.dur.buffer, 229fb726d48Sopenharmony_ci depth: perfCallChart.depth.buffer, 230fb726d48Sopenharmony_ci callchainId: perfCallChart.callchainId.buffer, 231fb726d48Sopenharmony_ci eventCount: perfCallChart.eventCount.buffer, 232fb726d48Sopenharmony_ci symbolId: perfCallChart.symbolId.buffer, 233fb726d48Sopenharmony_ci fileId: perfCallChart.fileId.buffer, 234fb726d48Sopenharmony_ci selfDur: perfCallChart.selfDur.buffer, 235fb726d48Sopenharmony_ci name: perfCallChart.name.buffer, 236fb726d48Sopenharmony_ci maxDepth: dataCache.maxDepth, 237fb726d48Sopenharmony_ci } 238fb726d48Sopenharmony_ci : {}, 239fb726d48Sopenharmony_ci len: len, 240fb726d48Sopenharmony_ci }, 241fb726d48Sopenharmony_ci transfer 242fb726d48Sopenharmony_ci ? [ 243fb726d48Sopenharmony_ci perfCallChart.startTs.buffer, 244fb726d48Sopenharmony_ci perfCallChart.dur.buffer, 245fb726d48Sopenharmony_ci perfCallChart.depth.buffer, 246fb726d48Sopenharmony_ci perfCallChart.callchainId.buffer, 247fb726d48Sopenharmony_ci perfCallChart.eventCount.buffer, 248fb726d48Sopenharmony_ci perfCallChart.symbolId.buffer, 249fb726d48Sopenharmony_ci perfCallChart.fileId.buffer, 250fb726d48Sopenharmony_ci perfCallChart.selfDur.buffer, 251fb726d48Sopenharmony_ci perfCallChart.name.buffer, 252fb726d48Sopenharmony_ci ] 253fb726d48Sopenharmony_ci : [] 254fb726d48Sopenharmony_ci ); 255fb726d48Sopenharmony_ci} 256fb726d48Sopenharmony_ci 257fb726d48Sopenharmony_ciexport function filterPerfCallChartData( 258fb726d48Sopenharmony_ci startNS: number, 259fb726d48Sopenharmony_ci endNS: number, 260fb726d48Sopenharmony_ci totalNS: number, 261fb726d48Sopenharmony_ci frame: unknown, 262fb726d48Sopenharmony_ci expand: boolean 263fb726d48Sopenharmony_ci): DataSource { 264fb726d48Sopenharmony_ci let dataSource = new DataSource(); 265fb726d48Sopenharmony_ci let data: unknown = {}; 266fb726d48Sopenharmony_ci dataCache.startTs.reduce((pre, current, index) => { 267fb726d48Sopenharmony_ci if ( 268fb726d48Sopenharmony_ci dataCache.dur[index] > 0 && 269fb726d48Sopenharmony_ci current + dataCache.dur[index] >= startNS && 270fb726d48Sopenharmony_ci current <= endNS && 271fb726d48Sopenharmony_ci ((!expand && dataCache.depth[index] === 0) || expand) 272fb726d48Sopenharmony_ci ) { 273fb726d48Sopenharmony_ci let x = 0; 274fb726d48Sopenharmony_ci if (current > startNS && current < endNS) { 275fb726d48Sopenharmony_ci x = Math.trunc(ns2x(current, startNS, endNS, totalNS, frame)); 276fb726d48Sopenharmony_ci } else { 277fb726d48Sopenharmony_ci x = 0; 278fb726d48Sopenharmony_ci } 279fb726d48Sopenharmony_ci let key = `${x}-${dataCache.depth[index]}`; 280fb726d48Sopenharmony_ci // @ts-ignore 281fb726d48Sopenharmony_ci let preIndex = pre[key]; 282fb726d48Sopenharmony_ci if (preIndex !== undefined) { 283fb726d48Sopenharmony_ci // @ts-ignore 284fb726d48Sopenharmony_ci pre[key] = dataCache.dur[preIndex] > dataCache.dur[index] ? preIndex : index; 285fb726d48Sopenharmony_ci } else { 286fb726d48Sopenharmony_ci // @ts-ignore 287fb726d48Sopenharmony_ci pre[key] = index; 288fb726d48Sopenharmony_ci } 289fb726d48Sopenharmony_ci } 290fb726d48Sopenharmony_ci return pre; 291fb726d48Sopenharmony_ci }, data); 292fb726d48Sopenharmony_ci setDataSource(data, dataSource); 293fb726d48Sopenharmony_ci return dataSource; 294fb726d48Sopenharmony_ci} 295fb726d48Sopenharmony_cifunction setDataSource(data: unknown, dataSource: DataSource): void { 296fb726d48Sopenharmony_ci // @ts-ignore 297fb726d48Sopenharmony_ci Reflect.ownKeys(data).map((kv: string | symbol): void => { 298fb726d48Sopenharmony_ci // @ts-ignore 299fb726d48Sopenharmony_ci let index = data[kv as string] as number; 300fb726d48Sopenharmony_ci // @ts-ignore 301fb726d48Sopenharmony_ci dataSource.startTs.push(dataCache.startTs[index]); 302fb726d48Sopenharmony_ci dataSource.dur.push(dataCache.dur[index]); 303fb726d48Sopenharmony_ci dataSource.depth.push(dataCache.depth[index]); 304fb726d48Sopenharmony_ci dataSource.eventCount.push(dataCache.eventCount[index]); 305fb726d48Sopenharmony_ci dataSource.symbolId.push(dataCache.symbolId[index]); 306fb726d48Sopenharmony_ci dataSource.fileId.push(dataCache.fileId[index]); 307fb726d48Sopenharmony_ci dataSource.callchainId.push(dataCache.callchainId[index]); 308fb726d48Sopenharmony_ci dataSource.selfDur.push(dataCache.selfDur[index]); 309fb726d48Sopenharmony_ci dataSource.name.push(dataCache.name[index]); 310fb726d48Sopenharmony_ci }); 311fb726d48Sopenharmony_ci} 312fb726d48Sopenharmony_ci// 将perf_sample表的数据根据callchain_id分组并赋值startTime,endTime等等 313fb726d48Sopenharmony_cifunction combinePerfSampleByCallChainId(sampleList: Array<unknown>, params: unknown): unknown[] { 314fb726d48Sopenharmony_ci return combineChartData( 315fb726d48Sopenharmony_ci sampleList.map((sample) => { 316fb726d48Sopenharmony_ci let perfSample: unknown = {}; 317fb726d48Sopenharmony_ci // @ts-ignore 318fb726d48Sopenharmony_ci perfSample.children = []; 319fb726d48Sopenharmony_ci // @ts-ignore 320fb726d48Sopenharmony_ci perfSample.children[0] = {}; 321fb726d48Sopenharmony_ci // @ts-ignore 322fb726d48Sopenharmony_ci perfSample.depth = -1; 323fb726d48Sopenharmony_ci // @ts-ignore 324fb726d48Sopenharmony_ci perfSample.callchainId = sample.callchainId; 325fb726d48Sopenharmony_ci // @ts-ignore 326fb726d48Sopenharmony_ci perfSample.threadId = sample.threadId; 327fb726d48Sopenharmony_ci // @ts-ignore 328fb726d48Sopenharmony_ci perfSample.id = sample.id; 329fb726d48Sopenharmony_ci // @ts-ignore 330fb726d48Sopenharmony_ci perfSample.cpuId = sample.cpuId; 331fb726d48Sopenharmony_ci // @ts-ignore 332fb726d48Sopenharmony_ci perfSample.startTime = sample.startTs; 333fb726d48Sopenharmony_ci // @ts-ignore 334fb726d48Sopenharmony_ci perfSample.endTime = sample.startTs + sample.dur; 335fb726d48Sopenharmony_ci // @ts-ignore 336fb726d48Sopenharmony_ci perfSample.totalTime = sample.dur; 337fb726d48Sopenharmony_ci // @ts-ignore 338fb726d48Sopenharmony_ci perfSample.eventCount = sample.eventCount; 339fb726d48Sopenharmony_ci return perfSample; 340fb726d48Sopenharmony_ci }), 341fb726d48Sopenharmony_ci params 342fb726d48Sopenharmony_ci ); 343fb726d48Sopenharmony_ci} 344fb726d48Sopenharmony_ci 345fb726d48Sopenharmony_cifunction combineChartData(samples: unknown, params: unknown): Array<unknown> { 346fb726d48Sopenharmony_ci let combineSample: unknown = []; 347fb726d48Sopenharmony_ci // 遍历sample表查到的数据,并且为其匹配相应的callchain数据 348fb726d48Sopenharmony_ci // @ts-ignore 349fb726d48Sopenharmony_ci for (let sample of samples) { 350fb726d48Sopenharmony_ci let stackTop = dataCache.callstack.get(`${sample.callchainId}-0`); 351fb726d48Sopenharmony_ci if (stackTop) { 352fb726d48Sopenharmony_ci let stackTopSymbol = JSON.parse(JSON.stringify(stackTop)); 353fb726d48Sopenharmony_ci stackTopSymbol.startTime = sample.startTime; 354fb726d48Sopenharmony_ci stackTopSymbol.endTime = sample.endTime; 355fb726d48Sopenharmony_ci stackTopSymbol.totalTime = sample.totalTime; 356fb726d48Sopenharmony_ci stackTopSymbol.threadId = sample.threadId; 357fb726d48Sopenharmony_ci stackTopSymbol.cpuId = sample.cpuId; 358fb726d48Sopenharmony_ci stackTopSymbol.eventCount = sample.eventCount; 359fb726d48Sopenharmony_ci setDur(stackTopSymbol); 360fb726d48Sopenharmony_ci sample.children = []; 361fb726d48Sopenharmony_ci sample.children.push(stackTopSymbol); 362fb726d48Sopenharmony_ci // 每一项都和combineSample对比 363fb726d48Sopenharmony_ci // @ts-ignore 364fb726d48Sopenharmony_ci if (combineSample.length === 0) { 365fb726d48Sopenharmony_ci // @ts-ignore 366fb726d48Sopenharmony_ci combineSample.push(sample); 367fb726d48Sopenharmony_ci } else { 368fb726d48Sopenharmony_ci // @ts-ignore 369fb726d48Sopenharmony_ci let pre = combineSample[combineSample.length - 1]; 370fb726d48Sopenharmony_ci // @ts-ignore 371fb726d48Sopenharmony_ci if (params.type === 0) { 372fb726d48Sopenharmony_ci if (pre.threadId === sample.threadId && pre.endTime === sample.startTime) { 373fb726d48Sopenharmony_ci // @ts-ignore 374fb726d48Sopenharmony_ci combinePerfCallData(combineSample[combineSample.length - 1], sample); 375fb726d48Sopenharmony_ci } else { 376fb726d48Sopenharmony_ci // @ts-ignore 377fb726d48Sopenharmony_ci combineSample.push(sample); 378fb726d48Sopenharmony_ci } 379fb726d48Sopenharmony_ci } else { 380fb726d48Sopenharmony_ci // @ts-ignore 381fb726d48Sopenharmony_ci combinePerfCallData(combineSample[combineSample.length - 1], sample); 382fb726d48Sopenharmony_ci } 383fb726d48Sopenharmony_ci } 384fb726d48Sopenharmony_ci } 385fb726d48Sopenharmony_ci } 386fb726d48Sopenharmony_ci // @ts-ignore 387fb726d48Sopenharmony_ci return combineSample; 388fb726d48Sopenharmony_ci} 389fb726d48Sopenharmony_ci 390fb726d48Sopenharmony_ci// 递归设置dur,startTime,endTime 391fb726d48Sopenharmony_cifunction setDur(data: unknown): void { 392fb726d48Sopenharmony_ci // @ts-ignore 393fb726d48Sopenharmony_ci if (data.children && data.children.length > 0) { 394fb726d48Sopenharmony_ci // @ts-ignore 395fb726d48Sopenharmony_ci data.children[0].totalTime = data.totalTime; 396fb726d48Sopenharmony_ci // @ts-ignore 397fb726d48Sopenharmony_ci data.children[0].startTime = data.startTime; 398fb726d48Sopenharmony_ci // @ts-ignore 399fb726d48Sopenharmony_ci data.children[0].endTime = data.endTime; 400fb726d48Sopenharmony_ci // @ts-ignore 401fb726d48Sopenharmony_ci data.children[0].threadId = data.threadId; 402fb726d48Sopenharmony_ci // @ts-ignore 403fb726d48Sopenharmony_ci data.children[0].cpuId = data.cpuId; 404fb726d48Sopenharmony_ci // @ts-ignore 405fb726d48Sopenharmony_ci data.children[0].eventCount = data.eventCount; 406fb726d48Sopenharmony_ci // @ts-ignore 407fb726d48Sopenharmony_ci setDur(data.children[0]); 408fb726d48Sopenharmony_ci } else { 409fb726d48Sopenharmony_ci return; 410fb726d48Sopenharmony_ci } 411fb726d48Sopenharmony_ci} 412fb726d48Sopenharmony_ci 413fb726d48Sopenharmony_ci// hiperf火焰图合并逻辑 414fb726d48Sopenharmony_cifunction combinePerfCallData(data1: unknown, data2: unknown): void { 415fb726d48Sopenharmony_ci if (fixMergeRuler(data1, data2)) { 416fb726d48Sopenharmony_ci // @ts-ignore 417fb726d48Sopenharmony_ci data1.endTime = data2.endTime; 418fb726d48Sopenharmony_ci // @ts-ignore 419fb726d48Sopenharmony_ci data1.totalTime = data1.endTime - data1.startTime; 420fb726d48Sopenharmony_ci // @ts-ignore 421fb726d48Sopenharmony_ci data1.eventCount += data2.eventCount; 422fb726d48Sopenharmony_ci // @ts-ignore 423fb726d48Sopenharmony_ci if (data1.children && data1.children.length > 0 && data2.children && data2.children.length > 0) { 424fb726d48Sopenharmony_ci // @ts-ignore 425fb726d48Sopenharmony_ci if (fixMergeRuler(data1.children[data1.children.length - 1], data2.children[0])) { 426fb726d48Sopenharmony_ci // @ts-ignore 427fb726d48Sopenharmony_ci combinePerfCallData(data1.children[data1.children.length - 1], data2.children[0]); 428fb726d48Sopenharmony_ci } else { 429fb726d48Sopenharmony_ci // @ts-ignore 430fb726d48Sopenharmony_ci if (data1.children[data1.children.length - 1].depth === data2.children[0].depth) { 431fb726d48Sopenharmony_ci // @ts-ignore 432fb726d48Sopenharmony_ci data1.children.push(data2.children[0]); 433fb726d48Sopenharmony_ci } 434fb726d48Sopenharmony_ci } 435fb726d48Sopenharmony_ci // @ts-ignore 436fb726d48Sopenharmony_ci } else if (data2.children && data2.children.length > 0 && (!data1.children || data1.children.length === 0)) { 437fb726d48Sopenharmony_ci // @ts-ignore 438fb726d48Sopenharmony_ci data1.endTime = data2.endTime; 439fb726d48Sopenharmony_ci // @ts-ignore 440fb726d48Sopenharmony_ci data1.totalTime = data1.endTime - data1.startTime; 441fb726d48Sopenharmony_ci // @ts-ignore 442fb726d48Sopenharmony_ci data1.children = []; 443fb726d48Sopenharmony_ci // @ts-ignore 444fb726d48Sopenharmony_ci data1.children.push(data2.children[0]); 445fb726d48Sopenharmony_ci } else { 446fb726d48Sopenharmony_ci } 447fb726d48Sopenharmony_ci } 448fb726d48Sopenharmony_ci return; 449fb726d48Sopenharmony_ci} 450fb726d48Sopenharmony_ci 451fb726d48Sopenharmony_ci/** 452fb726d48Sopenharmony_ci * 合并规则 453fb726d48Sopenharmony_ci * @param data1 454fb726d48Sopenharmony_ci * @param data2 455fb726d48Sopenharmony_ci */ 456fb726d48Sopenharmony_cifunction fixMergeRuler(data1: unknown, data2: unknown): boolean { 457fb726d48Sopenharmony_ci // @ts-ignore 458fb726d48Sopenharmony_ci return data1.depth === data2.depth && data1.name === data2.name; 459fb726d48Sopenharmony_ci} 460fb726d48Sopenharmony_ci 461fb726d48Sopenharmony_ciexport const hiPerfCallStackDataCacheSql = (): string => { 462fb726d48Sopenharmony_ci return `select c.callchain_id as callchainId, 463fb726d48Sopenharmony_ci c.file_id as fileId, 464fb726d48Sopenharmony_ci c.depth, 465fb726d48Sopenharmony_ci c.symbol_id as symbolId, 466fb726d48Sopenharmony_ci c.name 467fb726d48Sopenharmony_ci from perf_callchain c 468fb726d48Sopenharmony_ci where callchain_id != -1;`; 469fb726d48Sopenharmony_ci}; 470fb726d48Sopenharmony_ci 471fb726d48Sopenharmony_ciexport function hiPerfCallChartClearCache(clearStack: boolean): void { 472fb726d48Sopenharmony_ci if (clearStack) { 473fb726d48Sopenharmony_ci dataCache.callstack.clear(); 474fb726d48Sopenharmony_ci dataCache.sampleList.length = 0; 475fb726d48Sopenharmony_ci } 476fb726d48Sopenharmony_ci dataCache.startTs = []; 477fb726d48Sopenharmony_ci dataCache.dur = []; 478fb726d48Sopenharmony_ci dataCache.depth = []; 479fb726d48Sopenharmony_ci dataCache.eventCount = []; 480fb726d48Sopenharmony_ci dataCache.symbolId = []; 481fb726d48Sopenharmony_ci dataCache.fileId = []; 482fb726d48Sopenharmony_ci dataCache.callchainId = []; 483fb726d48Sopenharmony_ci dataCache.selfDur = []; 484fb726d48Sopenharmony_ci dataCache.name = []; 485fb726d48Sopenharmony_ci dataCache.maxDepth = 1; 486fb726d48Sopenharmony_ci} 487fb726d48Sopenharmony_ci 488fb726d48Sopenharmony_cifunction arrayBufferCallStackHandler(data: unknown, res: unknown[]): void { 489fb726d48Sopenharmony_ci for (const stack of res) { 490fb726d48Sopenharmony_ci let item = stack; 491fb726d48Sopenharmony_ci // @ts-ignore 492fb726d48Sopenharmony_ci if (data.params.trafic === TraficEnum.ProtoBuffer) { 493fb726d48Sopenharmony_ci item = { 494fb726d48Sopenharmony_ci // @ts-ignore 495fb726d48Sopenharmony_ci callchainId: stack.hiperfCallStackData.callchainId || 0, 496fb726d48Sopenharmony_ci // @ts-ignore 497fb726d48Sopenharmony_ci fileId: stack.hiperfCallStackData.fileId || 0, 498fb726d48Sopenharmony_ci // @ts-ignore 499fb726d48Sopenharmony_ci depth: stack.hiperfCallStackData.depth || 0, 500fb726d48Sopenharmony_ci // @ts-ignore 501fb726d48Sopenharmony_ci symbolId: stack.hiperfCallStackData.symbolId || 0, 502fb726d48Sopenharmony_ci // @ts-ignore 503fb726d48Sopenharmony_ci name: stack.hiperfCallStackData.name || 0, 504fb726d48Sopenharmony_ci }; 505fb726d48Sopenharmony_ci } 506fb726d48Sopenharmony_ci // @ts-ignore 507fb726d48Sopenharmony_ci dataCache.callstack.set(`${item.callchainId}-${item.depth}`, item); 508fb726d48Sopenharmony_ci // @ts-ignore 509fb726d48Sopenharmony_ci let parentSymbol = dataCache.callstack.get(`${item.callchainId}-${item.depth - 1}`); 510fb726d48Sopenharmony_ci // @ts-ignore 511fb726d48Sopenharmony_ci if (parentSymbol && parentSymbol.callchainId === item.callchainId && parentSymbol.depth === item.depth - 1) { 512fb726d48Sopenharmony_ci // @ts-ignore 513fb726d48Sopenharmony_ci parentSymbol.children = []; 514fb726d48Sopenharmony_ci // @ts-ignore 515fb726d48Sopenharmony_ci parentSymbol.children.push(item); 516fb726d48Sopenharmony_ci } 517fb726d48Sopenharmony_ci } 518fb726d48Sopenharmony_ci for (let key of Array.from(dataCache.callstack.keys())) { 519fb726d48Sopenharmony_ci if (!key.endsWith('-0')) { 520fb726d48Sopenharmony_ci dataCache.callstack.delete(key); 521fb726d48Sopenharmony_ci } 522fb726d48Sopenharmony_ci } 523fb726d48Sopenharmony_ci (self as unknown as Worker).postMessage( 524fb726d48Sopenharmony_ci { 525fb726d48Sopenharmony_ci // @ts-ignore 526fb726d48Sopenharmony_ci id: data.id, 527fb726d48Sopenharmony_ci // @ts-ignore 528fb726d48Sopenharmony_ci action: data.action, 529fb726d48Sopenharmony_ci results: 'ok', 530fb726d48Sopenharmony_ci len: res.length, 531fb726d48Sopenharmony_ci }, 532fb726d48Sopenharmony_ci [] 533fb726d48Sopenharmony_ci ); 534fb726d48Sopenharmony_ci} 535fb726d48Sopenharmony_ci 536fb726d48Sopenharmony_cifunction ns2x(ns: number, startNS: number, endNS: number, duration: number, rect: unknown): number { 537fb726d48Sopenharmony_ci if (endNS === 0) { 538fb726d48Sopenharmony_ci endNS = duration; 539fb726d48Sopenharmony_ci } 540fb726d48Sopenharmony_ci // @ts-ignore 541fb726d48Sopenharmony_ci let xSizeHiperf: number = ((ns - startNS) * rect.width) / (endNS - startNS); 542fb726d48Sopenharmony_ci if (xSizeHiperf < 0) { 543fb726d48Sopenharmony_ci xSizeHiperf = 0; 544fb726d48Sopenharmony_ci // @ts-ignore 545fb726d48Sopenharmony_ci } else if (xSizeHiperf > rect.width) { 546fb726d48Sopenharmony_ci // @ts-ignore 547fb726d48Sopenharmony_ci xSizeHiperf = rect.width; 548fb726d48Sopenharmony_ci } 549fb726d48Sopenharmony_ci return xSizeHiperf; 550fb726d48Sopenharmony_ci} 551fb726d48Sopenharmony_ciclass PerfCallChart { 552fb726d48Sopenharmony_ci startTs: Float64Array; 553fb726d48Sopenharmony_ci dur: Float64Array; 554fb726d48Sopenharmony_ci depth: Int32Array; 555fb726d48Sopenharmony_ci eventCount: Int32Array; 556fb726d48Sopenharmony_ci symbolId: Int32Array; 557fb726d48Sopenharmony_ci fileId: Int32Array; 558fb726d48Sopenharmony_ci callchainId: Int32Array; 559fb726d48Sopenharmony_ci selfDur: Int32Array; 560fb726d48Sopenharmony_ci name: Int32Array; 561fb726d48Sopenharmony_ci constructor(len: number) { 562fb726d48Sopenharmony_ci this.startTs = new Float64Array(len); 563fb726d48Sopenharmony_ci this.dur = new Float64Array(len); 564fb726d48Sopenharmony_ci this.depth = new Int32Array(len); 565fb726d48Sopenharmony_ci this.eventCount = new Int32Array(len); 566fb726d48Sopenharmony_ci this.symbolId = new Int32Array(len); 567fb726d48Sopenharmony_ci this.fileId = new Int32Array(len); 568fb726d48Sopenharmony_ci this.callchainId = new Int32Array(len); 569fb726d48Sopenharmony_ci this.selfDur = new Int32Array(len); 570fb726d48Sopenharmony_ci this.name = new Int32Array(len); 571fb726d48Sopenharmony_ci } 572fb726d48Sopenharmony_ci} 573fb726d48Sopenharmony_ciclass DataSource { 574fb726d48Sopenharmony_ci startTs: Array<number>; 575fb726d48Sopenharmony_ci dur: Array<number>; 576fb726d48Sopenharmony_ci depth: Array<number>; 577fb726d48Sopenharmony_ci eventCount: Array<number>; 578fb726d48Sopenharmony_ci symbolId: Array<number>; 579fb726d48Sopenharmony_ci fileId: Array<number>; 580fb726d48Sopenharmony_ci callchainId: Array<number>; 581fb726d48Sopenharmony_ci selfDur: Array<number>; 582fb726d48Sopenharmony_ci name: Array<number>; 583fb726d48Sopenharmony_ci constructor() { 584fb726d48Sopenharmony_ci this.startTs = []; 585fb726d48Sopenharmony_ci this.dur = []; 586fb726d48Sopenharmony_ci this.depth = []; 587fb726d48Sopenharmony_ci this.eventCount = []; 588fb726d48Sopenharmony_ci this.symbolId = []; 589fb726d48Sopenharmony_ci this.fileId = []; 590fb726d48Sopenharmony_ci this.callchainId = []; 591fb726d48Sopenharmony_ci this.selfDur = []; 592fb726d48Sopenharmony_ci this.name = []; 593fb726d48Sopenharmony_ci } 594fb726d48Sopenharmony_ci} 595