hyparquet/src/assemble.js

61 lines
1.7 KiB
JavaScript
Raw Normal View History

2024-03-18 23:36:16 +00:00
/**
* Dremel-assembly of arrays of values into lists
*
* @param {number[] | undefined} definitionLevels definition levels, max 3
* @param {number[]} repetitionLevels repetition levels, max 1
2024-03-19 06:54:58 +00:00
* @param {ArrayLike<any>} values values to process
2024-03-18 23:36:16 +00:00
* @param {boolean} isNull can an entry be null?
* @param {number} maxDefinitionLevel definition level that corresponds to non-null
* @returns {any[]} array of values
*/
export function assembleObjects(
2024-03-19 06:54:58 +00:00
definitionLevels, repetitionLevels, values, isNull, maxDefinitionLevel
2024-03-18 23:36:16 +00:00
) {
2024-03-19 06:54:58 +00:00
let valueIndex = 0
2024-03-18 23:36:16 +00:00
let started = false
let haveNull = false
2024-03-19 06:54:58 +00:00
let outputIndex = 0
2024-03-18 23:36:16 +00:00
let part = []
/** @type {any[]} */
2024-03-19 06:54:58 +00:00
const output = []
2024-03-18 23:36:16 +00:00
for (let counter = 0; counter < repetitionLevels.length; counter++) {
const def = definitionLevels?.length ? definitionLevels[counter] : maxDefinitionLevel
const rep = repetitionLevels[counter]
if (!rep) {
// new row - save what we have
if (started) {
2024-03-19 06:54:58 +00:00
output[outputIndex] = haveNull ? undefined : part
2024-03-18 23:36:16 +00:00
part = []
2024-03-19 06:54:58 +00:00
outputIndex++
2024-03-18 23:36:16 +00:00
} else {
// first time: no row to save yet, unless it's a row continued from previous page
2024-03-19 06:54:58 +00:00
if (valueIndex > 0) {
output[outputIndex - 1] = output[outputIndex - 1]?.concat(part) // add items to previous row
2024-03-18 23:36:16 +00:00
part = []
// don't increment i since we only filled i-1
}
started = true
}
}
if (def === maxDefinitionLevel) {
// append real value to current item
2024-03-19 06:54:58 +00:00
part.push(values[valueIndex])
valueIndex++
2024-03-18 23:36:16 +00:00
} else if (def > 0) {
// append null to current item
part.push(undefined)
}
haveNull = def === 0 && isNull
}
if (started) {
2024-03-19 06:54:58 +00:00
output[outputIndex] = haveNull ? undefined : part
2024-03-18 23:36:16 +00:00
}
2024-03-19 06:54:58 +00:00
return output
2024-03-18 23:36:16 +00:00
}