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 { filterDataByLayer } from '../utils/DataFilter';
16import { processList } from '../utils/AllMemoryCache';
17import { Args } from '../CommonArgs';
18
19const sqlNormal = (args: Args): string => {
20  return `select ta.cpu,                                                            
21                 max(dur)  as dur,
22                 ts - ${args.recordStartNS} as startTime,
23                 ((ts - ${args.recordStartNS}) / (${Math.floor(
24    (args.endNS - args.startNS) / args.width
25  )})) + (ta.cpu * ${args.width}) AS px
26          from thread_state ta
27          where ta.cpu is not null
28            and pid = ${args.pid}
29            and startTime + dur >= ${Math.floor(args.startNS)}
30            and startTime <= ${Math.floor(args.endNS)}
31          group by px;`;
32};
33
34const sqlMem = (args: Args): string => {
35  return `select ta.cpu,
36                 dur                        as dur,
37                 ts - ${args.recordStartNS} as startTime
38          from thread_state ta
39          where ta.cpu is not null
40            and pid = ${args.pid};`;
41};
42
43export function processDataReceiver(data: unknown, proc: Function): void {
44  //@ts-ignore
45  if (data.params.trafic === TraficEnum.Memory) {
46    //@ts-ignore
47    if (!processList.has(data.params.pid)) {
48      //@ts-ignore
49      processList.set(data.params.pid, proc(sqlMem(data.params)));
50    }
51    let res = filterDataByLayer(
52      //@ts-ignore
53      processList.get(data.params.pid) || [],
54      'cpu',
55      'startTime',
56      'dur', //@ts-ignore
57      data.params.startNS, //@ts-ignore
58      data.params.endNS, //@ts-ignore
59      data.params.width
60    );
61    arrayBufferHandler(data, res, true);
62    return;
63  } else {
64    //@ts-ignore
65    let transfer = data.params.trafic !== TraficEnum.SharedArrayBuffer; //@ts-ignore
66    let sql = sqlNormal(data.params);
67    let res: unknown[] = proc(sql);
68    arrayBufferHandler(data, res, transfer);
69  }
70}
71
72function arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean): void {
73  //@ts-ignore
74  let startTime = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startTime); //@ts-ignore
75  let dur = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.dur); //@ts-ignore
76  let cpu = new Uint8Array(transfer ? res.length : data.params.sharedArrayBuffers.cpu);
77  res.forEach((it, i) => {
78    //@ts-ignore
79    data.params.trafic === TraficEnum.ProtoBuffer && (it = it.processData); //@ts-ignore
80    startTime[i] = it.startTime; //@ts-ignore
81    dur[i] = it.dur; //@ts-ignore
82    cpu[i] = it.cpu;
83  });
84  (self as unknown as Worker).postMessage(
85    {
86      //@ts-ignore
87      id: data.id, //@ts-ignore
88      action: data.action,
89      results: transfer
90        ? {
91            startTime: startTime.buffer,
92            dur: dur.buffer,
93            cpu: cpu.buffer,
94          }
95        : {},
96      len: res.length,
97      transfer: transfer,
98    },
99    transfer ? [startTime.buffer, dur.buffer, cpu.buffer] : []
100  );
101}
102