File size: 5,452 Bytes
9ae1216 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | /**
* Read `count` values of the given type from the reader.view.
*
* @param {DataReader} reader - buffer to read data from
* @param {ParquetType} type - parquet type of the data
* @param {number} count - number of values to read
* @param {number | undefined} fixedLength - length of each fixed length byte array
* @returns {DecodedArray} array of values
*/
export function readPlain(reader, type, count, fixedLength) {
if (count === 0) return []
if (type === 'BOOLEAN') {
return readPlainBoolean(reader, count)
} else if (type === 'INT32') {
return readPlainInt32(reader, count)
} else if (type === 'INT64') {
return readPlainInt64(reader, count)
} else if (type === 'INT96') {
return readPlainInt96(reader, count)
} else if (type === 'FLOAT') {
return readPlainFloat(reader, count)
} else if (type === 'DOUBLE') {
return readPlainDouble(reader, count)
} else if (type === 'BYTE_ARRAY') {
return readPlainByteArray(reader, count)
} else if (type === 'FIXED_LEN_BYTE_ARRAY') {
if (!fixedLength) throw new Error('parquet missing fixed length')
return readPlainByteArrayFixed(reader, count, fixedLength)
} else {
throw new Error(`parquet unhandled type: ${type}`)
}
}
/**
* Read `count` boolean values.
*
* @param {DataReader} reader
* @param {number} count
* @returns {boolean[]}
*/
function readPlainBoolean(reader, count) {
const values = new Array(count)
for (let i = 0; i < count; i++) {
const byteOffset = reader.offset + (i / 8 | 0)
const bitOffset = i % 8
const byte = reader.view.getUint8(byteOffset)
values[i] = (byte & 1 << bitOffset) !== 0
}
reader.offset += Math.ceil(count / 8)
return values
}
/**
* Read `count` int32 values.
*
* @param {DataReader} reader
* @param {number} count
* @returns {Int32Array}
*/
function readPlainInt32(reader, count) {
const values = (reader.view.byteOffset + reader.offset) % 4
? new Int32Array(align(reader.view.buffer, reader.view.byteOffset + reader.offset, count * 4))
: new Int32Array(reader.view.buffer, reader.view.byteOffset + reader.offset, count)
reader.offset += count * 4
return values
}
/**
* Read `count` int64 values.
*
* @param {DataReader} reader
* @param {number} count
* @returns {BigInt64Array}
*/
function readPlainInt64(reader, count) {
const values = (reader.view.byteOffset + reader.offset) % 8
? new BigInt64Array(align(reader.view.buffer, reader.view.byteOffset + reader.offset, count * 8))
: new BigInt64Array(reader.view.buffer, reader.view.byteOffset + reader.offset, count)
reader.offset += count * 8
return values
}
/**
* Read `count` int96 values.
*
* @param {DataReader} reader
* @param {number} count
* @returns {bigint[]}
*/
function readPlainInt96(reader, count) {
const values = new Array(count)
for (let i = 0; i < count; i++) {
const low = reader.view.getBigInt64(reader.offset + i * 12, true)
const high = reader.view.getInt32(reader.offset + i * 12 + 8, true)
values[i] = BigInt(high) << 64n | low
}
reader.offset += count * 12
return values
}
/**
* Read `count` float values.
*
* @param {DataReader} reader
* @param {number} count
* @returns {Float32Array}
*/
function readPlainFloat(reader, count) {
const values = (reader.view.byteOffset + reader.offset) % 4
? new Float32Array(align(reader.view.buffer, reader.view.byteOffset + reader.offset, count * 4))
: new Float32Array(reader.view.buffer, reader.view.byteOffset + reader.offset, count)
reader.offset += count * 4
return values
}
/**
* Read `count` double values.
*
* @param {DataReader} reader
* @param {number} count
* @returns {Float64Array}
*/
function readPlainDouble(reader, count) {
const values = (reader.view.byteOffset + reader.offset) % 8
? new Float64Array(align(reader.view.buffer, reader.view.byteOffset + reader.offset, count * 8))
: new Float64Array(reader.view.buffer, reader.view.byteOffset + reader.offset, count)
reader.offset += count * 8
return values
}
/**
* Read `count` byte array values.
*
* @param {DataReader} reader
* @param {number} count
* @returns {Uint8Array[]}
*/
function readPlainByteArray(reader, count) {
const values = new Array(count)
for (let i = 0; i < count; i++) {
const length = reader.view.getUint32(reader.offset, true)
reader.offset += 4
values[i] = new Uint8Array(reader.view.buffer, reader.view.byteOffset + reader.offset, length)
reader.offset += length
}
return values
}
/**
* Read a fixed length byte array.
*
* @param {DataReader} reader
* @param {number} count
* @param {number} fixedLength
* @returns {Uint8Array[]}
*/
function readPlainByteArrayFixed(reader, count, fixedLength) {
// assert(reader.view.byteLength - reader.offset >= count * fixedLength)
const values = new Array(count)
for (let i = 0; i < count; i++) {
values[i] = new Uint8Array(reader.view.buffer, reader.view.byteOffset + reader.offset, fixedLength)
reader.offset += fixedLength
}
return values
}
/**
* Create a new buffer with the offset and size.
*
* @import {DataReader, DecodedArray, ParquetType} from '../src/types.js'
* @param {ArrayBufferLike} buffer
* @param {number} offset
* @param {number} size
* @returns {ArrayBuffer}
*/
function align(buffer, offset, size) {
const aligned = new ArrayBuffer(size)
new Uint8Array(aligned).set(new Uint8Array(buffer, offset, size))
return aligned
}
|