import { Args } from './CommonArgs';
import { TraficEnum } from './utils/QueryEnum';
export const ioDataGroupBy10MSProtoSql = (args: Args): string => {
const isWrite = args.type === 1 || args.type === 3 ? 1 : 0;
const isBlock = args.type === 2 || args.type === 3 ? 1 : 0;
const pidFilter = args.pid === -1 ? '' : `AND P.pid = ${args.pid}`;
return `SELECT
min( startNs ) AS startNs,
max( endNs ) AS endNs,
sum( size ) AS size,
( startNS / ( ( ${args.endNS} - ${args.startNS} ) / ${args.width} ) ) AS px
FROM
(
SELECT
( A.start_time - ${args.recordStartNS} ) / 10000000 * 10000000 AS startNs,
( A.start_time - ${args.recordStartNS} + 10000000 ) / 10000000 * 10000000 AS endNs,
sum( A.request_bytes ) AS size,
A.duration as duration,
0 AS itid
FROM
filesystem_io A
JOIN
process P ON A.ipid = P.ipid
WHERE
A.is_write = ${isWrite}
AND A.is_block = ${isBlock}
${pidFilter}
and (A.start_time - ${args.recordStartNS}) > ${Math.floor(args.startNS)}
AND (A.start_time - ${args.recordStartNS}) + A.duration >= ${Math.floor(args.startNS)}
AND (A.start_time - ${args.recordStartNS}) < ${Math.floor(args.endNS)}
GROUP BY startNs
)
GROUP BY px
`;
};
export const ioDataProtoSql = (args: Args): string => {
const isWrite = args.type === 1 || args.type === 3 ? 1 : 0;
const isBlock = args.type === 2 || args.type === 3 ? 1 : 0;
const pidFilter = args.pid === -1 ? '' : `AND P.pid = ${args.pid}`;
return `select
(A.start_time - ${args.recordStartNS}) as startNs,
(A.end_time - ${args.recordStartNS}) as endNs,
A.duration as dur,
A.request_bytes as size,
A.is_write as isWrite,
A.is_block as isPhysical,
COALESCE(A.itid, 0) as itid
from filesystem_io A
JOIN
process P ON A.ipid = P.ipid
where A.is_write = ${isWrite}
AND A.is_block = ${isBlock}
${pidFilter}
and (A.start_time - ${args.recordStartNS}) > 0
and (A.start_time - ${args.recordStartNS}) + A.duration > ${args.startNS}
and (A.start_time - ${args.recordStartNS}) < ${args.endNS}
`;
};
export function ioDataReceiver(data: unknown, proc: Function): void {
let sql: string;
if (data.params.scale > 40_000_000) {
sql = ioDataGroupBy10MSProtoSql(data.params);
} else {
sql = ioDataProtoSql(data.params);
}
let res = proc(sql);
arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
}
function arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean): void {
let startNS = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startNS);
let endNS = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.endNS);
let size = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.size);
let dur = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.dur);
let height = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.height);
let isWrite = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.isWrite);
let isPhysical = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.isPhysical);
let itid = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.itid);
let maxSize = res.length > 0 ? Math.max(...res.map((it) => it.size)) : 0;
res.forEach((it, i) => {
startNS[i] = it.startNs;
endNS[i] = it.endNs;
size[i] = it.size;
const durVal = it.dur != null ? it.dur : it.endNs - it.startNs;
dur[i] = durVal;
height[i] = maxSize > 0 ? Math.ceil((it.size / maxSize) * 36) : 36;
isWrite[i] = it.isWrite != null ? it.isWrite : 0;
isPhysical[i] = it.isPhysical != null ? it.isPhysical : 0;
itid[i] = it.itid != null ? it.itid : 0;
});
(self as unknown as Worker).postMessage(
{
id: data.id,
action: data.action,
results: transfer
? {
startNS: startNS.buffer,
endNS: endNS.buffer,
size: size.buffer,
height: height.buffer,
dur: dur.buffer,
isWrite: isWrite.buffer,
isPhysical: isPhysical.buffer,
itid: itid.buffer,
}
: {},
len: res.length,
transfer: transfer,
},
transfer
? [startNS.buffer, endNS.buffer, size.buffer, height.buffer, dur.buffer, isWrite.buffer, isPhysical.buffer, itid.buffer]
: []
);
}