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 { TraficEnum } from './utils/QueryEnum';
15import { lostFrameList } from './utils/AllMemoryCache';
16
17export const queryPresentInfo = (args: any): string => {
18  return `SELECT ts,dur,name FROM callstack WHERE callid in (SELECT id FROM "thread" WHERE name LIKE('${args.threadName}'))
19    AND name LIKE('${args.funcName}')`;
20};
21
22export function lostFrameReceiver(data: any, proc: Function): void {
23  if (data.params.trafic === TraficEnum.Memory) {
24    if (!lostFrameList.has(data.params.pid)) {
25      lostFrameList.set(data.params.pid, proc(queryPresentInfo(data.params)));
26    }
27    let res = lostFrameList.get(data.params.pid)!;
28    arrayBufferHandler(data, res, true);
29  } else {
30    let res = proc(queryPresentInfo(data.params));
31    arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
32  }
33}
34
35function arrayBufferHandler(data: any, res: any[], transfer: boolean): void {
36  let startTime = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startTime);
37  let dur = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.dur);
38  let argSetId = new Uint8Array(transfer ? res.length : data.params.sharedArrayBuffers.argSetId);
39  let nofinish = new Uint8Array(transfer ? res.length : data.params.sharedArrayBuffers.nofinish);
40  let presentId = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.presentId);
41  res.forEach((it, i) => {
42    let nameCutArr = it.name.split(' ');
43    data.params.trafic === TraficEnum.ProtoBuffer && (it = it.cpuData);
44    startTime[i] = it.ts;
45    dur[i] = it.dur;
46    nofinish[i] = it.nofinish;
47    argSetId[i] = it.argSetId;
48    presentId[i] = Number(nameCutArr[nameCutArr.length - 1]);
49  });
50  (self as unknown as Worker).postMessage(
51    {
52      id: data.id,
53      action: data.action,
54      results: transfer
55        ? {
56            startTime: startTime.buffer,
57            dur: dur.buffer,
58            argSetID: argSetId.buffer,
59            presentId: presentId.buffer,
60          }
61        : {},
62      len: res.length,
63      transfer: transfer,
64    },
65    transfer ? [startTime.buffer, dur.buffer, argSetId.buffer] : []
66  );
67}
68