From 429fd9e813ab5d03a3685dc0545f6157b0639c99 Mon Sep 17 00:00:00 2001 From: Kenny Daniel Date: Sat, 6 Apr 2024 20:01:48 -0700 Subject: [PATCH] Fix max call stack error in browser: concat not spread... --- package.json | 2 +- src/column.js | 9 +++++---- src/encoding.js | 12 +++++++----- src/read.js | 6 +++--- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 88c15bb..73eb629 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "typecheck": "tsc" }, "devDependencies": { - "@types/node": "20.12.4", + "@types/node": "20.12.5", "@typescript-eslint/eslint-plugin": "7.5.0", "@vitest/coverage-v8": "1.4.0", "eslint": "8.57.0", diff --git a/src/column.js b/src/column.js index 06f7b06..c589c35 100644 --- a/src/column.js +++ b/src/column.js @@ -30,7 +30,8 @@ export function readColumn(arrayBuffer, columnOffset, rowGroup, columnMetadata, let dictionary = undefined let valuesSeen = 0 let byteOffset = 0 // byteOffset within the column - const rowData = [] + /** @type {any[]} */ + let rowData = [] while (valuesSeen < rowGroup.num_rows) { // parse column header @@ -92,7 +93,7 @@ export function readColumn(arrayBuffer, columnOffset, rowGroup, columnMetadata, // values.length !== daph.num_values isn't right. In cases like arrays, // you need the total number of children, not the number of top-level values. - rowData.push(...values) + rowData = rowData.concat(values) } else if (header.type === PageType.DICTIONARY_PAGE) { const diph = header.dictionary_page_header if (!diph) throw new Error('parquet dictionary page header is undefined') @@ -115,7 +116,7 @@ export function readColumn(arrayBuffer, columnOffset, rowGroup, columnMetadata, if (repetitionLevels.length) { dereferenceDictionary(dictionary, dataPage) // Use repetition levels to construct lists - rowData.push(...assembleObjects( + rowData = rowData.concat(assembleObjects( definitionLevels, repetitionLevels, dataPage, true, maxDefinitionLevel, maxRepetitionLevel )) } else if (daph2.num_nulls) { @@ -124,7 +125,7 @@ export function readColumn(arrayBuffer, columnOffset, rowGroup, columnMetadata, skipNulls(definitionLevels, maxDefinitionLevel, dataPage, dictionary, rowData) } else { dereferenceDictionary(dictionary, dataPage) - rowData.push(...dataPage) + rowData = rowData.concat(dataPage) } // TODO: convert? } else { diff --git a/src/encoding.js b/src/encoding.js index 78bc900..50a00a4 100644 --- a/src/encoding.js +++ b/src/encoding.js @@ -211,14 +211,15 @@ export function widthFromMaxInt(value) { * @returns {Decoded} array of values */ export function readData(dataView, encoding, offset, count, bitWidth) { - const value = [] + /** @type {any[]} */ + let value = [] let byteLength = 0 if (encoding === 'RLE') { let seen = 0 while (seen < count) { const rle = readRleBitPackedHybrid(dataView, offset + byteLength, bitWidth, 0, count) if (!rle.value.length) break // EOF - value.push(...rle.value) + value = value.concat(rle.value) seen += rle.value.length byteLength += rle.byteLength } @@ -247,7 +248,8 @@ export function readRleBitPackedHybrid(dataView, offset, width, length, numValue if (length < 0) throw new Error(`parquet invalid rle/bitpack length ${length}`) byteLength += 4 } - const value = [] + /** @type {number[]} */ + let value = [] const startByteLength = byteLength while (byteLength - startByteLength < length && value.length < numValues) { const [header, newOffset] = readVarInt(dataView, offset + byteLength) @@ -255,14 +257,14 @@ export function readRleBitPackedHybrid(dataView, offset, width, length, numValue if ((header & 1) === 0) { // rle const rle = readRle(dataView, offset + byteLength, header, width) - value.push(...rle.value) + value = value.concat(rle.value) byteLength += rle.byteLength } else { // bit-packed const bitPacked = readBitPacked( dataView, offset + byteLength, header, width, numValues - value.length ) - value.push(...bitPacked.value) + value = value.concat(bitPacked.value) byteLength += bitPacked.byteLength } } diff --git a/src/read.js b/src/read.js index 3d516fc..fc6a79e 100644 --- a/src/read.js +++ b/src/read.js @@ -37,10 +37,10 @@ export async function parquetRead(options) { if (!options.metadata) throw new Error('parquet metadata not found') const { metadata, onComplete } = options - /** @type {any[][]} */ - const rowData = [] const rowStart = options.rowStart || 0 const rowEnd = options.rowEnd || Number(metadata.num_rows) + /** @type {any[][]} */ + let rowData = [] // find which row groups to read let groupStart = 0 // first row index of the current group @@ -55,7 +55,7 @@ export async function parquetRead(options) { // filter to rows in range const start = Math.max(rowStart - groupStart, 0) const end = Math.min(rowEnd - groupStart, groupRows) - rowData.push(...groupData.slice(start, end)) + rowData = rowData.concat(groupData.slice(start, end)) } } groupStart += groupRows