diff --git a/arrow/array/builder.go b/arrow/array/builder.go index ed4f08e72..517feec5f 100644 --- a/arrow/array/builder.go +++ b/arrow/array/builder.go @@ -164,10 +164,11 @@ func (b *builder) resize(newBits int, init func(int)) { return } - newBytesN := bitutil.CeilByte(newBits) / 8 + allocBits := max(newBits, minBuilderCapacity) + newBytesN := bitutil.CeilByte(allocBits) / 8 oldBytesN := b.nullBitmap.Len() b.nullBitmap.Resize(newBytesN) - b.capacity = newBits + b.capacity = allocBits if oldBytesN < newBytesN { // TODO(sgc): necessary? memory.Set(b.nullBitmap.Buf()[oldBytesN:], 0) diff --git a/arrow/array/numericbuilder.gen_test.go b/arrow/array/numericbuilder.gen_test.go index 2ca563292..c54d8cf2d 100644 --- a/arrow/array/numericbuilder.gen_test.go +++ b/arrow/array/numericbuilder.gen_test.go @@ -230,6 +230,18 @@ func TestInt64Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestInt64Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewInt64Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestInt64BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -457,6 +469,18 @@ func TestUint64Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestUint64Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewUint64Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestUint64BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -684,6 +708,18 @@ func TestFloat64Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestFloat64Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewFloat64Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestFloat64BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -909,6 +945,18 @@ func TestInt32Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestInt32Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewInt32Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestInt32BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -1136,6 +1184,18 @@ func TestUint32Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestUint32Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewUint32Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestUint32BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -1363,6 +1423,18 @@ func TestFloat32Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestFloat32Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewFloat32Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestFloat32BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -1588,6 +1660,18 @@ func TestInt16Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestInt16Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewInt16Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestInt16BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -1815,6 +1899,18 @@ func TestUint16Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestUint16Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewUint16Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestUint16BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -2042,6 +2138,18 @@ func TestInt8Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestInt8Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewInt8Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestInt8BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -2269,6 +2377,18 @@ func TestUint8Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestUint8Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewUint8Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestUint8BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -2501,6 +2621,19 @@ func TestTime32Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestTime32Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + dtype := &arrow.Time32Type{Unit: arrow.Second} + ab := array.NewTime32Builder(mem, dtype) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestTime32BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -2734,6 +2867,19 @@ func TestTime64Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestTime64Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + dtype := &arrow.Time64Type{Unit: arrow.Second} + ab := array.NewTime64Builder(mem, dtype) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestTime64BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -2962,6 +3108,18 @@ func TestDate32Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestDate32Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewDate32Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestDate32BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -3196,6 +3354,18 @@ func TestDate64Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestDate64Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + ab := array.NewDate64Builder(mem) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestDate64BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) @@ -3428,6 +3598,19 @@ func TestDurationBuilder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func TestDurationBuilder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + dtype := &arrow.DurationType{Unit: arrow.Second} + ab := array.NewDurationBuilder(mem, dtype) + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func TestDurationBuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0) diff --git a/arrow/array/numericbuilder.gen_test.go.tmpl b/arrow/array/numericbuilder.gen_test.go.tmpl index 07d5fc8a2..e34224960 100644 --- a/arrow/array/numericbuilder.gen_test.go.tmpl +++ b/arrow/array/numericbuilder.gen_test.go.tmpl @@ -272,6 +272,23 @@ func Test{{.Name}}Builder_Resize(t *testing.T) { assert.Equal(t, 5, ab.Len()) } +func Test{{.Name}}Builder_ResizeToZeroThenAppend(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + +{{if .Opt.Parametric -}} + dtype := &arrow.{{.Name}}Type{Unit: arrow.Second} + ab := array.New{{.Name}}Builder(mem, dtype) +{{else}} + ab := array.New{{.Name}}Builder(mem) +{{end -}} + defer ab.Release() + + ab.Append(0) + ab.Resize(0) + ab.Append(0) +} + func Test{{.Name}}BuilderUnmarshalJSON(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0)