blob: bd71ee562aab504202de900c1acd0c745d614c39 [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//go:build cgo
package mallocator_test
import (
"fmt"
"testing"
"unsafe"
"github.com/apache/arrow-go/v18/arrow/memory/mallocator"
"github.com/stretchr/testify/assert"
)
func TestMallocatorAllocate(t *testing.T) {
sizes := []int{0, 1, 4, 33, 65, 4095, 4096, 8193}
for _, size := range sizes {
t.Run(fmt.Sprint(size), func(t *testing.T) {
a := mallocator.NewMallocator()
buf := a.Allocate(size)
defer a.Free(buf)
assert.Equal(t, size, len(buf))
assert.LessOrEqual(t, size, cap(buf))
// check 0-initialized
for idx, c := range buf {
assert.Equal(t, uint8(0), c, fmt.Sprintf("Buf not zero-initialized at %d", idx))
}
// check aligned
if size > 0 {
assert.Equal(t, uintptr(0), uintptr(unsafe.Pointer(&buf[0]))%64)
}
})
}
}
func TestMallocatorAllocateAligned(t *testing.T) {
sizes := []int{0, 1, 4, 33, 65, 4095, 4096, 8193}
for _, size := range sizes {
t.Run(fmt.Sprint(size), func(t *testing.T) {
a := mallocator.NewMallocatorWithAlignment(16)
buf := a.Allocate(size)
defer a.Free(buf)
assert.Equal(t, size, len(buf))
assert.LessOrEqual(t, size, cap(buf))
// check 0-initialized
for idx, c := range buf {
assert.Equal(t, uint8(0), c, fmt.Sprintf("Buf not zero-initialized at %d", idx))
}
// check aligned
if size > 0 {
assert.Equal(t, uintptr(0), uintptr(unsafe.Pointer(&buf[0]))%16)
}
})
}
}
func TestMallocatorReallocate(t *testing.T) {
sizes := []struct {
before, after int
}{
{0, 1},
{1, 0},
{1, 2},
{1, 33},
{4, 4},
{32, 16},
{32, 1},
}
for _, test := range sizes {
t.Run(fmt.Sprintf("%dTo%d", test.before, test.after), func(t *testing.T) {
a := mallocator.NewMallocator()
buf := a.Allocate(test.before)
assert.Equal(t, test.before, len(buf))
assert.LessOrEqual(t, test.before, cap(buf))
// check 0-initialized
for idx, c := range buf {
assert.Equal(t, uint8(0), c, fmt.Sprintf("Buf not zero-initialized at %d", idx))
}
a.AssertSize(t, test.before)
buf = a.Reallocate(test.after, buf)
defer a.Free(buf)
assert.Equal(t, test.after, len(buf))
assert.LessOrEqual(t, test.after, cap(buf))
// check 0-initialized
for idx, c := range buf {
assert.Equal(t, uint8(0), c, fmt.Sprintf("Buf not zero-initialized at %d", idx))
}
a.AssertSize(t, test.after)
})
}
}
func TestMallocatorReallocateInPlace(t *testing.T) {
a := mallocator.NewMallocator()
buf := a.Allocate(80)
assert.Equal(t, 80, len(buf))
assert.LessOrEqual(t, 80, cap(buf))
a.AssertSize(t, 80)
addr := uintptr(unsafe.Pointer(&buf[0]))
buf2 := a.Reallocate(81, buf)
assert.Equal(t, 81, len(buf2))
assert.LessOrEqual(t, 81, cap(buf2))
a.AssertSize(t, 81)
addr2 := uintptr(unsafe.Pointer(&buf[0]))
assert.Equal(t, addr, addr2)
}
func TestMallocatorAssertSize(t *testing.T) {
a := mallocator.NewMallocator()
assert.Equal(t, int64(0), a.AllocatedBytes())
buf1 := a.Allocate(64)
a.AssertSize(t, 64)
buf2 := a.Allocate(128)
a.AssertSize(t, 192)
assert.Equal(t, int64(192), a.AllocatedBytes())
a.Free(buf1)
a.AssertSize(t, 128)
assert.Equal(t, int64(128), a.AllocatedBytes())
buf2 = a.Reallocate(256, buf2)
a.AssertSize(t, 256)
assert.Equal(t, int64(256), a.AllocatedBytes())
buf2 = a.Reallocate(64, buf2)
a.AssertSize(t, 64)
assert.Equal(t, int64(64), a.AllocatedBytes())
a.Free(buf2)
a.AssertSize(t, 0)
assert.Equal(t, int64(0), a.AllocatedBytes())
}
func TestMallocatorAllocateNegative(t *testing.T) {
a := mallocator.NewMallocator()
assert.PanicsWithValue(t, "mallocator: negative size", func() {
a.Allocate(-1)
})
}
func TestMallocatorReallocateNegative(t *testing.T) {
a := mallocator.NewMallocator()
buf := a.Allocate(1)
defer a.Free(buf)
assert.PanicsWithValue(t, "mallocator: negative size", func() {
a.Reallocate(-1, buf)
})
}