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 { TraficEnum } from './utils/QueryEnum';
16
17export const fileSystemDataGroupBy10MSProtoSql = (args: Args): string => {
18  return `SELECT
19        startNs, endNs, max( count ) AS size,
20        ( startNS / ( ( ${args.endNS} - ${args.startNS} ) / ${args.width} ) ) AS px
21        FROM
22        (
23        SELECT
24            ( A.start_ts - ${args.recordStartNS} ) / 10000000 * 10000000 AS startNs,
25            ( A.start_ts - ${args.recordStartNS} + 10000000 ) / 10000000 * 10000000 AS endNs,
26            count( dur ) AS count
27        FROM
28            file_system_sample A
29        WHERE
30            type = ${args.type}
31            and startNs > ${Math.floor(args.startNS)}
32            AND startNs + dur >= ${Math.floor(args.startNS)}
33            AND startNs < ${Math.floor(args.endNS)}
34        GROUP BY
35        startNs
36        )
37        GROUP BY px
38            `;
39};
40export const fileSystemDataProtoSql = (args: Args): string => {
41  return `select
42          (A.start_ts - ${args.recordStartNS}) as startNs,
43          (A.end_ts - ${args.recordStartNS}) as endNs,
44          dur
45          from file_system_sample A
46          where type = ${args.type}
47          and startNs > 0
48          and startNs + dur > ${args.startNS}
49          and startNs < ${args.endNS}
50    `;
51};
52export const diskIoDataGroupBy10MSProtoSql = (args: Args): string => {
53  return `SELECT
54        startNs,
55        endNs,
56        max( dur ) AS size,
57        ( startNS / ( ( ${args.endNS} - ${args.startNS} ) / ${args.width} ) ) AS px
58        FROM
59        (
60        SELECT
61            ( A.start_ts - ${args.recordStartNS} ) / 10000000 * 10000000 AS startNs,
62            ( A.start_ts - ${args.recordStartNS} + 10000000 ) / 10000000 * 10000000 AS endNs,
63            max( latency_dur ) AS dur
64        FROM bio_latency_sample A
65            where type in (${args.typeArr.join(',')}) and startNs > 0
66            ${args.all ? '' : 'and ipid = ' + args.ipid}
67            and startNs + latency_dur > ${args.startNS}
68            and startNs < ${args.endNS}
69            GROUP BY startNs
70            order by startNs
71        )
72        GROUP BY px`;
73};
74export const diskIoDataProtoSql = (args: Args): string => {
75  return `select
76        (A.start_ts - ${args.recordStartNS}) as startNs,
77        (A.start_ts - ${args.recordStartNS} + A.latency_dur) as endNs,
78        latency_dur as dur
79        from bio_latency_sample A
80        where type in (${args.typeArr.join(',')}) and startNs > 0
81        ${args.all ? '' : 'and ipid = ' + args.ipid}
82        and startNs + dur > ${args.startNS}
83        and startNs < ${args.endNS}
84        order by A.start_ts;`;
85};
86export const eBPFVmDataGroupBy10MSProtoSql = (args: unknown): string => {
87  return `SELECT startNs, endNs, max( count ) AS size,
88        ( startNS / ( ( ${
89          // @ts-ignore
90          args.endNS
91        } - ${
92    // @ts-ignore
93    args.startNS
94  } ) / ${
95    // @ts-ignore
96    args.width
97  } ) ) AS px
98        FROM
99        (
100        SELECT
101            ( A.start_ts - ${
102              // @ts-ignore
103              args.recordStartNS
104            } ) / 10000000 * 10000000 AS startNs,
105            ( A.start_ts - ${
106              // @ts-ignore
107              args.recordStartNS
108            } + 10000000 ) / 10000000 * 10000000 AS endNs,
109            count( dur ) AS count
110        FROM
111        paged_memory_sample A
112        where startNs + dur > ${
113          // @ts-ignore
114          args.startNS
115        }
116        and startNs > 0
117        and startNs < ${
118          // @ts-ignore
119          args.endNS
120        }
121        and endNs > ${
122          // @ts-ignore
123          args.startNS
124        }
125        GROUP BY startNs
126        order by startNs
127        )
128        GROUP BY px`;
129};
130export const eBPFVmDataProtoSql = (args: unknown): string => {
131  return `select
132        (A.start_ts - ${
133          // @ts-ignore
134          args.recordStartNS
135        }) as startNs,
136        (A.end_ts - ${
137          // @ts-ignore
138          args.recordStartNS
139        }) as endNs,
140        dur as dur
141        from paged_memory_sample A
142        where startNs + dur > ${
143          // @ts-ignore
144          args.startNS
145        }
146        and startNs > 0
147        and startNs < ${
148          // @ts-ignore
149          args.endNS
150        }
151        and endNs > ${
152          // @ts-ignore
153          args.startNS
154        }
155        order by A.start_ts;`;
156};
157
158/**
159 * @param data
160 * @param proc
161 */
162export function fileSystemDataReceiver(data: unknown, proc: Function): void {
163  let sql: string;
164  // @ts-ignore
165  if (data.params.scale > 40_000_000) {
166    // @ts-ignore
167    sql = fileSystemDataGroupBy10MSProtoSql(data.params);
168  } else {
169    // @ts-ignore
170    sql = fileSystemDataProtoSql(data.params);
171  }
172  let res = proc(sql);
173  // @ts-ignore
174  arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
175}
176export function diskIoReceiver(data: unknown, proc: Function): void {
177  let sql: string;
178  // @ts-ignore
179  if (data.params.scale > 40_000_000) {
180    // @ts-ignore
181    sql = diskIoDataGroupBy10MSProtoSql(data.params);
182  } else {
183    // @ts-ignore
184    sql = diskIoDataProtoSql(data.params);
185  }
186  let res = proc(sql);
187  // @ts-ignore
188  arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
189}
190export function eBPFVmReceiver(data: unknown, proc: Function): void {
191  let sql: string;
192  // @ts-ignore
193  if (data.params.scale > 40_000_000) {
194    // @ts-ignore
195    sql = eBPFVmDataGroupBy10MSProtoSql(data.params);
196  } else {
197    // @ts-ignore
198    sql = eBPFVmDataProtoSql(data.params);
199  }
200  let res = proc(sql);
201  // @ts-ignore
202  arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
203}
204
205function arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean): void {
206  // @ts-ignore
207  let startNS = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startNS);
208  // @ts-ignore
209  let endNS = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.endNS);
210  // @ts-ignore
211  let size = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.size);
212  // @ts-ignore
213  let dur = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.dur);
214  // @ts-ignore
215  let height = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.height);
216  // @ts-ignore
217  let maxSize = Math.max(...res.map((it) => it.size));
218  res.forEach((it, i) => {
219    // @ts-ignore
220    startNS[i] = it.startNs;
221    // @ts-ignore
222    endNS[i] = it.endNs;
223    // @ts-ignore
224    size[i] = it.size;
225    // @ts-ignore
226    dur[i] = it.dur;
227    // @ts-ignore
228    height[i] = Math.ceil((it.size / maxSize) * 36);
229  });
230  (self as unknown as Worker).postMessage(
231    {
232      // @ts-ignore
233      id: data.id,
234      // @ts-ignore
235      action: data.action,
236      results: transfer
237        ? {
238            startNS: startNS.buffer,
239            endNS: endNS.buffer,
240            size: size.buffer,
241            height: height.buffer,
242            dur: dur.buffer,
243          }
244        : {},
245      len: res.length,
246      transfer: transfer,
247    },
248    transfer ? [startNS.buffer, endNS.buffer, size.buffer, height.buffer, dur.buffer] : []
249  );
250}
251