Files
dbx/apps/desktop/src/lib/export/exportDiagnostics.ts
T

103 lines
2.9 KiB
TypeScript

import type { CellValue } from "@/lib/dataGrid/cellValue";
export interface ExportRowsDiagnostics {
rowCount: number;
cellCount: number;
nullCellCount: number;
stringCellCount: number;
numberCellCount: number;
booleanCellCount: number;
totalValueChars: number;
totalValueUtf8Bytes: number;
maxValueChars: number;
maxValueUtf8Bytes: number;
cellsAtLeast1MiB: number;
cellsAtLeast10MiB: number;
rowsAtLeast1MiB: number;
minCellsPerRow: number;
maxCellsPerRow: number;
}
const MEBIBYTE = 1024 * 1024;
function utf8ByteLength(value: string): number {
let bytes = 0;
for (let index = 0; index < value.length; index += 1) {
const code = value.charCodeAt(index);
if (code <= 0x7f) bytes += 1;
else if (code <= 0x7ff) bytes += 2;
else if (code >= 0xd800 && code <= 0xdbff && index + 1 < value.length) {
const next = value.charCodeAt(index + 1);
if (next >= 0xdc00 && next <= 0xdfff) {
bytes += 4;
index += 1;
} else bytes += 3;
} else bytes += 3;
}
return bytes;
}
export function summarizeExportRows(rows: readonly (readonly CellValue[])[]): ExportRowsDiagnostics {
let cellCount = 0;
let nullCellCount = 0;
let stringCellCount = 0;
let numberCellCount = 0;
let booleanCellCount = 0;
let totalValueChars = 0;
let totalValueUtf8Bytes = 0;
let maxValueChars = 0;
let maxValueUtf8Bytes = 0;
let cellsAtLeast1MiB = 0;
let cellsAtLeast10MiB = 0;
let rowsAtLeast1MiB = 0;
let minCellsPerRow = rows.length === 0 ? 0 : Number.POSITIVE_INFINITY;
let maxCellsPerRow = 0;
for (const row of rows) {
minCellsPerRow = Math.min(minCellsPerRow, row.length);
maxCellsPerRow = Math.max(maxCellsPerRow, row.length);
let rowHasLargeCell = false;
for (const value of row) {
cellCount += 1;
if (value === null) {
nullCellCount += 1;
continue;
}
if (typeof value === "string") stringCellCount += 1;
else if (typeof value === "number") numberCellCount += 1;
else booleanCellCount += 1;
const text = String(value);
const utf8Bytes = utf8ByteLength(text);
totalValueChars += text.length;
totalValueUtf8Bytes += utf8Bytes;
maxValueChars = Math.max(maxValueChars, text.length);
maxValueUtf8Bytes = Math.max(maxValueUtf8Bytes, utf8Bytes);
if (utf8Bytes >= MEBIBYTE) {
cellsAtLeast1MiB += 1;
rowHasLargeCell = true;
}
if (utf8Bytes >= 10 * MEBIBYTE) cellsAtLeast10MiB += 1;
}
if (rowHasLargeCell) rowsAtLeast1MiB += 1;
}
return {
rowCount: rows.length,
cellCount,
nullCellCount,
stringCellCount,
numberCellCount,
booleanCellCount,
totalValueChars,
totalValueUtf8Bytes,
maxValueChars,
maxValueUtf8Bytes,
cellsAtLeast1MiB,
cellsAtLeast10MiB,
rowsAtLeast1MiB,
minCellsPerRow: Number.isFinite(minCellsPerRow) ? minCellsPerRow : 0,
maxCellsPerRow,
};
}