1// Licensed to the Apache Software Foundation (ASF) under one 2// or more contributor license agreements. See the NOTICE file 3// distributed with this work for additional information 4// regarding copyright ownership. The ASF licenses this file 5// to you under the Apache License, Version 2.0 (the 6// "License"); you may not use this file except in compliance 7// with the License. You may obtain a copy of the License at 8// 9// http://www.apache.org/licenses/LICENSE-2.0 10// 11// Unless required by applicable law or agreed to in writing, 12// software distributed under the License is distributed on an 13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14// KIND, either express or implied. See the License for the 15// specific language governing permissions and limitations 16// under the License. 17 18import { Data } from '../data'; 19import { BN } from '../util/bn'; 20import { Visitor } from '../visitor'; 21import { decodeUtf8 } from '../util/utf8'; 22import { VectorType } from '../interfaces'; 23import { uint16ToFloat64 } from '../util/math'; 24import { Type, UnionMode, Precision, DateUnit, TimeUnit, IntervalUnit } from '../enum'; 25import { 26 DataType, Dictionary, 27 Bool, Null, Utf8, Binary, Decimal, FixedSizeBinary, List, FixedSizeList, Map_, Struct, 28 Float, Float16, Float32, Float64, 29 Int, Uint8, Uint16, Uint32, Uint64, Int8, Int16, Int32, Int64, 30 Date_, DateDay, DateMillisecond, 31 Interval, IntervalDayTime, IntervalYearMonth, 32 Time, TimeSecond, TimeMillisecond, TimeMicrosecond, TimeNanosecond, 33 Timestamp, TimestampSecond, TimestampMillisecond, TimestampMicrosecond, TimestampNanosecond, 34 Union, DenseUnion, SparseUnion, 35} from '../type'; 36 37/** @ignore */ 38export interface GetVisitor extends Visitor { 39 visit<T extends VectorType> (node: T, index: number): T['TValue']; 40 visitMany<T extends VectorType> (nodes: T[], indices: number[]): T['TValue'][]; 41 getVisitFn<T extends Type> (node: T): (vector: VectorType<T>, index: number) => VectorType<T>['TValue']; 42 getVisitFn<T extends DataType>(node: VectorType<T> | Data<T> | T): (vector: VectorType<T>, index: number) => VectorType<T>['TValue']; 43 visitNull <T extends Null> (vector: VectorType<T>, index: number): T['TValue']; 44 visitBool <T extends Bool> (vector: VectorType<T>, index: number): T['TValue']; 45 visitInt <T extends Int> (vector: VectorType<T>, index: number): T['TValue']; 46 visitInt8 <T extends Int8> (vector: VectorType<T>, index: number): T['TValue']; 47 visitInt16 <T extends Int16> (vector: VectorType<T>, index: number): T['TValue']; 48 visitInt32 <T extends Int32> (vector: VectorType<T>, index: number): T['TValue']; 49 visitInt64 <T extends Int64> (vector: VectorType<T>, index: number): T['TValue']; 50 visitUint8 <T extends Uint8> (vector: VectorType<T>, index: number): T['TValue']; 51 visitUint16 <T extends Uint16> (vector: VectorType<T>, index: number): T['TValue']; 52 visitUint32 <T extends Uint32> (vector: VectorType<T>, index: number): T['TValue']; 53 visitUint64 <T extends Uint64> (vector: VectorType<T>, index: number): T['TValue']; 54 visitFloat <T extends Float> (vector: VectorType<T>, index: number): T['TValue']; 55 visitFloat16 <T extends Float16> (vector: VectorType<T>, index: number): T['TValue']; 56 visitFloat32 <T extends Float32> (vector: VectorType<T>, index: number): T['TValue']; 57 visitFloat64 <T extends Float64> (vector: VectorType<T>, index: number): T['TValue']; 58 visitUtf8 <T extends Utf8> (vector: VectorType<T>, index: number): T['TValue']; 59 visitBinary <T extends Binary> (vector: VectorType<T>, index: number): T['TValue']; 60 visitFixedSizeBinary <T extends FixedSizeBinary> (vector: VectorType<T>, index: number): T['TValue']; 61 visitDate <T extends Date_> (vector: VectorType<T>, index: number): T['TValue']; 62 visitDateDay <T extends DateDay> (vector: VectorType<T>, index: number): T['TValue']; 63 visitDateMillisecond <T extends DateMillisecond> (vector: VectorType<T>, index: number): T['TValue']; 64 visitTimestamp <T extends Timestamp> (vector: VectorType<T>, index: number): T['TValue']; 65 visitTimestampSecond <T extends TimestampSecond> (vector: VectorType<T>, index: number): T['TValue']; 66 visitTimestampMillisecond <T extends TimestampMillisecond> (vector: VectorType<T>, index: number): T['TValue']; 67 visitTimestampMicrosecond <T extends TimestampMicrosecond> (vector: VectorType<T>, index: number): T['TValue']; 68 visitTimestampNanosecond <T extends TimestampNanosecond> (vector: VectorType<T>, index: number): T['TValue']; 69 visitTime <T extends Time> (vector: VectorType<T>, index: number): T['TValue']; 70 visitTimeSecond <T extends TimeSecond> (vector: VectorType<T>, index: number): T['TValue']; 71 visitTimeMillisecond <T extends TimeMillisecond> (vector: VectorType<T>, index: number): T['TValue']; 72 visitTimeMicrosecond <T extends TimeMicrosecond> (vector: VectorType<T>, index: number): T['TValue']; 73 visitTimeNanosecond <T extends TimeNanosecond> (vector: VectorType<T>, index: number): T['TValue']; 74 visitDecimal <T extends Decimal> (vector: VectorType<T>, index: number): T['TValue']; 75 visitList <T extends List> (vector: VectorType<T>, index: number): T['TValue']; 76 visitStruct <T extends Struct> (vector: VectorType<T>, index: number): T['TValue']; 77 visitUnion <T extends Union> (vector: VectorType<T>, index: number): T['TValue']; 78 visitDenseUnion <T extends DenseUnion> (vector: VectorType<T>, index: number): T['TValue']; 79 visitSparseUnion <T extends SparseUnion> (vector: VectorType<T>, index: number): T['TValue']; 80 visitDictionary <T extends Dictionary> (vector: VectorType<T>, index: number): T['TValue']; 81 visitInterval <T extends Interval> (vector: VectorType<T>, index: number): T['TValue']; 82 visitIntervalDayTime <T extends IntervalDayTime> (vector: VectorType<T>, index: number): T['TValue']; 83 visitIntervalYearMonth <T extends IntervalYearMonth> (vector: VectorType<T>, index: number): T['TValue']; 84 visitFixedSizeList <T extends FixedSizeList> (vector: VectorType<T>, index: number): T['TValue']; 85 visitMap <T extends Map_> (vector: VectorType<T>, index: number): T['TValue']; 86} 87 88/** @ignore */ 89export class GetVisitor extends Visitor {} 90 91/** @ignore */const epochDaysToMs = (data: Int32Array, index: number) => 86400000 * data[index]; 92/** @ignore */const epochMillisecondsLongToMs = (data: Int32Array, index: number) => 4294967296 * (data[index + 1]) + (data[index] >>> 0); 93/** @ignore */const epochMicrosecondsLongToMs = (data: Int32Array, index: number) => 4294967296 * (data[index + 1] / 1000) + ((data[index] >>> 0) / 1000); 94/** @ignore */const epochNanosecondsLongToMs = (data: Int32Array, index: number) => 4294967296 * (data[index + 1] / 1000000) + ((data[index] >>> 0) / 1000000); 95 96/** @ignore */const epochMillisecondsToDate = (epochMs: number) => new Date(epochMs); 97/** @ignore */const epochDaysToDate = (data: Int32Array, index: number) => epochMillisecondsToDate(epochDaysToMs(data, index)); 98/** @ignore */const epochMillisecondsLongToDate = (data: Int32Array, index: number) => epochMillisecondsToDate(epochMillisecondsLongToMs(data, index)); 99 100/** @ignore */ 101const getNull = <T extends Null>(_vector: VectorType<T>, _index: number): T['TValue'] => null; 102/** @ignore */ 103const getVariableWidthBytes = (values: Uint8Array, valueOffsets: Int32Array, index: number) => { 104 const { [index]: x, [index + 1]: y } = valueOffsets; 105 return x != null && y != null ? values.subarray(x, y) : null as any; 106}; 107 108/** @ignore */ 109const getBool = <T extends Bool>({ offset, values }: VectorType<T>, index: number): T['TValue'] => { 110 const idx = offset + index; 111 const byte = values[idx >> 3]; 112 return (byte & 1 << (idx % 8)) !== 0; 113}; 114 115/** @ignore */ 116type Numeric1X = Int8 | Int16 | Int32 | Uint8 | Uint16 | Uint32 | Float32 | Float64; 117/** @ignore */ 118type Numeric2X = Int64 | Uint64; 119 120/** @ignore */ 121const getDateDay = <T extends DateDay> ({ values }: VectorType<T>, index: number): T['TValue'] => epochDaysToDate(values, index); 122/** @ignore */ 123const getDateMillisecond = <T extends DateMillisecond>({ values }: VectorType<T>, index: number): T['TValue'] => epochMillisecondsLongToDate(values, index * 2); 124/** @ignore */ 125const getNumeric = <T extends Numeric1X> ({ stride, values }: VectorType<T>, index: number): T['TValue'] => values[stride * index]; 126/** @ignore */ 127const getFloat16 = <T extends Float16> ({ stride, values }: VectorType<T>, index: number): T['TValue'] => uint16ToFloat64(values[stride * index]); 128/** @ignore */ 129const getBigInts = <T extends Numeric2X>({ stride, values, type }: VectorType<T>, index: number): T['TValue'] => <any> BN.new(values.subarray(stride * index, stride * (index + 1)), type.isSigned); 130/** @ignore */ 131const getFixedSizeBinary = <T extends FixedSizeBinary>({ stride, values }: VectorType<T>, index: number): T['TValue'] => values.subarray(stride * index, stride * (index + 1)); 132 133/** @ignore */ 134const getBinary = <T extends Binary>({ values, valueOffsets }: VectorType<T>, index: number): T['TValue'] => getVariableWidthBytes(values, valueOffsets, index); 135/** @ignore */ 136const getUtf8 = <T extends Utf8>({ values, valueOffsets }: VectorType<T>, index: number): T['TValue'] => { 137 const bytes = getVariableWidthBytes(values, valueOffsets, index); 138 return bytes !== null ? decodeUtf8(bytes) : null as any; 139}; 140 141/* istanbul ignore next */ 142/** @ignore */ 143const getInt = <T extends Int>(vector: VectorType<T>, index: number): T['TValue'] => ( 144 vector.type.bitWidth < 64 145 ? getNumeric(vector as VectorType<Numeric1X>, index) 146 : getBigInts(vector as VectorType<Numeric2X>, index) 147); 148 149/* istanbul ignore next */ 150/** @ignore */ 151const getFloat = <T extends Float> (vector: VectorType<T>, index: number): T['TValue'] => ( 152 vector.type.precision !== Precision.HALF 153 ? getNumeric(vector as VectorType<Numeric1X>, index) 154 : getFloat16(vector as VectorType<Float16>, index) 155); 156 157/* istanbul ignore next */ 158/** @ignore */ 159const getDate = <T extends Date_> (vector: VectorType<T>, index: number): T['TValue'] => ( 160 vector.type.unit === DateUnit.DAY 161 ? getDateDay(vector as VectorType<DateDay>, index) 162 : getDateMillisecond(vector as VectorType<DateMillisecond>, index) 163); 164 165/** @ignore */ 166const getTimestampSecond = <T extends TimestampSecond> ({ values }: VectorType<T>, index: number): T['TValue'] => 1000 * epochMillisecondsLongToMs(values, index * 2); 167/** @ignore */ 168const getTimestampMillisecond = <T extends TimestampMillisecond>({ values }: VectorType<T>, index: number): T['TValue'] => epochMillisecondsLongToMs(values, index * 2); 169/** @ignore */ 170const getTimestampMicrosecond = <T extends TimestampMicrosecond>({ values }: VectorType<T>, index: number): T['TValue'] => epochMicrosecondsLongToMs(values, index * 2); 171/** @ignore */ 172const getTimestampNanosecond = <T extends TimestampNanosecond> ({ values }: VectorType<T>, index: number): T['TValue'] => epochNanosecondsLongToMs(values, index * 2); 173/* istanbul ignore next */ 174/** @ignore */ 175const getTimestamp = <T extends Timestamp>(vector: VectorType<T>, index: number): T['TValue'] => { 176 switch (vector.type.unit) { 177 case TimeUnit.SECOND: return getTimestampSecond(vector as VectorType<TimestampSecond>, index); 178 case TimeUnit.MILLISECOND: return getTimestampMillisecond(vector as VectorType<TimestampMillisecond>, index); 179 case TimeUnit.MICROSECOND: return getTimestampMicrosecond(vector as VectorType<TimestampMicrosecond>, index); 180 case TimeUnit.NANOSECOND: return getTimestampNanosecond(vector as VectorType<TimestampNanosecond>, index); 181 } 182}; 183 184/** @ignore */ 185const getTimeSecond = <T extends TimeSecond> ({ values, stride }: VectorType<T>, index: number): T['TValue'] => values[stride * index]; 186/** @ignore */ 187const getTimeMillisecond = <T extends TimeMillisecond>({ values, stride }: VectorType<T>, index: number): T['TValue'] => values[stride * index]; 188/** @ignore */ 189const getTimeMicrosecond = <T extends TimeMicrosecond>({ values }: VectorType<T>, index: number): T['TValue'] => BN.signed(values.subarray(2 * index, 2 * (index + 1))); 190/** @ignore */ 191const getTimeNanosecond = <T extends TimeNanosecond> ({ values }: VectorType<T>, index: number): T['TValue'] => BN.signed(values.subarray(2 * index, 2 * (index + 1))); 192/* istanbul ignore next */ 193/** @ignore */ 194const getTime = <T extends Time>(vector: VectorType<T>, index: number): T['TValue'] => { 195 switch (vector.type.unit) { 196 case TimeUnit.SECOND: return getTimeSecond(vector as VectorType<TimeSecond>, index); 197 case TimeUnit.MILLISECOND: return getTimeMillisecond(vector as VectorType<TimeMillisecond>, index); 198 case TimeUnit.MICROSECOND: return getTimeMicrosecond(vector as VectorType<TimeMicrosecond>, index); 199 case TimeUnit.NANOSECOND: return getTimeNanosecond(vector as VectorType<TimeNanosecond>, index); 200 } 201}; 202 203/** @ignore */ 204const getDecimal = <T extends Decimal>({ values }: VectorType<T>, index: number): T['TValue'] => BN.decimal(values.subarray(4 * index, 4 * (index + 1))); 205 206/** @ignore */ 207const getList = <T extends List>(vector: VectorType<T>, index: number): T['TValue'] => { 208 const child = vector.getChildAt(0)!, { valueOffsets, stride } = vector; 209 return child.slice(valueOffsets[index * stride], valueOffsets[(index * stride) + 1]) as T['TValue']; 210}; 211 212/** @ignore */ 213const getMap = <T extends Map_>(vector: VectorType<T>, index: number): T['TValue'] => { 214 return vector.bind(index) as T['TValue']; 215}; 216 217/** @ignore */ 218const getStruct = <T extends Struct>(vector: VectorType<T>, index: number): T['TValue'] => { 219 return vector.bind(index) as T['TValue']; 220}; 221 222/* istanbul ignore next */ 223/** @ignore */ 224const getUnion = < 225 V extends VectorType<Union> | VectorType<DenseUnion> | VectorType<SparseUnion> 226>(vector: V, index: number): V['TValue'] => { 227 return vector.type.mode === UnionMode.Dense ? 228 getDenseUnion(vector as VectorType<DenseUnion>, index) : 229 getSparseUnion(vector as VectorType<SparseUnion>, index); 230}; 231 232/** @ignore */ 233const getDenseUnion = <T extends DenseUnion>(vector: VectorType<T>, index: number): T['TValue'] => { 234 const childIndex = vector.typeIdToChildIndex[vector.typeIds[index]]; 235 const child = vector.getChildAt(childIndex); 236 return child ? child.get(vector.valueOffsets[index]) : null; 237}; 238 239/** @ignore */ 240const getSparseUnion = <T extends SparseUnion>(vector: VectorType<T>, index: number): T['TValue'] => { 241 const childIndex = vector.typeIdToChildIndex[vector.typeIds[index]]; 242 const child = vector.getChildAt(childIndex); 243 return child ? child.get(index) : null; 244}; 245 246/** @ignore */ 247const getDictionary = <T extends Dictionary>(vector: VectorType<T>, index: number): T['TValue'] => { 248 return vector.getValue(vector.getKey(index)!); 249}; 250 251/* istanbul ignore next */ 252/** @ignore */ 253const getInterval = <T extends Interval>(vector: VectorType<T>, index: number): T['TValue'] => 254 (vector.type.unit === IntervalUnit.DAY_TIME) 255 ? getIntervalDayTime(vector as VectorType<IntervalDayTime>, index) 256 : getIntervalYearMonth(vector as VectorType<IntervalYearMonth>, index); 257 258/** @ignore */ 259const getIntervalDayTime = <T extends IntervalDayTime>({ values }: VectorType<T>, index: number): T['TValue'] => values.subarray(2 * index, 2 * (index + 1)); 260 261/** @ignore */ 262const getIntervalYearMonth = <T extends IntervalYearMonth>({ values }: VectorType<T>, index: number): T['TValue'] => { 263 const interval = values[index]; 264 const int32s = new Int32Array(2); 265 int32s[0] = interval / 12 | 0; /* years */ 266 int32s[1] = interval % 12 | 0; /* months */ 267 return int32s; 268}; 269 270/** @ignore */ 271const getFixedSizeList = <T extends FixedSizeList>(vector: VectorType<T>, index: number): T['TValue'] => { 272 const child = vector.getChildAt(0)!, { stride } = vector; 273 return child.slice(index * stride, (index + 1) * stride) as T['TValue']; 274}; 275 276GetVisitor.prototype.visitNull = getNull; 277GetVisitor.prototype.visitBool = getBool; 278GetVisitor.prototype.visitInt = getInt; 279GetVisitor.prototype.visitInt8 = getNumeric; 280GetVisitor.prototype.visitInt16 = getNumeric; 281GetVisitor.prototype.visitInt32 = getNumeric; 282GetVisitor.prototype.visitInt64 = getBigInts; 283GetVisitor.prototype.visitUint8 = getNumeric; 284GetVisitor.prototype.visitUint16 = getNumeric; 285GetVisitor.prototype.visitUint32 = getNumeric; 286GetVisitor.prototype.visitUint64 = getBigInts; 287GetVisitor.prototype.visitFloat = getFloat; 288GetVisitor.prototype.visitFloat16 = getFloat16; 289GetVisitor.prototype.visitFloat32 = getNumeric; 290GetVisitor.prototype.visitFloat64 = getNumeric; 291GetVisitor.prototype.visitUtf8 = getUtf8; 292GetVisitor.prototype.visitBinary = getBinary; 293GetVisitor.prototype.visitFixedSizeBinary = getFixedSizeBinary; 294GetVisitor.prototype.visitDate = getDate; 295GetVisitor.prototype.visitDateDay = getDateDay; 296GetVisitor.prototype.visitDateMillisecond = getDateMillisecond; 297GetVisitor.prototype.visitTimestamp = getTimestamp; 298GetVisitor.prototype.visitTimestampSecond = getTimestampSecond; 299GetVisitor.prototype.visitTimestampMillisecond = getTimestampMillisecond; 300GetVisitor.prototype.visitTimestampMicrosecond = getTimestampMicrosecond; 301GetVisitor.prototype.visitTimestampNanosecond = getTimestampNanosecond; 302GetVisitor.prototype.visitTime = getTime; 303GetVisitor.prototype.visitTimeSecond = getTimeSecond; 304GetVisitor.prototype.visitTimeMillisecond = getTimeMillisecond; 305GetVisitor.prototype.visitTimeMicrosecond = getTimeMicrosecond; 306GetVisitor.prototype.visitTimeNanosecond = getTimeNanosecond; 307GetVisitor.prototype.visitDecimal = getDecimal; 308GetVisitor.prototype.visitList = getList; 309GetVisitor.prototype.visitStruct = getStruct; 310GetVisitor.prototype.visitUnion = getUnion; 311GetVisitor.prototype.visitDenseUnion = getDenseUnion; 312GetVisitor.prototype.visitSparseUnion = getSparseUnion; 313GetVisitor.prototype.visitDictionary = getDictionary; 314GetVisitor.prototype.visitInterval = getInterval; 315GetVisitor.prototype.visitIntervalDayTime = getIntervalDayTime; 316GetVisitor.prototype.visitIntervalYearMonth = getIntervalYearMonth; 317GetVisitor.prototype.visitFixedSizeList = getFixedSizeList; 318GetVisitor.prototype.visitMap = getMap; 319 320/** @ignore */ 321export const instance = new GetVisitor(); 322