From 708f1b4e77bcb99336d4fca3d5663af96d75c8ca Mon Sep 17 00:00:00 2001 From: ptaylor Date: Wed, 9 Jan 2019 09:34:26 -0800 Subject: [PATCH] move stride to data, fix chunked slicing, remove intermediate binding and getters in favor of direct property accesses --- js/src/data.ts | 163 +++++++++++++++++-------------- js/src/recordbatch.ts | 2 +- js/src/vector/base.ts | 52 +++++----- js/src/vector/chunked.ts | 16 +-- js/src/vector/date.ts | 4 +- js/src/vector/decimal.ts | 7 +- js/src/vector/dictionary.ts | 4 +- js/src/vector/fixedsizebinary.ts | 4 - js/src/vector/fixedsizelist.ts | 4 - js/src/vector/index.ts | 13 +-- js/src/vector/int.ts | 3 - js/src/vector/interval.ts | 8 +- js/src/vector/time.ts | 7 +- js/src/vector/timestamp.ts | 7 +- js/src/visitor/bytewidth.ts | 10 +- 15 files changed, 139 insertions(+), 165 deletions(-) diff --git a/js/src/data.ts b/js/src/data.ts index 04f80a2ffcfe6..0c99036dbc294 100644 --- a/js/src/data.ts +++ b/js/src/data.ts @@ -15,11 +15,11 @@ // specific language governing permissions and limitations // under the License. -import { DataType } from './type'; import { Vector } from './vector'; import { popcnt_bit_range } from './util/bit'; import { toArrayBufferView } from './util/buffer'; -import { VectorType as BufferType, UnionMode } from './enum'; +import { DataType, SparseUnion, DenseUnion } from './type'; +import { VectorType as BufferType, UnionMode, Type } from './enum'; import { Dictionary, Null, Int, Float, @@ -30,7 +30,7 @@ import { // When slicing, we do not know the null count of the sliced range without // doing some computation. To avoid doing this eagerly, we set the null count -// to -1 (any negative number will do). When Array::null_count is called the +// to -1 (any negative number will do). When Vector.nullCount is called the // first time, the null count will be computed. See ARROW-33 /** @ignore */ export type kUnknownNullCount = -1; /** @ignore */ export const kUnknownNullCount = -1; @@ -42,12 +42,13 @@ import { /** @ignore */ export interface Buffers { - [BufferType.OFFSET]?: Int32Array; - [BufferType.DATA]?: T['TArray']; - [BufferType.VALIDITY]?: Uint8Array; - [BufferType.TYPE]?: T['TArray']; + [BufferType.OFFSET]: Int32Array; + [BufferType.DATA]: T['TArray']; + [BufferType.VALIDITY]: Uint8Array; + [BufferType.TYPE]: T['TArray']; } +/** @ignore */ export interface Data { readonly TType: T['TType']; readonly TArray: T['TArray']; @@ -57,47 +58,71 @@ export interface Data { /** @ignore */ export class Data { - protected _type: T; - protected _length: number; - protected _offset: number; - + public readonly type: T; + public readonly length: number; + public readonly offset: number; + public readonly stride: number; + public readonly childData: Data[]; + public readonly values: Buffers[BufferType.DATA]; + public readonly typeIds: Buffers[BufferType.TYPE]; // @ts-ignore - protected _childData: Data[]; - protected _buffers = [] as Buffers; - protected _nullCount: number | kUnknownNullCount; - - public get type() { return this._type; } - public get length() { return this._length; } - public get offset() { return this._offset; } - public get typeId() { return this._type.typeId; } - public get childData() { return this._childData; } + public readonly nullBitmap: Buffers[BufferType.VALIDITY]; + // @ts-ignore + public readonly valueOffsets: Buffers[BufferType.OFFSET]; + + public get ArrayType() { return this.type.ArrayType; } + public get typeId(): T['TType'] { return this.type.typeId; } + public get buffers() { + return [this.valueOffsets, this.values, this.nullBitmap, this.typeIds] as Buffers; + } - public get ArrayType() { return this._type.ArrayType; } + protected _nullCount: number | kUnknownNullCount; - public get buffers() { return this._buffers; } - public get values() { return this._buffers[BufferType.DATA]!; } - public get typeIds() { return this._buffers[BufferType.TYPE]!; } - public get nullBitmap() { return this._buffers[BufferType.VALIDITY]!; } - public get valueOffsets() { return this._buffers[BufferType.OFFSET]!; } public get nullCount() { let nullCount = this._nullCount; let nullBitmap: Uint8Array | undefined; - if (nullCount === kUnknownNullCount && (nullBitmap = this._buffers[BufferType.VALIDITY])) { - this._nullCount = nullCount = this._length - popcnt_bit_range(nullBitmap, this._offset, this._offset + this._length); + if (nullCount <= kUnknownNullCount && (nullBitmap = this.nullBitmap)) { + this._nullCount = nullCount = this.length - popcnt_bit_range(nullBitmap, this.offset, this.offset + this.length); } return nullCount; } - constructor(type: T, offset: number, length: number, nullCount?: number, buffers?: Buffers, childData?: (Data | Vector)[]) { - this._type = type; - this._offset = Math.floor(Math.max(offset || 0, 0)); - this._length = Math.floor(Math.max(length || 0, 0)); - this._buffers = Object.assign([], buffers) as Buffers; + constructor(type: T, offset: number, length: number, nullCount?: number, buffers?: Partial> | Data, childData?: (Data | Vector)[]) { + this.type = type; + this.offset = Math.floor(Math.max(offset || 0, 0)); + this.length = Math.floor(Math.max(length || 0, 0)); this._nullCount = Math.floor(Math.max(nullCount || 0, -1)); - this._childData = (childData || []).map((x) => x instanceof Data ? x : x.data) as Data[]; + this.childData = (childData || []).map((x) => x instanceof Data ? x : x.data) as Data[]; + let buffer: Buffers[keyof Buffers]; + if (buffers instanceof Data) { + this.stride = buffers.stride; + this.values = buffers.values; + this.typeIds = buffers.typeIds; + this.nullBitmap = buffers.nullBitmap; + this.valueOffsets = buffers.valueOffsets; + } else { + if (buffers) { + (buffer = (buffers as Buffers)[0]) && (this.valueOffsets = buffer); + (buffer = (buffers as Buffers)[1]) && (this.values = buffer); + (buffer = (buffers as Buffers)[2]) && (this.nullBitmap = buffer); + (buffer = (buffers as Buffers)[3]) && (this.typeIds = buffer); + } + const t: any = type; + switch (type.typeId) { + case Type.Decimal: this.stride = 4; break; + case Type.Timestamp: this.stride = 2; break; + case Type.Date: this.stride = 1 + (t as Date_).unit; break; + case Type.Interval: this.stride = 1 + (t as Interval).unit; break; + case Type.Int: this.stride = 1 + +((t as Int).bitWidth > 32); break; + case Type.Time: this.stride = 1 + +((t as Time).bitWidth > 32); break; + case Type.FixedSizeList: this.stride = (t as FixedSizeList).listSize; break; + case Type.FixedSizeBinary: this.stride = (t as FixedSizeBinary).byteWidth; break; + default: this.stride = 1; + } + } } - public clone(type: R, offset = this._offset, length = this._length, nullCount = this._nullCount, buffers: Buffers = this._buffers, childData: (Data | Vector)[] = this._childData) { + public clone(type: R, offset = this.offset, length = this.length, nullCount = this._nullCount, buffers: Buffers = this, childData: (Data | Vector)[] = this.childData) { return new Data(type, offset, length, nullCount, buffers, childData); } @@ -105,38 +130,28 @@ export class Data { // +true === 1, +false === 0, so this means // we keep nullCount at 0 if it's already 0, // otherwise set to the invalidated flag -1 + const { stride, typeId, childData } = this; const nullCount = +(this._nullCount === 0) - 1; - const buffers = this.sliceBuffers(offset, length); - const childData = this.sliceChildren(offset, length); - return this.clone(this._type, this._offset + offset, length, nullCount, buffers, childData); + const childStride = typeId === 16 /* FixedSizeList */ ? stride : 1; + const buffers = this._sliceBuffers(offset, length, stride, typeId); + return this.clone(this.type, this.offset + offset, length, nullCount, buffers, + // Don't slice children if we have value offsets (the variable-width types) + (!childData.length || this.valueOffsets) ? childData : this._sliceChildren(childData, childStride * offset, childStride * length)); } - protected sliceBuffers(offset: number, length: number): Buffers { - let arr: any, buffers = Object.assign([], this._buffers) as Buffers; + protected _sliceBuffers(offset: number, length: number, stride: number, typeId: T['TType']): Buffers { + let arr: any, { buffers } = this; // If typeIds exist, slice the typeIds buffer - (arr = buffers[BufferType.TYPE]) && (buffers[BufferType.TYPE] = this.sliceData(arr, offset, length)); + (arr = buffers[BufferType.TYPE]) && (buffers[BufferType.TYPE] = arr.subarray(offset, offset + length)); // If offsets exist, only slice the offsets buffer - (arr = buffers[BufferType.OFFSET]) && (buffers[BufferType.OFFSET] = this.sliceOffsets(arr, offset, length)) || - // Otherwise if no offsets, slice the data buffer - (arr = buffers[BufferType.DATA]) && (buffers[BufferType.DATA] = this.sliceData(arr, offset, length)); + (arr = buffers[BufferType.OFFSET]) && (buffers[BufferType.OFFSET] = arr.subarray(offset, offset + length + 1)) || + // Otherwise if no offsets, slice the data buffer. Don't slice the data vector for Booleans, since the offset goes by bits not bytes + (arr = buffers[BufferType.DATA]) && (buffers[BufferType.DATA] = typeId === 6 ? arr : arr.subarray(stride * offset, stride * (offset + length))); return buffers; } - protected sliceChildren(offset: number, length: number): Data[] { - // Only slice children if this isn't variable width data - if (!this._buffers[BufferType.OFFSET]) { - return this._childData.map((child) => child.slice(offset, length)); - } - return this._childData; - } - - protected sliceData(data: T['TArray'] & ArrayBufferView, offset: number, length: number) { - // Don't slice the data vector for Booleans, since the offset goes by bits not bytes - return this._type.typeId === 6 ? data : data.subarray(offset, offset + length); - } - - protected sliceOffsets(valueOffsets: Int32Array, offset: number, length: number) { - return valueOffsets.subarray(offset, offset + length + 1); + protected _sliceChildren(childData: Data[], offset: number, length: number): Data[] { + return childData.map((child) => child.slice(offset, length)); } // @@ -235,40 +250,44 @@ export class Data { }); } /** @nocollapse */ - public static List(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, valueOffsets: ValueOffsetsBuffer, childData: Data | Vector) { + public static List(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, valueOffsets: ValueOffsetsBuffer, child: Data | Vector) { return new Data(type, offset, length, nullCount, { [BufferType.VALIDITY]: toArrayBufferView(Uint8Array, nullBitmap), [BufferType.OFFSET]: toArrayBufferView(Int32Array, valueOffsets) - }, [childData]); + }, [child]); } /** @nocollapse */ - public static FixedSizeList(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, childData: Data | Vector) { + public static FixedSizeList(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, child: Data | Vector) { return new Data(type, offset, length, nullCount, { [BufferType.VALIDITY]: toArrayBufferView(Uint8Array, nullBitmap) - }, [childData]); + }, [child]); } /** @nocollapse */ - public static Struct(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, childData: (Data | Vector)[]) { + public static Struct(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, children: (Data | Vector)[]) { return new Data(type, offset, length, nullCount, { [BufferType.VALIDITY]: toArrayBufferView(Uint8Array, nullBitmap) - }, childData); + }, children); } /** @nocollapse */ - public static Map(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, childData: (Data | Vector)[]) { + public static Map(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, children: (Data | Vector)[]) { return new Data(type, offset, length, nullCount, { [BufferType.VALIDITY]: toArrayBufferView(Uint8Array, nullBitmap) - }, childData); + }, children); } + public static Union(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, typeIds: TypeIdsBuffer, children: (Data | Vector)[]): Data; + public static Union(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, typeIds: TypeIdsBuffer, valueOffsets: ValueOffsetsBuffer, children: (Data | Vector)[]): Data; /** @nocollapse */ - public static Union(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, typeIds: TypeIdsBuffer, valueOffsetsOrChildData: ValueOffsetsBuffer | (Data | Vector)[], childData?: (Data | Vector)[]) { + public static Union(type: T, offset: number, length: number, nullCount: number, nullBitmap: NullBuffer, typeIds: TypeIdsBuffer, valueOffsetsOrChildren: ValueOffsetsBuffer | (Data | Vector)[], children?: (Data | Vector)[]) { const buffers = { [BufferType.VALIDITY]: toArrayBufferView(Uint8Array, nullBitmap), [BufferType.TYPE]: toArrayBufferView(type.ArrayType, typeIds) - } as any; + } as Partial>; if (type.mode === UnionMode.Sparse) { - return new Data(type, offset, length, nullCount, buffers, valueOffsetsOrChildData as (Data | Vector)[]); + return new Data(type, offset, length, nullCount, buffers, valueOffsetsOrChildren as (Data | Vector)[]); } - buffers[BufferType.OFFSET] = toArrayBufferView(Int32Array, valueOffsetsOrChildData); - return new Data(type, offset, length, nullCount, buffers, childData); + buffers[BufferType.OFFSET] = toArrayBufferView(Int32Array, valueOffsetsOrChildren); + return new Data(type, offset, length, nullCount, buffers, children); } } + +((Data.prototype as any).childData = Object.freeze([])); diff --git a/js/src/recordbatch.ts b/js/src/recordbatch.ts index 28aefffbfbe96..6a94a8cb583e6 100644 --- a/js/src/recordbatch.ts +++ b/js/src/recordbatch.ts @@ -81,7 +81,7 @@ export class RecordBatch const fields = this._schema.fields; const schema = this._schema.select(...columnNames); const childNames = columnNames.reduce((xs, x) => (xs[x] = true) && xs, {}); - const childData = this._data.childData.filter((_, i) => childNames[fields[i].name]); + const childData = this.data.childData.filter((_, i) => childNames[fields[i].name]); const structData = Data.Struct(new Struct(schema.fields), 0, this.length, 0, null, childData); return new RecordBatch<{ [P in K]: T[P] }>(schema, structData as Data>); } diff --git a/js/src/vector/base.ts b/js/src/vector/base.ts index b16ea27754172..f552fedb11074 100644 --- a/js/src/vector/base.ts +++ b/js/src/vector/base.ts @@ -26,48 +26,43 @@ import { Clonable, Sliceable, Applicative } from '../vector'; export interface BaseVector extends Clonable>, Sliceable>, Applicative> { slice(begin?: number, end?: number): VType; concat(...others: Vector[]): Chunked; - clone(data: Data, children?: Vector[], stride?: number): VType; + clone(data: Data, children?: Vector[]): VType; } export abstract class BaseVector extends Vector implements Clonable>, Sliceable>, Applicative> { - // @ts-ignore - protected _data: Data; - protected _stride: number = 1; - protected _numChildren: number = 0; protected _children?: Vector[]; - constructor(data: Data, children?: Vector[], stride?: number) { + constructor(data: Data, children?: Vector[]) { super(); this._children = children; - this._numChildren = data.childData.length; - this._bindDataAccessors(this._data = data); - this._stride = Math.floor(Math.max(stride || 1, 1)); + this.numChildren = data.childData.length; + this._bindDataAccessors(this.data = data); } - public get data() { return this._data; } - public get stride() { return this._stride; } - public get numChildren() { return this._numChildren; } + public readonly data: Data; + public readonly numChildren: number; - public get type() { return this._data.type; } - public get typeId() { return this._data.typeId as T['TType']; } - public get length() { return this._data.length; } - public get offset() { return this._data.offset; } - public get nullCount() { return this._data.nullCount; } + public get type() { return this.data.type; } + public get typeId() { return this.data.typeId; } + public get length() { return this.data.length; } + public get offset() { return this.data.offset; } + public get stride() { return this.data.stride; } + public get nullCount() { return this.data.nullCount; } public get VectorName() { return this.constructor.name; } - public get ArrayType(): T['ArrayType'] { return this._data.ArrayType; } + public get ArrayType(): T['ArrayType'] { return this.data.ArrayType; } - public get values() { return this._data.values; } - public get typeIds() { return this._data.typeIds; } - public get nullBitmap() { return this._data.nullBitmap; } - public get valueOffsets() { return this._data.valueOffsets; } + public get values() { return this.data.values; } + public get typeIds() { return this.data.typeIds; } + public get nullBitmap() { return this.data.nullBitmap; } + public get valueOffsets() { return this.data.valueOffsets; } public get [Symbol.toStringTag]() { return `${this.VectorName}<${this.type[Symbol.toStringTag]}>`; } - public clone(data: Data, children = this._children, stride = this._stride) { - return Vector.new(data, children, stride) as any; + public clone(data: Data, children = this._children) { + return Vector.new(data, children) as any; } public concat(...others: Vector[]) { @@ -94,16 +89,15 @@ export abstract class BaseVector extends Vector public getChildAt(index: number): Vector | null { return index < 0 || index >= this.numChildren ? null : ( (this._children || (this._children = []))[index] || - (this._children[index] = Vector.new(this._data.childData[index] as Data)) + (this._children[index] = Vector.new(this.data.childData[index] as Data)) ) as Vector; } // @ts-ignore public toJSON(): any { return [...this]; } - protected _sliceInternal(self: this, offset: number, length: number) { - const stride = self.stride; - return self.clone(self.data.slice(offset * stride, (length - offset) * stride)); + protected _sliceInternal(self: this, begin: number, end: number) { + return self.clone(self.data.slice(begin, end - begin)); } // @ts-ignore @@ -111,3 +105,5 @@ export abstract class BaseVector extends Vector // Implementation in src/vectors/index.ts due to circular dependency/packaging shenanigans } } + +(BaseVector.prototype as any)[Symbol.isConcatSpreadable] = true; diff --git a/js/src/vector/chunked.ts b/js/src/vector/chunked.ts index 057322fb71175..9665b6c5bd046 100644 --- a/js/src/vector/chunked.ts +++ b/js/src/vector/chunked.ts @@ -27,7 +27,7 @@ type ChunkedDict = T extends Dictionary ? T['dictionaryVecto type ChunkedKeys = T extends Dictionary ? Vector | Chunked : null | never; /** @ignore */ -type SearchContinuation = (column: T, chunkIndex: number, valueIndex: number) => any; +export type SearchContinuation = (column: T, chunkIndex: number, valueIndex: number) => any; /** @ignore */ export class Chunked @@ -218,7 +218,7 @@ export class Chunked return -1; } - protected _sliceInternal(self: Chunked, offset: number, length: number) { + protected _sliceInternal(self: Chunked, begin: number, end: number) { const slices: Vector[] = []; const { chunks, _chunkOffsets: chunkOffsets } = self; for (let i = -1, n = chunks.length; ++i < n;) { @@ -226,18 +226,18 @@ export class Chunked const chunkLength = chunk.length; const chunkOffset = chunkOffsets[i]; // If the child is to the right of the slice boundary, we can stop - if (chunkOffset >= offset + length) { continue; } + if (chunkOffset >= end) { break; } // If the child is to the left of of the slice boundary, exclude - if (offset >= chunkOffset + chunkLength) { continue; } + if (begin >= chunkOffset + chunkLength) { continue; } // If the child is between both left and right boundaries, include w/o slicing - if (chunkOffset >= offset && (chunkOffset + chunkLength) <= offset + length) { + if (chunkOffset >= begin && (chunkOffset + chunkLength) <= end) { slices.push(chunk); continue; } // If the child overlaps one of the slice boundaries, include that slice - const begin = Math.max(0, offset - chunkOffset); - const end = begin + Math.min(chunkLength - begin, (offset + length) - chunkOffset); - slices.push(chunk.slice(begin, end) as Vector); + const from = Math.max(0, begin - chunkOffset); + const to = from + Math.min(chunkLength - from, end - chunkOffset); + slices.push(chunk.slice(from, to) as Vector); } return self.clone(slices); } diff --git a/js/src/vector/date.ts b/js/src/vector/date.ts index 95426c962f95b..cca31a57fbbce 100644 --- a/js/src/vector/date.ts +++ b/js/src/vector/date.ts @@ -37,9 +37,7 @@ export class DateVector extends BaseVector { } throw new TypeError(`Unrecognized date unit "${DateUnit[unit]}"`); } - constructor(data: Data) { - super(data, undefined, data.type.unit + 1); - } } + export class DateDayVector extends DateVector {} export class DateMillisecondVector extends DateVector {} diff --git a/js/src/vector/decimal.ts b/js/src/vector/decimal.ts index 703a575e75b5a..fd197508660a8 100644 --- a/js/src/vector/decimal.ts +++ b/js/src/vector/decimal.ts @@ -15,12 +15,7 @@ // specific language governing permissions and limitations // under the License. -import { Data } from '../data'; import { Decimal } from '../type'; import { BaseVector } from './base'; -export class DecimalVector extends BaseVector { - constructor(data: Data) { - super(data, undefined, 4); - } -} +export class DecimalVector extends BaseVector {} diff --git a/js/src/vector/dictionary.ts b/js/src/vector/dictionary.ts index 7de8220afeca4..ef3378c2dc762 100644 --- a/js/src/vector/dictionary.ts +++ b/js/src/vector/dictionary.ts @@ -32,12 +32,12 @@ export class DictionaryVector; constructor(data: Data>) { - super(data, void 0, 1); + super(data); this._indices = Vector.new(data.clone(this.type.indices)); } // protected _bindDataAccessors() {} public get indices() { return this._indices; } - public get dictionary() { return this._data.type.dictionaryVector; } + public get dictionary() { return this.data.type.dictionaryVector; } public isValid(index: number) { return this._indices.isValid(index); } public reverseLookup(value: T) { return this.dictionary.indexOf(value); } public getKey(idx: number): TKey['TValue'] | null { return this._indices.get(idx); } diff --git a/js/src/vector/fixedsizebinary.ts b/js/src/vector/fixedsizebinary.ts index 76c00cd9960d9..b474d2a8c5880 100644 --- a/js/src/vector/fixedsizebinary.ts +++ b/js/src/vector/fixedsizebinary.ts @@ -15,12 +15,8 @@ // specific language governing permissions and limitations // under the License. -import { Data } from '../data'; import { BaseVector } from './base'; import { FixedSizeBinary } from '../type'; export class FixedSizeBinaryVector extends BaseVector { - constructor(data: Data) { - super(data, void 0, data.type.byteWidth); - } } diff --git a/js/src/vector/fixedsizelist.ts b/js/src/vector/fixedsizelist.ts index af39e8c48bb02..b5841fa90a60c 100644 --- a/js/src/vector/fixedsizelist.ts +++ b/js/src/vector/fixedsizelist.ts @@ -15,12 +15,8 @@ // specific language governing permissions and limitations // under the License. -import { Data } from '../data'; import { BaseVector } from './base'; import { DataType, FixedSizeList } from '../type'; export class FixedSizeListVector extends BaseVector> { - constructor(data: Data>) { - super(data, void 0, data.type.listSize); - } } diff --git a/js/src/vector/index.ts b/js/src/vector/index.ts index 4662b92b3b49f..e4814b44d5930 100644 --- a/js/src/vector/index.ts +++ b/js/src/vector/index.ts @@ -170,14 +170,9 @@ function wrapNullableSet, F extends /** @ignore */ function bindBaseVectorDataAccessors(this: BaseVector) { - const type = this.type; - this['get'] = getVisitor.getVisitFn(type).bind(this, this as V); - this['set'] = setVisitor.getVisitFn(type).bind(this, this as V); - this['indexOf'] = indexOfVisitor.getVisitFn(type).bind(this, this as V); - this['toArray'] = toArrayVisitor.getVisitFn(type).bind(this, this as V); - this[Symbol.iterator] = iteratorVisitor.getVisitFn(type).bind(this, this as V); - if (this.nullCount > 0) { - this['get'] = wrapNullable1(this['get']); - this['set'] = wrapNullableSet(this['set']); + const nullBitmap = this.nullBitmap; + if (nullBitmap && nullBitmap.byteLength > 0) { + this.get = wrapNullable1(this.get); + this.set = wrapNullableSet(this.set); } } diff --git a/js/src/vector/int.ts b/js/src/vector/int.ts index d851732cbf4bc..3bf40b9bf1252 100644 --- a/js/src/vector/int.ts +++ b/js/src/vector/int.ts @@ -41,9 +41,6 @@ export class IntVector extends BaseVector { } throw new TypeError('Unrecognized Int data'); } - constructor(data: Data) { - super(data, undefined, 1 + Number(data.type.bitWidth > 32)); - } } export class Int8Vector extends IntVector {} diff --git a/js/src/vector/interval.ts b/js/src/vector/interval.ts index 31722981841a6..4d6ff15018a4f 100644 --- a/js/src/vector/interval.ts +++ b/js/src/vector/interval.ts @@ -15,15 +15,9 @@ // specific language governing permissions and limitations // under the License. -import { Data } from '../data'; import { BaseVector } from './base'; import { Interval, IntervalDayTime, IntervalYearMonth } from '../type'; -export class IntervalVector extends BaseVector { - constructor(data: Data) { - super(data, undefined, data.type.unit + 1); - } -} - +export class IntervalVector extends BaseVector {} export class IntervalDayTimeVector extends IntervalVector {} export class IntervalYearMonthVector extends IntervalVector {} diff --git a/js/src/vector/time.ts b/js/src/vector/time.ts index a3d9648e533d9..206e58b7dd995 100644 --- a/js/src/vector/time.ts +++ b/js/src/vector/time.ts @@ -15,15 +15,10 @@ // specific language governing permissions and limitations // under the License. -import { Data } from '../data'; import { BaseVector } from './base'; import { Time, TimeSecond, TimeMillisecond, TimeMicrosecond, TimeNanosecond } from '../type'; -export class TimeVector extends BaseVector { - constructor(data: Data) { - super(data, undefined, 1 + Number(data.type.bitWidth > 32)); - } -} +export class TimeVector extends BaseVector {} export class TimeSecondVector extends TimeVector {} export class TimeMillisecondVector extends TimeVector {} export class TimeMicrosecondVector extends TimeVector {} diff --git a/js/src/vector/timestamp.ts b/js/src/vector/timestamp.ts index 95fd98d9486a1..019483f156be6 100644 --- a/js/src/vector/timestamp.ts +++ b/js/src/vector/timestamp.ts @@ -15,15 +15,10 @@ // specific language governing permissions and limitations // under the License. -import { Data } from '../data'; import { BaseVector } from './base'; import { Timestamp, TimestampSecond, TimestampMillisecond, TimestampMicrosecond, TimestampNanosecond } from '../type'; -export class TimestampVector extends BaseVector { - constructor(data: Data) { - super(data, undefined, 2); - } -} +export class TimestampVector extends BaseVector {} export class TimestampSecondVector extends TimestampVector {} export class TimestampMillisecondVector extends TimestampVector {} export class TimestampMicrosecondVector extends TimestampVector {} diff --git a/js/src/visitor/bytewidth.ts b/js/src/visitor/bytewidth.ts index 42f1b3b99eea0..5438d2a9d66f7 100644 --- a/js/src/visitor/bytewidth.ts +++ b/js/src/visitor/bytewidth.ts @@ -33,12 +33,10 @@ import { /** @ignore */ const variableWidthColumnErrorMessage = (type: DataType) => `Cannot compute the byte width of variable-width column ${type}`; export interface ByteWidthVisitor extends Visitor { - visitMany (nodes: T[] ): number[]; - visit (node: T ): number; - getVisitFn (node: T ): (type: DataType) => number; - getVisitFn(node: Vector): (type: T ) => number; - getVisitFn(node: Data ): (type: T ) => number; - getVisitFn(node: T ): (type: T ) => number; + visit(node: T): number; + visitMany(nodes: T[]): number[]; + getVisitFn (node: T): (type: DataType) => number; + getVisitFn(node: Vector | Data | T): (type: T) => number; } export class ByteWidthVisitor extends Visitor {