| |
| |
| |
|
|
| import { readVarInt } from './thrift.js' |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function readRleBitPackedHybrid(reader, width, output, length) { |
| if (length === undefined) { |
| length = reader.view.getUint32(reader.offset, true) |
| reader.offset += 4 |
| } |
| const startOffset = reader.offset |
| let seen = 0 |
| while (seen < output.length) { |
| const header = readVarInt(reader) |
| if (header & 1) { |
| |
| seen = readBitPacked(reader, header, width, output, seen) |
| } else { |
| |
| const count = header >>> 1 |
| readRle(reader, count, width, output, seen) |
| seen += count |
| } |
| } |
| reader.offset = startOffset + length |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| function readRle(reader, count, bitWidth, output, seen) { |
| const width = bitWidth + 7 >> 3 |
| let value = 0 |
| for (let i = 0; i < width; i++) { |
| value |= reader.view.getUint8(reader.offset++) << (i << 3) |
| } |
| |
|
|
| |
| for (let i = 0; i < count; i++) { |
| output[seen + i] = value |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| function readBitPacked(reader, header, bitWidth, output, seen) { |
| let count = header >> 1 << 3 |
| const mask = (1 << bitWidth) - 1 |
|
|
| let data = 0 |
| if (reader.offset < reader.view.byteLength) { |
| data = reader.view.getUint8(reader.offset++) |
| } else if (mask) { |
| |
| throw new Error(`parquet bitpack offset ${reader.offset} out of range`) |
| } |
| let left = 8 |
| let right = 0 |
|
|
| |
| while (count) { |
| |
| if (right > 8) { |
| right -= 8 |
| left -= 8 |
| data >>>= 8 |
| } else if (left - right < bitWidth) { |
| |
| data |= reader.view.getUint8(reader.offset) << left |
| reader.offset++ |
| left += 8 |
| } else { |
| if (seen < output.length) { |
| |
| output[seen++] = data >> right & mask |
| } |
| count-- |
| right += bitWidth |
| } |
| } |
|
|
| return seen |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| export function byteStreamSplit(reader, count, type, typeLength) { |
| const width = byteWidth(type, typeLength) |
| const bytes = new Uint8Array(count * width) |
| for (let b = 0; b < width; b++) { |
| for (let i = 0; i < count; i++) { |
| bytes[i * width + b] = reader.view.getUint8(reader.offset++) |
| } |
| } |
| |
| if (type === 'FLOAT') return new Float32Array(bytes.buffer) |
| else if (type === 'DOUBLE') return new Float64Array(bytes.buffer) |
| else if (type === 'INT32') return new Int32Array(bytes.buffer) |
| else if (type === 'INT64') return new BigInt64Array(bytes.buffer) |
| else if (type === 'FIXED_LEN_BYTE_ARRAY') { |
| |
| const split = new Array(count) |
| for (let i = 0; i < count; i++) { |
| split[i] = bytes.subarray(i * width, (i + 1) * width) |
| } |
| return split |
| } |
| throw new Error(`parquet byte_stream_split unsupported type: ${type}`) |
| } |
|
|
| |
| |
| |
| |
| |
| function byteWidth(type, typeLength) { |
| switch (type) { |
| case 'INT32': |
| case 'FLOAT': |
| return 4 |
| case 'INT64': |
| case 'DOUBLE': |
| return 8 |
| case 'FIXED_LEN_BYTE_ARRAY': |
| if (!typeLength) throw new Error('parquet byteWidth missing type_length') |
| return typeLength |
| default: |
| throw new Error(`parquet unsupported type: ${type}`) |
| } |
| } |
|
|