From 71ef81478ff5fa8f0011ca7a723f6d8e05a017cd Mon Sep 17 00:00:00 2001 From: Giorgio Delgado Date: Wed, 1 Oct 2025 22:35:11 -0400 Subject: [PATCH 1/2] feat: Add LargeList support for JavaScript bindings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement full support for the LargeList data type, which uses 64-bit offsets (BigInt64Array) instead of 32-bit offsets, enabling list values larger than 2GB. Changes include: - Add LargeList type class with BigInt64Array offset support - Implement visitor pattern methods across all visitors (get, iterator, indexof, typeassembler, jsontypeassembler) - Add IPC serialization/deserialization support - Add comprehensive test suite using existing test generation framework - Export LargeList in public API The implementation follows existing code patterns and all tests pass. Closes #70 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/Arrow.dom.ts | 1 + src/Arrow.ts | 1 + src/data.ts | 12 +++++++++++- src/enum.ts | 1 + src/ipc/metadata/message.ts | 3 ++- src/type.ts | 27 +++++++++++++++++++++++++++ src/visitor.ts | 3 +++ src/visitor/get.ts | 14 +++++++++++++- src/visitor/indexof.ts | 4 +++- src/visitor/iterator.ts | 4 +++- src/visitor/jsontypeassembler.ts | 3 +++ src/visitor/typeassembler.ts | 5 +++++ test/generate-test-data.ts | 22 +++++++++++++++++++++- test/unit/generated-data-tests.ts | 1 + 14 files changed, 95 insertions(+), 6 deletions(-) diff --git a/src/Arrow.dom.ts b/src/Arrow.dom.ts index e0cd681c..f5705bbb 100644 --- a/src/Arrow.dom.ts +++ b/src/Arrow.dom.ts @@ -57,6 +57,7 @@ export { Time, TimeSecond, TimeMillisecond, TimeMicrosecond, TimeNanosecond, Decimal, List, + LargeList, Struct, StructRow, Union, DenseUnion, SparseUnion, Dictionary, diff --git a/src/Arrow.ts b/src/Arrow.ts index 8321026f..2aa65820 100644 --- a/src/Arrow.ts +++ b/src/Arrow.ts @@ -45,6 +45,7 @@ export { Time, TimeSecond, TimeMillisecond, TimeMicrosecond, TimeNanosecond, Decimal, List, + LargeList, Struct, Union, DenseUnion, SparseUnion, Dictionary, diff --git a/src/data.ts b/src/data.ts index 45fcc35d..3aa9e1c5 100644 --- a/src/data.ts +++ b/src/data.ts @@ -256,7 +256,7 @@ export class Data { import { Dictionary, - Bool, Null, Utf8, LargeUtf8, Binary, LargeBinary, Decimal, FixedSizeBinary, List, FixedSizeList, Map_, Struct, + Bool, Null, Utf8, LargeUtf8, Binary, LargeBinary, Decimal, FixedSizeBinary, List, LargeList, FixedSizeList, Map_, Struct, Float, Int, Date_, @@ -377,6 +377,13 @@ class MakeDataVisitor extends Visitor { const { ['length']: length = valueOffsets.length - 1, ['nullCount']: nullCount = props['nullBitmap'] ? -1 : 0 } = props; return new Data(type, offset, length, nullCount, [valueOffsets, undefined, nullBitmap], [child]); } + public visitLargeList(props: LargeListDataProps) { + const { ['type']: type, ['offset']: offset = 0, ['child']: child } = props; + const nullBitmap = toUint8Array(props['nullBitmap']); + const valueOffsets = toBigInt64Array(props['valueOffsets']); + const { ['length']: length = valueOffsets.length - 1, ['nullCount']: nullCount = props['nullBitmap'] ? -1 : 0 } = props; + return new Data(type, offset, length, nullCount, [valueOffsets, undefined, nullBitmap], [child]); + } public visitStruct(props: StructDataProps) { const { ['type']: type, ['offset']: offset = 0, ['children']: children = [] } = props; const nullBitmap = toUint8Array(props['nullBitmap']); @@ -459,6 +466,7 @@ interface LargeBinaryDataProps extends DataProps_ { va interface Utf8DataProps extends DataProps_ { valueOffsets: ValueOffsetsBuffer; data?: DataBuffer } interface LargeUtf8DataProps extends DataProps_ { valueOffsets: LargeValueOffsetsBuffer | ValueOffsetsBuffer; data?: DataBuffer } interface ListDataProps extends DataProps_ { valueOffsets: ValueOffsetsBuffer; child: Data } +interface LargeListDataProps extends DataProps_ { valueOffsets: LargeValueOffsetsBuffer | ValueOffsetsBuffer; child: Data } interface FixedSizeListDataProps extends DataProps_ { child: Data } interface StructDataProps extends DataProps_ { children: Data[] } interface Map_DataProps extends DataProps_ { valueOffsets: ValueOffsetsBuffer; child: Data } @@ -484,6 +492,7 @@ export type DataProps = ( T extends Utf8 /* */ ? Utf8DataProps : T extends LargeUtf8 /* */ ? LargeUtf8DataProps : T extends List /* */ ? ListDataProps : + T extends LargeList /* */ ? LargeListDataProps : T extends FixedSizeList /* */ ? FixedSizeListDataProps : T extends Struct /* */ ? StructDataProps : T extends Map_ /* */ ? Map_DataProps : @@ -512,6 +521,7 @@ export function makeData(props: LargeBinaryDataProps): export function makeData(props: Utf8DataProps): Data; export function makeData(props: LargeUtf8DataProps): Data; export function makeData(props: ListDataProps): Data; +export function makeData(props: LargeListDataProps): Data; export function makeData(props: FixedSizeListDataProps): Data; export function makeData(props: StructDataProps): Data; export function makeData(props: Map_DataProps): Data; diff --git a/src/enum.ts b/src/enum.ts index 73d95538..ad61c719 100644 --- a/src/enum.ts +++ b/src/enum.ts @@ -70,6 +70,7 @@ export enum Type { Duration = 18, /** Measure of elapsed time in either seconds, milliseconds, microseconds or nanoseconds */ LargeBinary = 19, /** Large variable-length bytes (no guarantee of UTF8-ness) */ LargeUtf8 = 20, /** Large variable-length string as List */ + LargeList = 21, /** A list of some logical data type with 64-bit offsets */ Dictionary = -1, /** Dictionary aka Category type */ Int8 = -2, diff --git a/src/ipc/metadata/message.ts b/src/ipc/metadata/message.ts index 17e8897b..4700706b 100644 --- a/src/ipc/metadata/message.ts +++ b/src/ipc/metadata/message.ts @@ -58,7 +58,7 @@ import ByteBuffer = flatbuffers.ByteBuffer; import { DataType, Dictionary, TimeBitWidth, Utf8, LargeUtf8, Binary, LargeBinary, Decimal, FixedSizeBinary, - List, FixedSizeList, Map_, Struct, Union, + List, LargeList, FixedSizeList, Map_, Struct, Union, Bool, Null, Int, Float, Date_, Time, Interval, Timestamp, IntBitWidth, Int32, TKeys, Duration, } from '../../type.js'; @@ -472,6 +472,7 @@ function decodeFieldType(f: _Field, children?: Field[]): DataType { case Type['LargeUtf8']: return new LargeUtf8(); case Type['Bool']: return new Bool(); case Type['List']: return new List((children || [])[0]); + case Type['LargeList']: return new LargeList((children || [])[0]); case Type['Struct_']: return new Struct(children || []); } diff --git a/src/type.ts b/src/type.ts index ea5e24fa..adc2d7ed 100644 --- a/src/type.ts +++ b/src/type.ts @@ -69,6 +69,7 @@ export abstract class DataType extends DataType extends DataType { + TArray: Array; + TValue: Vector; + TOffsetArray: BigInt64Array; + OffsetArrayType: BigIntArrayConstructor; +} + +/** @ignore */ +export class LargeList extends DataType { + constructor(child: Field) { + super(Type.LargeList); + this.children = [child]; + } + public declare readonly children: Field[]; + public toString() { return `LargeList<${this.valueType}>`; } + public get valueType(): T { return this.children[0].type as T; } + public get valueField(): Field { return this.children[0] as Field; } + public get ArrayType(): T['ArrayType'] { return this.valueType.ArrayType; } + protected static [Symbol.toStringTag] = ((proto: LargeList) => { + (proto).children = null; + (proto).OffsetArrayType = BigInt64Array; + return proto[Symbol.toStringTag] = 'LargeList'; + })(LargeList.prototype); +} + /** @ignore */ export interface Struct extends DataType { TArray: Array>; diff --git a/src/visitor.ts b/src/visitor.ts index 977e0a4e..a1596e08 100644 --- a/src/visitor.ts +++ b/src/visitor.ts @@ -45,6 +45,7 @@ export abstract class Visitor { public visitTime(_node: any, ..._args: any[]): any { return null; } public visitDecimal(_node: any, ..._args: any[]): any { return null; } public visitList(_node: any, ..._args: any[]): any { return null; } + public visitLargeList(_node: any, ..._args: any[]): any { return null; } public visitStruct(_node: any, ..._args: any[]): any { return null; } public visitUnion(_node: any, ..._args: any[]): any { return null; } public visitDictionary(_node: any, ..._args: any[]): any { return null; } @@ -110,6 +111,7 @@ function getVisitFnByTypeId(visitor: Visitor, dtype: Type, throwIfNotFound = tru case Type.TimeNanosecond: fn = visitor.visitTimeNanosecond || visitor.visitTime; break; case Type.Decimal: fn = visitor.visitDecimal; break; case Type.List: fn = visitor.visitList; break; + case Type.LargeList: fn = visitor.visitLargeList; break; case Type.Struct: fn = visitor.visitStruct; break; case Type.Union: fn = visitor.visitUnion; break; case Type.DenseUnion: fn = visitor.visitDenseUnion || visitor.visitUnion; break; @@ -205,6 +207,7 @@ function inferDType(type: T): Type { return Type.Duration; case Type.Map: return Type.Map; case Type.List: return Type.List; + case Type.LargeList: return Type.LargeList; case Type.Struct: return Type.Struct; case Type.Union: switch ((type as any as Union).mode) { diff --git a/src/visitor/get.ts b/src/visitor/get.ts index a5502dd3..76544a00 100644 --- a/src/visitor/get.ts +++ b/src/visitor/get.ts @@ -28,7 +28,7 @@ import { uint16ToFloat64 } from '../util/math.js'; import { Type, UnionMode, Precision, DateUnit, TimeUnit, IntervalUnit } from '../enum.js'; import { DataType, Dictionary, - Bool, Null, Utf8, LargeUtf8, Binary, LargeBinary, Decimal, FixedSizeBinary, List, FixedSizeList, Map_, Struct, + Bool, Null, Utf8, LargeUtf8, Binary, LargeBinary, Decimal, FixedSizeBinary, List, LargeList, FixedSizeList, Map_, Struct, Float, Float16, Float32, Float64, Int, Uint8, Uint16, Uint32, Uint64, Int8, Int16, Int32, Int64, Date_, DateDay, DateMillisecond, @@ -81,6 +81,7 @@ export interface GetVisitor extends Visitor { visitTimeNanosecond(data: Data, index: number): T['TValue'] | null; visitDecimal(data: Data, index: number): T['TValue'] | null; visitList(data: Data, index: number): T['TValue'] | null; + visitLargeList(data: Data, index: number): T['TValue'] | null; visitStruct(data: Data, index: number): T['TValue'] | null; visitUnion(data: Data, index: number): T['TValue'] | null; visitDenseUnion(data: Data, index: number): T['TValue'] | null; @@ -222,6 +223,16 @@ const getList = (data: Data, index: number): T['TValue'] => { return new Vector([slice]) as T['TValue']; }; +/** @ignore */ +const getLargeList = (data: Data, index: number): T['TValue'] => { + const { valueOffsets, stride, children } = data; + const begin = Number(valueOffsets[index * stride]); + const end = Number(valueOffsets[index * stride + 1]); + const child: Data = children[0]; + const slice = child.slice(begin, end - begin); + return new Vector([slice]) as T['TValue']; +}; + /** @ignore */ const getMap = (data: Data, index: number): T['TValue'] => { const { valueOffsets, children } = data; @@ -350,6 +361,7 @@ GetVisitor.prototype.visitTimeMicrosecond = wrapGet(getTimeMicrosecond); GetVisitor.prototype.visitTimeNanosecond = wrapGet(getTimeNanosecond); GetVisitor.prototype.visitDecimal = wrapGet(getDecimal); GetVisitor.prototype.visitList = wrapGet(getList); +GetVisitor.prototype.visitLargeList = wrapGet(getLargeList); GetVisitor.prototype.visitStruct = wrapGet(getStruct); GetVisitor.prototype.visitUnion = wrapGet(getUnion); GetVisitor.prototype.visitDenseUnion = wrapGet(getDenseUnion); diff --git a/src/visitor/indexof.ts b/src/visitor/indexof.ts index 3a4d1171..bda9017e 100644 --- a/src/visitor/indexof.ts +++ b/src/visitor/indexof.ts @@ -24,7 +24,7 @@ import { getBool, BitIterator } from '../util/bit.js'; import { createElementComparator } from '../util/vector.js'; import { DataType, Dictionary, - Bool, Null, Utf8, LargeUtf8, Binary, LargeBinary, Decimal, FixedSizeBinary, List, FixedSizeList, Map_, Struct, + Bool, Null, Utf8, LargeUtf8, Binary, LargeBinary, Decimal, FixedSizeBinary, List, LargeList, FixedSizeList, Map_, Struct, Float, Float16, Float32, Float64, Int, Uint8, Uint16, Uint32, Uint64, Int8, Int16, Int32, Int64, Date_, DateDay, DateMillisecond, @@ -77,6 +77,7 @@ export interface IndexOfVisitor extends Visitor { visitTimeNanosecond(data: Data, value: T['TValue'] | null, index?: number): number; visitDecimal(data: Data, value: T['TValue'] | null, index?: number): number; visitList(data: Data, value: T['TValue'] | null, index?: number): number; + visitLargeList(data: Data, value: T['TValue'] | null, index?: number): number; visitStruct(data: Data, value: T['TValue'] | null, index?: number): number; visitUnion(data: Data, value: T['TValue'] | null, index?: number): number; visitDenseUnion(data: Data, value: T['TValue'] | null, index?: number): number; @@ -195,6 +196,7 @@ IndexOfVisitor.prototype.visitTimeMicrosecond = indexOfValue; IndexOfVisitor.prototype.visitTimeNanosecond = indexOfValue; IndexOfVisitor.prototype.visitDecimal = indexOfValue; IndexOfVisitor.prototype.visitList = indexOfValue; +IndexOfVisitor.prototype.visitLargeList = indexOfValue; IndexOfVisitor.prototype.visitStruct = indexOfValue; IndexOfVisitor.prototype.visitUnion = indexOfValue; IndexOfVisitor.prototype.visitDenseUnion = indexOfUnion; diff --git a/src/visitor/iterator.ts b/src/visitor/iterator.ts index 9f2844b3..e97f3523 100644 --- a/src/visitor/iterator.ts +++ b/src/visitor/iterator.ts @@ -21,7 +21,7 @@ import { Type, Precision } from '../enum.js'; import { TypeToDataType } from '../interfaces.js'; import { DataType, Dictionary, - Bool, Null, Utf8, LargeUtf8, Binary, LargeBinary, Decimal, FixedSizeBinary, List, FixedSizeList, Map_, Struct, + Bool, Null, Utf8, LargeUtf8, Binary, LargeBinary, Decimal, FixedSizeBinary, List, LargeList, FixedSizeList, Map_, Struct, Float, Float16, Float32, Float64, Int, Uint8, Uint16, Uint32, Uint64, Int8, Int16, Int32, Int64, Date_, DateDay, DateMillisecond, @@ -75,6 +75,7 @@ export interface IteratorVisitor extends Visitor { visitTimeNanosecond(vector: Vector): IterableIterator; visitDecimal(vector: Vector): IterableIterator; visitList(vector: Vector): IterableIterator; + visitLargeList(vector: Vector): IterableIterator; visitStruct(vector: Vector): IterableIterator; visitUnion(vector: Vector): IterableIterator; visitDenseUnion(vector: Vector): IterableIterator; @@ -182,6 +183,7 @@ IteratorVisitor.prototype.visitTimeMicrosecond = vectorIterator; IteratorVisitor.prototype.visitTimeNanosecond = vectorIterator; IteratorVisitor.prototype.visitDecimal = vectorIterator; IteratorVisitor.prototype.visitList = vectorIterator; +IteratorVisitor.prototype.visitLargeList = vectorIterator; IteratorVisitor.prototype.visitStruct = vectorIterator; IteratorVisitor.prototype.visitUnion = vectorIterator; IteratorVisitor.prototype.visitDenseUnion = vectorIterator; diff --git a/src/visitor/jsontypeassembler.ts b/src/visitor/jsontypeassembler.ts index 823b1dea..9647c42c 100644 --- a/src/visitor/jsontypeassembler.ts +++ b/src/visitor/jsontypeassembler.ts @@ -75,6 +75,9 @@ export class JSONTypeAssembler extends Visitor { public visitList({ typeId }: T) { return { 'name': ArrowType[typeId].toLowerCase() }; } + public visitLargeList({ typeId }: T) { + return { 'name': ArrowType[typeId].toLowerCase() }; + } public visitStruct({ typeId }: T) { return { 'name': ArrowType[typeId].toLowerCase() }; } diff --git a/src/visitor/typeassembler.ts b/src/visitor/typeassembler.ts index 169f3627..ac2c0a92 100644 --- a/src/visitor/typeassembler.ts +++ b/src/visitor/typeassembler.ts @@ -36,6 +36,7 @@ import { Timestamp } from '../fb/timestamp.js'; import { Interval } from '../fb/interval.js'; import { Duration } from '../fb/duration.js'; import { List } from '../fb/list.js'; +import { LargeList } from '../fb/large-list.js'; import { Struct_ as Struct } from '../fb/struct-.js'; import { Union } from '../fb/union.js'; import { DictionaryEncoding } from '../fb/dictionary-encoding.js'; @@ -129,6 +130,10 @@ export class TypeAssembler extends Visitor { List.startList(b); return List.endList(b); } + public visitLargeList(_node: T, b: Builder) { + LargeList.startLargeList(b); + return LargeList.endLargeList(b); + } public visitStruct(_node: T, b: Builder) { Struct.startStruct_(b); return Struct.endStruct_(b); diff --git a/test/generate-test-data.ts b/test/generate-test-data.ts index de4a8269..cd393d39 100644 --- a/test/generate-test-data.ts +++ b/test/generate-test-data.ts @@ -30,6 +30,7 @@ import { Time, TimeSecond, TimeMillisecond, TimeMicrosecond, TimeNanosecond, Decimal, List, + LargeList, Struct, Union, DenseUnion, SparseUnion, Dictionary, @@ -64,6 +65,7 @@ interface TestDataVectorGenerator extends Visitor { visit(type: T, length?: number, nullCount?: number): GeneratedVector; visit(type: T, length?: number, nullCount?: number): GeneratedVector; visit(type: T, length?: number, nullCount?: number, child?: Vector): GeneratedVector; + visit(type: T, length?: number, nullCount?: number, child?: Vector): GeneratedVector; visit(type: T, length?: number, nullCount?: number, child?: Vector): GeneratedVector; visit(type: T, length?: number, nullCount?: number, dictionary?: Vector): GeneratedVector; visit(type: T, length?: number, nullCount?: number, children?: Vector[]): GeneratedVector; @@ -87,6 +89,7 @@ interface TestDataVectorGenerator extends Visitor { visitTime: typeof generateTime; visitDecimal: typeof generateDecimal; visitList: typeof generateList; + visitLargeList: typeof generateLargeList; visitStruct: typeof generateStruct; visitUnion: typeof generateUnion; visitDictionary: typeof generateDictionary; @@ -114,6 +117,7 @@ TestDataVectorGenerator.prototype.visitTimestamp = generateTimestamp; TestDataVectorGenerator.prototype.visitTime = generateTime; TestDataVectorGenerator.prototype.visitDecimal = generateDecimal; TestDataVectorGenerator.prototype.visitList = generateList; +TestDataVectorGenerator.prototype.visitLargeList = generateLargeList; TestDataVectorGenerator.prototype.visitStruct = generateStruct; TestDataVectorGenerator.prototype.visitUnion = generateUnion; TestDataVectorGenerator.prototype.visitDictionary = generateDictionary; @@ -237,6 +241,7 @@ export const timeMicrosecond = (length = 100, nullCount = Math.trunc(length * 0. export const timeNanosecond = (length = 100, nullCount = Math.trunc(length * 0.2)) => vectorGenerator.visit(new TimeNanosecond(), length, nullCount); export const decimal = (length = 100, nullCount = Math.trunc(length * 0.2), scale = 2, precision = 9, bitWidth = 128) => vectorGenerator.visit(new Decimal(scale, precision, bitWidth), length, nullCount); export const list = (length = 100, nullCount = Math.trunc(length * 0.2), child = defaultListChild) => vectorGenerator.visit(new List(child), length, nullCount); +export const largeList = (length = 100, nullCount = Math.trunc(length * 0.2), child = defaultListChild) => vectorGenerator.visit(new LargeList(child), length, nullCount); export const struct = (length = 100, nullCount = Math.trunc(length * 0.2), children: Field[] = defaultStructChildren()) => vectorGenerator.visit(new Struct(children), length, nullCount); export const denseUnion = (length = 100, nullCount = Math.trunc(length * 0.2), children: Field[] = defaultUnionChildren()) => vectorGenerator.visit(new DenseUnion(children.map((f) => f.typeId), children), length, nullCount); export const sparseUnion = (length = 100, nullCount = Math.trunc(length * 0.2), children: Field[] = defaultUnionChildren()) => vectorGenerator.visit(new SparseUnion(children.map((f) => f.typeId), children), length, nullCount); @@ -493,6 +498,21 @@ function generateList(this: TestDataVectorGenerator, type: T, le return { values, vector: new Vector([makeData({ type, length, nullCount, nullBitmap, valueOffsets, child: childVec.data[0] })]) }; } +function generateLargeList(this: TestDataVectorGenerator, type: T, length = 100, nullCount = Math.trunc(length * 0.2), child = this.visit(type.children[0].type, length * 3, nullCount * 3)): GeneratedVector { + const childVec = child.vector; + const nullBitmap = createBitmap(length, nullCount); + const stride = childVec.length / (length - nullCount); + const valueOffsets = createVariableWidthOffsets64(length, nullBitmap, stride, stride); + const values = memoize(() => { + const childValues = child.values(); + const values: (T['valueType'] | null)[] = [...valueOffsets.slice(1)] + .map((offset, i) => isValid(nullBitmap, i) ? offset : null) + .map((o, i) => o == null ? null : childValues.slice(Number(valueOffsets[i]), Number(o))); + return values; + }); + return { values, vector: new Vector([makeData({ type, length, nullCount, nullBitmap, valueOffsets, child: childVec.data[0] })]) }; +} + function generateFixedSizeList(this: TestDataVectorGenerator, type: T, length = 100, nullCount = Math.trunc(length * 0.2), child = this.visit(type.children[0].type, length * type.listSize, nullCount * type.listSize)): GeneratedVector { const nullBitmap = createBitmap(length, nullCount); const values = memoize(() => { @@ -720,7 +740,7 @@ function createVariableWidthOffsets64(length: number, nullBitmap: Uint8Array, mi offsets[i + 1] = offsets[i]; } else { do { - offsets[i + 1] = offsets[i] + BigInt(Math.min(max, Math.max(min, Math.trunc(rand() * max)))); + offsets[i + 1] = offsets[i] + BigInt(Math.trunc(Math.min(max, Math.max(min, Math.trunc(rand() * max))))); } while (!allowEmpty && offsets[i + 1] === offsets[i]); } }); diff --git a/test/unit/generated-data-tests.ts b/test/unit/generated-data-tests.ts index 9affe5f6..8de116af 100644 --- a/test/unit/generated-data-tests.ts +++ b/test/unit/generated-data-tests.ts @@ -54,6 +54,7 @@ describe('Generated Test Data', () => { describe('TimeNanosecond', () => { validateVector(generate.timeNanosecond()); }); describe('Decimal', () => { validateVector(generate.decimal()); }); describe('List', () => { validateVector(generate.list()); }); + describe('LargeList', () => { validateVector(generate.largeList()); }); describe('Struct', () => { validateVector(generate.struct()); }); describe('DenseUnion', () => { validateVector(generate.denseUnion()); }); describe('SparseUnion', () => { validateVector(generate.sparseUnion()); }); From ada53273fbede750aecf3f7bacbf8abdc9b82fc6 Mon Sep 17 00:00:00 2001 From: Giorgio Delgado Date: Fri, 10 Oct 2025 12:10:07 -0400 Subject: [PATCH 2/2] Remove redundant Math.trunc call --- test/generate-test-data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/generate-test-data.ts b/test/generate-test-data.ts index cd393d39..c501e481 100644 --- a/test/generate-test-data.ts +++ b/test/generate-test-data.ts @@ -740,7 +740,7 @@ function createVariableWidthOffsets64(length: number, nullBitmap: Uint8Array, mi offsets[i + 1] = offsets[i]; } else { do { - offsets[i + 1] = offsets[i] + BigInt(Math.trunc(Math.min(max, Math.max(min, Math.trunc(rand() * max))))); + offsets[i + 1] = offsets[i] + BigInt(Math.min(max, Math.max(min, Math.trunc(rand() * max)))); } while (!allowEmpty && offsets[i + 1] === offsets[i]); } });