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 { filterDataByGroup } from '../utils/DataFilter';
16import { cpuStateList } from '../utils/AllMemoryCache';
17import { Args } from '../CommonArgs';
18
19export const chartCpuStateDataSql = (args: Args): string => {
20  return `
21      select  (value) as value,
22              max(ifnull(dur, ${args.recordEndNS} - A.ts))                                                 as dur,
23              (A.ts - ${args.recordStartNS})                                                               as startTs,
24             ((A.ts - ${args.recordStartNS}) / (${Math.floor((args.endNS - args.startNS) / args.width)})) AS px
25      from measure A
26      where filter_id = ${args.filterId}
27        and startTs + ifnull(dur, ${args.recordEndNS} - A.ts) >= ${Math.floor(args.startNS)}
28        and startTs <= ${Math.floor(args.endNS)}
29      group by px
30      union
31      select  max(value) as value,
32              (ifnull(dur, ${args.recordEndNS} - A.ts))                                                 as dur,
33              (A.ts - ${args.recordStartNS})                                                               as startTs,
34             ((A.ts - ${args.recordStartNS}) / (${Math.floor((args.endNS - args.startNS) / args.width)})) AS px
35      from measure A
36      where filter_id = ${args.filterId}
37        and startTs + ifnull(dur, ${args.recordEndNS} - A.ts) >= ${Math.floor(args.startNS)}
38        and startTs <= ${Math.floor(args.endNS)}
39      group by px
40      ;`;
41};
42
43export const chartCpuStateDataSqlMem = (args: Args): string => {
44  return `
45   select (A.ts - ${args.recordStartNS}) as startTs,ifnull(dur,${args.recordEndNS} - A.ts) dur,
46            value
47        from measure A
48        where filter_id = ${args.filterId};
49      `;
50};
51
52export function cpuStateReceiver(data: unknown, proc: Function): void {
53  // @ts-ignore
54  if (data.params.trafic === TraficEnum.Memory) {
55    let res: unknown[];
56    let list: unknown[];
57    // @ts-ignore
58    if (!cpuStateList.has(data.params.filterId)) {
59      // @ts-ignore
60      list = proc(chartCpuStateDataSqlMem(data.params));
61      for (let i = 0; i < list.length; i++) {
62        // @ts-ignore
63        if (list[i].dur === -1 || list[i].dur === null || list[i].dur === undefined) {
64          // @ts-ignore
65          list[i].dur = data.params.recordEndNS - data.params.recordStartNS - list[i].startTs;
66        }
67      }
68      // @ts-ignore
69      cpuStateList.set(data.params.filterId, list);
70    } else {
71      // @ts-ignore
72      list = cpuStateList.get(data.params.filterId) || [];
73    }
74    res = filterDataByGroup(
75      list || [],
76      'startTs',
77      'dur',
78      // @ts-ignore
79      data.params.startNS,
80      // @ts-ignore
81      data.params.endNS,
82      // @ts-ignore
83      data.params.width,
84      'value'
85    );
86    arrayBufferHandler(data, res, true);
87  } else {
88    // @ts-ignore
89    let sql = chartCpuStateDataSql(data.params);
90    let res = proc(sql);
91    // @ts-ignore
92    arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
93  }
94}
95
96let heights = [4, 8, 12, 16, 20, 24, 28, 32];
97
98function arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean): void {
99  // @ts-ignore
100  let startTs = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startTs);
101  // @ts-ignore
102  let dur = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.dur);
103  // @ts-ignore
104  let value = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.value);
105  // @ts-ignore
106  let height = new Uint8Array(transfer ? res.length : data.params.sharedArrayBuffers.height);
107  res.forEach((it, i) => {
108    // @ts-ignore
109    data.params.trafic === TraficEnum.ProtoBuffer && (it = it.cpuStateData);
110    // @ts-ignore
111    startTs[i] = it.startTs;
112    // @ts-ignore
113    dur[i] = it.dur;
114    // @ts-ignore
115    value[i] = it.value;
116    // @ts-ignore
117    height[i] = heights[it.value];
118  });
119  (self as unknown as Worker).postMessage(
120    {
121      // @ts-ignore
122      id: data.id,
123      // @ts-ignore
124      action: data.action,
125      results: transfer
126        ? {
127            startTs: startTs.buffer,
128            dur: dur.buffer,
129            value: value.buffer,
130          }
131        : {},
132      len: res.length,
133      transfer: transfer,
134    },
135    transfer ? [startTs.buffer, dur.buffer, value.buffer] : []
136  );
137}
138