1// Copyright (c) 2021 Huawei Device Co., Ltd. 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14import { Args } from '../CommonArgs'; 15import { threadCallStackList } from '../utils/AllMemoryCache'; 16import { filterDataByGroupLayer } from '../utils/DataFilter'; 17import { TraficEnum } from '../utils/QueryEnum'; 18 19export const chartFuncDataSql = (args: Args): string => { 20 return ` 21 select 22 startTs, 23 dur, 24 ifnull(argsetid, -1) as argsetid, 25 depth, 26 id, 27 max(dur2) as dur2, 28 (startTs) / (${Math.floor((args.endNS - args.startNS) / args.width)}) + (depth * ${ 29 args.width 30 }) AS px 31 from ( 32 select c.ts - ${args.recordStartNS} as startTs, 33 c.dur as dur, 34 case when (c.dur=-1 or c.dur is null ) then ${args.recordEndNS} else c.dur end as dur2, 35 c.argsetid, 36 c.depth, 37 c.id as id 38 --c.name as funName, 39 from callstack C 40 where startTs not null 41 and c.cookie is null 42 and c.callid in (select id from thread where tid=${args.tid} 43 and ipid=${args.ipid}) 44 and startTs + dur2 >= ${Math.floor(args.startNS)} 45 and startTs <= ${Math.floor(args.endNS)} 46 ) 47 group by px; 48`; 49}; 50 51export const chartFuncDataSqlMem = (args: Args): string => { 52 return `select c.ts - ${args.recordStartNS} as startTs, 53 c.dur as dur, 54 ifnull(c.argsetid, -1) as argsetid, 55 c.depth, 56 c.id as id 57 from callstack C 58 where startTs not null 59 and c.cookie is null 60 and c.callid in (select id from thread where tid=${args.tid} 61 and ipid=${args.ipid})`; 62}; 63export function funcDataReceiver(data: unknown, proc: Function): void { 64 //@ts-ignore 65 if (data.params.trafic === TraficEnum.Memory) { 66 //@ts-ignore 67 let key = `${data.params.tid}${data.params.ipid}`; 68 if (!threadCallStackList.has(key)) { 69 //@ts-ignore 70 let list = proc(chartFuncDataSqlMem(data.params)); 71 for (let i = 0; i < list.length; i++) { 72 if (list[i].dur === -1 || list[i].dur === null || list[i].dur === undefined) { 73 list[i].nofinish = 1; //@ts-ignore 74 let totalNs = data.params.recordEndNS - data.params.recordStartNS; 75 list[i].dur = totalNs - list[i].startTs; 76 } else { 77 list[i].nofinish = 0; 78 } 79 } 80 threadCallStackList.set(key, list); 81 } 82 //@ts-ignore 83 let array = data.params.expand ? (threadCallStackList.get(key) || []) : arrayFoldHandler(key); 84 let res = filterDataByGroupLayer( 85 //@ts-ignore 86 array, 87 'depth', 88 'startTs', 89 'dur', //@ts-ignore 90 data.params.startNS, //@ts-ignore 91 data.params.endNS, //@ts-ignore 92 data.params.width 93 ); 94 //@ts-ignore 95 arrayBufferHandler(data, res, true, array.length === 0); 96 } else { 97 //@ts-ignore 98 let sql = chartFuncDataSql(data.params); 99 let res = proc(sql); //@ts-ignore 100 arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer, false); 101 } 102} 103 104//func泳道折叠时,过滤出depth为0的数据 105function arrayFoldHandler(key: unknown): unknown { 106 //@ts-ignore 107 return (threadCallStackList.get(key) || []).filter((it) => it.depth === 0 ); 108} 109 110function arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean, isEmpty: boolean): void { 111 //@ts-ignore 112 let startTs = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startTs); //@ts-ignore 113 let dur = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.dur); //@ts-ignore 114 let argsetid = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.argsetid); //@ts-ignore 115 let depth = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.depth); //@ts-ignore 116 let id = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.id); //@ts-ignore 117 let nofinish = new Uint8Array(transfer ? res.length : data.params.sharedArrayBuffers.nofinish); 118 res.forEach((it, i) => { 119 //@ts-ignore 120 data.params.trafic === TraficEnum.ProtoBuffer && (it = it.processFuncData); //@ts-ignore 121 startTs[i] = it.startTs; //@ts-ignore 122 dur[i] = it.dur; //@ts-ignore 123 argsetid[i] = it.argsetid; //@ts-ignore 124 depth[i] = it.depth; //@ts-ignore 125 id[i] = it.id; //@ts-ignore 126 nofinish[i] = it.nofinish; 127 }); 128 (self as unknown as Worker).postMessage( 129 { 130 //@ts-ignore 131 id: data.id, //@ts-ignore 132 action: data.action, 133 results: transfer 134 ? { 135 startTs: startTs.buffer, 136 dur: dur.buffer, 137 argsetid: argsetid.buffer, 138 depth: depth.buffer, 139 id: id.buffer, 140 nofinish: nofinish.buffer, 141 } 142 : {}, 143 len: res.length, 144 transfer: transfer, 145 isEmpty: isEmpty, 146 }, 147 transfer ? [startTs.buffer, dur.buffer, argsetid.buffer, depth.buffer, id.buffer, nofinish.buffer] : [] 148 ); 149} 150