1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15import { TraficEnum } from './utils/QueryEnum';
16import { hiSysEventList } from './utils/AllMemoryCache';
17import { filterDataByGroupLayer } from './utils/DataFilter';
18import { Args } from './CommonArgs';
19
20export const chartHiSysEventDataSql = (args: Args): string => {
21  return `
22      SELECT S.id,
23             (S.ts - ${
24               args.recordStartNS
25             })                                                                                 AS startNs,
26             pid,
27             tid,
28             uid,
29             seq,
30             CASE
31                 WHEN S.level = 'MINOR' THEN 0
32                 WHEN S.level = 'CRITICAL' THEN 1
33                 END
34                                                                                                                            AS depth,
35             1                                                                                                              AS dur,
36             ((S.ts - ${args.recordStartNS}) / (${Math.floor((args.endNS - args.startNS) / args.width)})) + (CASE
37                                                                                                                 WHEN S.level = 'MINOR'
38                                                                                                                     THEN 0
39                                                                                                                 WHEN S.level = 'CRITICAL'
40                                                                                                                     THEN 1
41                                                                                                                 END *
42                                                                                                             ${
43                                                                                                               args.width
44                                                                                                             }) AS px
45      FROM hisys_all_event AS S
46      where S.id is not null
47        and startNs + dur >= ${Math.floor(args.startNS)}
48        and startNs <= ${Math.floor(args.endNS)}
49      group by px`;
50};
51
52export const chartHiSysEventSql = (args: Args): string => {
53  return `
54     SELECT S.id,
55             (S.ts - ${args.recordStartNS})                                                                                 AS startNs,
56             pid,
57             tid,
58             uid,
59             seq,
60             CASE
61                 WHEN S.level = 'MINOR' THEN 0
62                 WHEN S.level = 'CRITICAL' THEN 1
63                 END
64                                                                                                                            AS depth,
65             1                                                                                                              AS dur
66      FROM hisys_all_event AS S
67      where S.id is not null
68      ORDER BY S.id`;
69};
70
71export function hiSysEventDataReceiver(data: unknown, proc: Function): void {
72  // @ts-ignore
73  if (data.params.trafic === TraficEnum.Memory) {
74    // @ts-ignore
75    if (!hiSysEventList.has(data.params.id)) {
76      // @ts-ignore
77      let sql = chartHiSysEventSql(data.params);
78      // @ts-ignore
79      hiSysEventList.set(data.params.id, proc(sql));
80    }
81    // @ts-ignore
82    let list = hiSysEventList.get(data.params.id) || [];
83    let res = filterDataByGroupLayer(
84      list || [],
85      'depth',
86      'startNs',
87      'dur',
88      // @ts-ignore
89      data.params.startNS,
90      // @ts-ignore
91      data.params.endNS,
92      // @ts-ignore
93      data.params.width
94    );
95    // @ts-ignore
96    arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
97  } else {
98    // @ts-ignore
99    let sql = chartHiSysEventDataSql(data.params);
100    let res = proc(sql);
101    // @ts-ignore
102    arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
103  }
104}
105
106function arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean): void {
107  // @ts-ignore
108  let id = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.id);
109  // @ts-ignore
110  let ts = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.ts);
111  // @ts-ignore
112  let pid = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.pid);
113  // @ts-ignore
114  let tid = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.tid);
115  // @ts-ignore
116  let seq = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.seq);
117  // @ts-ignore
118  let uid = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.uid);
119  // @ts-ignore
120  let dur = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.dur);
121  // @ts-ignore
122  let depth = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.depth);
123  res.forEach((it, index) => {
124    // @ts-ignore
125    data.params.trafic === TraficEnum.ProtoBuffer && (it = it.hiSysEventData);
126    // @ts-ignore
127    uid[index] = it.uid;
128    // @ts-ignore
129    id[index] = it.id;
130    // @ts-ignore
131    ts[index] = it.startNs || it.ts;
132    // @ts-ignore
133    pid[index] = it.pid;
134    // @ts-ignore
135    tid[index] = it.tid;
136    // @ts-ignore
137    seq[index] = it.seq;
138    // @ts-ignore
139    dur[index] = it.dur;
140    // @ts-ignore
141    depth[index] = it.depth;
142  });
143  (self as unknown as Worker).postMessage(
144    {
145      // @ts-ignore
146      id: data.id,
147      // @ts-ignore
148      action: data.action,
149      results: transfer
150        ? {
151            uid: uid.buffer,
152            id: id.buffer,
153            ts: ts.buffer,
154            pid: pid.buffer,
155            tid: tid.buffer,
156            seq: seq.buffer,
157            dur: dur.buffer,
158            depth: depth.buffer,
159          }
160        : {},
161      len: res.length,
162      transfer: transfer,
163    },
164    transfer ? [id.buffer, ts.buffer, pid.buffer, tid.buffer, uid.buffer, dur.buffer, seq.buffer, depth.buffer] : []
165  );
166}
167