This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new 950fbb62ce GH-40733: [Go] Require Go 1.21 or later (#40848)
950fbb62ce is described below
commit 950fbb62ce7388aad926c5af5861bf07f7db6de1
Author: Matt Topol <[email protected]>
AuthorDate: Thu Mar 28 15:59:14 2024 -0400
GH-40733: [Go] Require Go 1.21 or later (#40848)
### Rationale for this change
Bumping to require Go 1.21 or later as 1.20 is EOL
* GitHub Issue: #40733
Authored-by: Matt Topol <[email protected]>
Signed-off-by: Matt Topol <[email protected]>
---
.env | 4 +-
.github/workflows/go.yml | 28 ++++++-----
ci/docker/conda-integration.dockerfile | 2 +-
ci/docker/debian-12-go.dockerfile | 4 +-
dev/release/verify-release-candidate.sh | 6 +--
dev/tasks/tasks.yml | 2 +-
go/arrow/bitutil/bitutil.go | 35 +------------
.../bitutil/bitutil_bytes.go} | 26 +++++-----
go/arrow/cdata/cdata_allocate.go | 57 ++++++++++++++++++++++
go/arrow/cdata/cdata_exports.go | 55 ---------------------
go/arrow/compute/exec/span.go | 17 -------
.../compute/exec/span_offsets.go} | 20 ++++++--
go/arrow/compute/fieldref.go | 17 -------
.../compute/fieldref_hash.go} | 23 +++++++--
go/arrow/doc.go | 2 -
go/arrow/flight/flightsql/driver/driver_test.go | 1 +
go/arrow/memory/mallocator/mallocator.go | 11 ++---
go/arrow/memory/mallocator/mallocator_util.go | 26 ++++++++++
go/go.mod | 2 +-
go/internal/hashing/hash_string.go | 4 ++
go/internal/hashing/xxh3_memo_table.go | 9 +---
go/parquet/types.go | 44 +++--------------
22 files changed, 177 insertions(+), 218 deletions(-)
diff --git a/.env b/.env
index b5c66563f5..298c100c09 100644
--- a/.env
+++ b/.env
@@ -58,8 +58,8 @@ CUDA=11.2.2
DASK=latest
DOTNET=7.0
GCC_VERSION=""
-GO=1.19.13
-STATICCHECK=v0.4.5
+GO=1.21.8
+STATICCHECK=v0.4.7
HDFS=3.2.1
JDK=8
KARTOTHEK=latest
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 47148d9568..7ff781d35e 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -59,13 +59,13 @@ jobs:
{
"arch-label": "AMD64",
"arch": "amd64",
- "go": "1.19",
+ "go": "1.21",
"runs-on": "ubuntu-latest"
},
{
"arch-label": "AMD64",
"arch": "amd64",
- "go": "1.20",
+ "go": "1.22",
"runs-on": "ubuntu-latest"
}
JSON
@@ -75,13 +75,13 @@ jobs:
{
"arch-label": "ARM64",
"arch": "arm64v8",
- "go": "1.19",
+ "go": "1.21",
"runs-on": ["self-hosted", "arm", "linux"]
},
{
"arch-label": "ARM64",
"arch": "arm64v8",
- "go": "1.20",
+ "go": "1.22",
"runs-on": ["self-hosted", "arm", "linux"]
}
JSON
@@ -169,10 +169,13 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
+ - name: Get required Go version
+ run: |
+ (. .env && echo "GO_VERSION=${GO}") >> $GITHUB_ENV
- name: Install Go
uses: actions/setup-go@v5
with:
- go-version: 1.19
+ go-version: "${{ env.GO_VERSION }}"
cache: true
cache-dependency-path: go/go.sum
- name: Run build
@@ -188,7 +191,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- go: [1.19, '1.20']
+ go: ['1.21', '1.22']
env:
GO: ${{ matrix.go }}
steps:
@@ -229,7 +232,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- go: [1.19, '1.20']
+ go: ['1.21', '1.22']
env:
GO: ${{ matrix.go }}
steps:
@@ -268,7 +271,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- go: [1.19, '1.20']
+ go: ['1.21', '1.22']
steps:
- name: Checkout Arrow
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #
v4.0.0
@@ -301,7 +304,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- go: [1.19, '1.20']
+ go: ['1.21', '1.22']
steps:
- name: Checkout Arrow
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #
v4.0.0
@@ -359,7 +362,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- go: [1.19, '1.20']
+ go: ['1.21', '1.22']
env:
ARROW_GO_TESTCGO: "1"
steps:
@@ -428,6 +431,9 @@ jobs:
shell: msys2 {0}
run: |
ci/scripts/msys2_setup.sh cgo
+ - name: Get required Go version
+ run: |
+ (. .env && echo "GO_VERSION=${GO}") >> $GITHUB_ENV
- name: Update CGO Env vars
shell: msys2 {0}
run: |
@@ -437,7 +443,7 @@ jobs:
- name: Install go
uses: actions/setup-go@v5
with:
- go-version: '1.19'
+ go-version: "${{ env.GO_VERSION }}"
cache: true
cache-dependency-path: go/go.sum
- name: Install staticcheck
diff --git a/ci/docker/conda-integration.dockerfile
b/ci/docker/conda-integration.dockerfile
index 8406a419c0..a747ccbc72 100644
--- a/ci/docker/conda-integration.dockerfile
+++ b/ci/docker/conda-integration.dockerfile
@@ -24,7 +24,7 @@ ARG maven=3.8.7
ARG node=16
ARG yarn=1.22
ARG jdk=8
-ARG go=1.19.13
+ARG go=1.21.8
# Install Archery and integration dependencies
COPY ci/conda_env_archery.txt /arrow/ci/
diff --git a/ci/docker/debian-12-go.dockerfile
b/ci/docker/debian-12-go.dockerfile
index 7c077910a6..c958e6bdee 100644
--- a/ci/docker/debian-12-go.dockerfile
+++ b/ci/docker/debian-12-go.dockerfile
@@ -16,8 +16,8 @@
# under the License.
ARG arch=amd64
-ARG go=1.19
-ARG staticcheck=v0.4.5
+ARG go=1.21
+ARG staticcheck=v0.4.7
FROM ${arch}/golang:${go}-bookworm
# FROM collects all the args, get back the staticcheck version arg
diff --git a/dev/release/verify-release-candidate.sh
b/dev/release/verify-release-candidate.sh
index d74ce1f670..e7d78328ed 100755
--- a/dev/release/verify-release-candidate.sh
+++ b/dev/release/verify-release-candidate.sh
@@ -24,7 +24,7 @@
# - JDK >=8
# - gcc >= 4.8
# - Node.js >= 18
-# - Go >= 1.19
+# - Go >= 1.21
# - Docker
#
# If using a non-system Boost, set BOOST_ROOT and add Boost libraries to
@@ -405,7 +405,7 @@ install_go() {
return 0
fi
- local version=1.19.13
+ local version=1.21.8
show_info "Installing go version ${version}..."
local arch="$(uname -m)"
@@ -953,7 +953,7 @@ test_go() {
show_header "Build and test Go libraries"
maybe_setup_go
- maybe_setup_conda compilers go=1.19
+ maybe_setup_conda compilers go=1.21
pushd go
go get -v ./...
diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml
index 15b687b2d2..2abfbc1517 100644
--- a/dev/tasks/tasks.yml
+++ b/dev/tasks/tasks.yml
@@ -1415,7 +1415,7 @@ tasks:
R_PRUNE_DEPS: TRUE
image: fedora-r-clang-sanitizer
- {% for go_version, staticcheck in [("1.19", "v0.4.5"), ("1.21", "latest")] %}
+ {% for go_version, staticcheck in [("1.21", "v0.4.7"), ("1.22", "latest")] %}
test-debian-12-go-{{ go_version }}:
ci: azure
template: docker-tests/azure.linux.yml
diff --git a/go/arrow/bitutil/bitutil.go b/go/arrow/bitutil/bitutil.go
index 82747ee141..6a8f754103 100644
--- a/go/arrow/bitutil/bitutil.go
+++ b/go/arrow/bitutil/bitutil.go
@@ -19,7 +19,6 @@ package bitutil
import (
"math"
"math/bits"
- "reflect"
"unsafe"
"github.com/apache/arrow/go/v16/arrow/memory"
@@ -99,8 +98,6 @@ func countSetBitsWithOffset(buf []byte, offset, n int) int {
count := 0
beg := offset
- end := offset + n
-
begU8 := roundUp(beg, uint64SizeBits)
init := min(n, begU8-beg)
@@ -110,27 +107,8 @@ func countSetBitsWithOffset(buf []byte, offset, n int) int
{
}
}
- nU64 := (n - init) / uint64SizeBits
- begU64 := begU8 / uint64SizeBits
- endU64 := begU64 + nU64
- bufU64 := bytesToUint64(buf)
- if begU64 < len(bufU64) {
- for _, v := range bufU64[begU64:endU64] {
- count += bits.OnesCount64(v)
- }
- }
-
- // FIXME: use a fallback to bits.OnesCount8
- // before counting the tail bits.
-
- tail := beg + init + nU64*uint64SizeBits
- for i := tail; i < end; i++ {
- if BitIsSet(buf, i) {
- count++
- }
- }
-
- return count
+ begU64 := BytesForBits(int64(beg + init))
+ return count + CountSetBits(buf[begU64:], 0, n-init)
}
func roundUp(v, f int) int {
@@ -149,15 +127,6 @@ const (
uint64SizeBits = uint64SizeBytes * 8
)
-func bytesToUint64(b []byte) []uint64 {
- if cap(b) < uint64SizeBytes {
- return nil
- }
-
- h := (*reflect.SliceHeader)(unsafe.Pointer(&b))
- return unsafe.Slice((*uint64)(unsafe.Pointer(h.Data)),
cap(b)/uint64SizeBytes)[:len(b)/uint64SizeBytes]
-}
-
var (
// PrecedingBitmask is a convenience set of values as bitmasks for
checking
// prefix bits of a byte
diff --git a/go/internal/hashing/hash_string_go1.19.go
b/go/arrow/bitutil/bitutil_bytes.go
similarity index 58%
rename from go/internal/hashing/hash_string_go1.19.go
rename to go/arrow/bitutil/bitutil_bytes.go
index f38eb5c523..09dd5cbc67 100644
--- a/go/internal/hashing/hash_string_go1.19.go
+++ b/go/arrow/bitutil/bitutil_bytes.go
@@ -14,24 +14,24 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-//go:build !go1.20 && !tinygo
+//go:build go1.20 || tinygo
-package hashing
+package bitutil
import (
- "reflect"
"unsafe"
)
-func hashString(val string, alg uint64) uint64 {
- if val == "" {
- return Hash([]byte{}, alg)
+func bytesToUint64(b []byte) []uint64 {
+ if len(b) < uint64SizeBytes {
+ return nil
}
- // highly efficient way to get byte slice without copy before
- // the introduction of unsafe.StringData in go1.20
- //
(https://stackoverflow.com/questions/59209493/how-to-use-unsafe-get-a-byte-slice-from-a-string-without-memory-copy)
- const MaxInt32 = 1<<31 - 1
- buf := (*[MaxInt32]byte)(unsafe.Pointer((*reflect.StringHeader)(
- unsafe.Pointer(&val)).Data))[: len(val)&MaxInt32 :
len(val)&MaxInt32]
- return Hash(buf, alg)
+
+ ptr := unsafe.SliceData(b)
+ if ptr == nil {
+ return nil
+ }
+
+ return unsafe.Slice((*uint64)(unsafe.Pointer(ptr)),
+ len(b)/uint64SizeBytes)
}
diff --git a/go/arrow/cdata/cdata_allocate.go b/go/arrow/cdata/cdata_allocate.go
new file mode 100644
index 0000000000..da0bd957de
--- /dev/null
+++ b/go/arrow/cdata/cdata_allocate.go
@@ -0,0 +1,57 @@
+// 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 go1.20 || tinygo
+
+package cdata
+
+// #include <stdlib.h>
+// #include "arrow/c/abi.h"
+import "C"
+
+import (
+ "unsafe"
+)
+
+func allocateArrowSchemaArr(n int) (out []CArrowSchema) {
+ return unsafe.Slice((*CArrowSchema)(C.calloc(C.size_t(n),
+ C.sizeof_struct_ArrowSchema)), n)
+}
+
+func allocateArrowSchemaPtrArr(n int) (out []*CArrowSchema) {
+ return unsafe.Slice((**CArrowSchema)(C.calloc(C.size_t(n),
+ C.size_t(unsafe.Sizeof((*CArrowSchema)(nil))))), n)
+}
+
+func allocateArrowArrayArr(n int) (out []CArrowArray) {
+ return unsafe.Slice((*CArrowArray)(C.calloc(C.size_t(n),
+ C.sizeof_struct_ArrowArray)), n)
+}
+
+func allocateArrowArrayPtrArr(n int) (out []*CArrowArray) {
+ return unsafe.Slice((**CArrowArray)(C.calloc(C.size_t(n),
+ C.size_t(unsafe.Sizeof((*CArrowArray)(nil))))), n)
+}
+
+func allocateBufferPtrArr(n int) (out []*C.void) {
+ return unsafe.Slice((**C.void)(C.calloc(C.size_t(n),
+ C.size_t(unsafe.Sizeof((*C.void)(nil))))), n)
+}
+
+func allocateBufferSizeArr(n int) (out []C.int64_t) {
+ return unsafe.Slice((*C.int64_t)(C.calloc(C.size_t(n),
+ C.sizeof_int64_t)), n)
+}
diff --git a/go/arrow/cdata/cdata_exports.go b/go/arrow/cdata/cdata_exports.go
index d59c87712e..fecc8610bf 100644
--- a/go/arrow/cdata/cdata_exports.go
+++ b/go/arrow/cdata/cdata_exports.go
@@ -39,7 +39,6 @@ import (
"bytes"
"encoding/binary"
"fmt"
- "reflect"
"runtime/cgo"
"strconv"
"strings"
@@ -291,60 +290,6 @@ func (exp *schemaExporter) export(field arrow.Field) {
exp.exportMeta(&field.Metadata)
}
-func allocateArrowSchemaArr(n int) (out []CArrowSchema) {
- s := (*reflect.SliceHeader)(unsafe.Pointer(&out))
- s.Data = uintptr(C.calloc(C.size_t(n), C.sizeof_struct_ArrowSchema))
- s.Len = n
- s.Cap = n
-
- return
-}
-
-func allocateArrowSchemaPtrArr(n int) (out []*CArrowSchema) {
- s := (*reflect.SliceHeader)(unsafe.Pointer(&out))
- s.Data = uintptr(C.calloc(C.size_t(n),
C.size_t(unsafe.Sizeof((*CArrowSchema)(nil)))))
- s.Len = n
- s.Cap = n
-
- return
-}
-
-func allocateArrowArrayArr(n int) (out []CArrowArray) {
- s := (*reflect.SliceHeader)(unsafe.Pointer(&out))
- s.Data = uintptr(C.calloc(C.size_t(n), C.sizeof_struct_ArrowArray))
- s.Len = n
- s.Cap = n
-
- return
-}
-
-func allocateArrowArrayPtrArr(n int) (out []*CArrowArray) {
- s := (*reflect.SliceHeader)(unsafe.Pointer(&out))
- s.Data = uintptr(C.calloc(C.size_t(n),
C.size_t(unsafe.Sizeof((*CArrowArray)(nil)))))
- s.Len = n
- s.Cap = n
-
- return
-}
-
-func allocateBufferPtrArr(n int) (out []*C.void) {
- s := (*reflect.SliceHeader)(unsafe.Pointer(&out))
- s.Data = uintptr(C.calloc(C.size_t(n),
C.size_t(unsafe.Sizeof((*C.void)(nil)))))
- s.Len = n
- s.Cap = n
-
- return
-}
-
-func allocateBufferSizeArr(n int) (out []C.int64_t) {
- s := (*reflect.SliceHeader)(unsafe.Pointer(&out))
- s.Data = uintptr(C.calloc(C.size_t(n),
C.size_t(unsafe.Sizeof(int64(0)))))
- s.Len = n
- s.Cap = n
-
- return
-}
-
func (exp *schemaExporter) finish(out *CArrowSchema) {
out.dictionary = nil
if exp.dict != nil {
diff --git a/go/arrow/compute/exec/span.go b/go/arrow/compute/exec/span.go
index 6f9bb240e3..4425784f25 100644
--- a/go/arrow/compute/exec/span.go
+++ b/go/arrow/compute/exec/span.go
@@ -19,7 +19,6 @@
package exec
import (
- "reflect"
"sync/atomic"
"unsafe"
@@ -250,22 +249,6 @@ func (a *ArraySpan) resizeChildren(i int) {
}
}
-// convenience function for populating the offsets buffer from a scalar
-// value's size.
-func setOffsetsForScalar[T int32 | int64](span *ArraySpan, buf []T, valueSize
int64, bufidx int) {
- buf[0] = 0
- buf[1] = T(valueSize)
-
- b := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
- s := (*reflect.SliceHeader)(unsafe.Pointer(&span.Buffers[bufidx].Buf))
- s.Data = b.Data
- s.Len = 2 * int(unsafe.Sizeof(T(0)))
- s.Cap = s.Len
-
- span.Buffers[bufidx].Owner = nil
- span.Buffers[bufidx].SelfAlloc = false
-}
-
// FillFromScalar populates this ArraySpan as if it were a 1 length array
// with the single value equal to the passed in Scalar.
func (a *ArraySpan) FillFromScalar(val scalar.Scalar) {
diff --git a/go/internal/hashing/hash_string.go
b/go/arrow/compute/exec/span_offsets.go
similarity index 64%
copy from go/internal/hashing/hash_string.go
copy to go/arrow/compute/exec/span_offsets.go
index b772c7d7f8..d2d0398884 100644
--- a/go/internal/hashing/hash_string.go
+++ b/go/arrow/compute/exec/span_offsets.go
@@ -16,11 +16,21 @@
//go:build go1.20 || tinygo
-package hashing
+package exec
-import "unsafe"
+import (
+ "unsafe"
+)
-func hashString(val string, alg uint64) uint64 {
- buf := unsafe.Slice(unsafe.StringData(val), len(val))
- return Hash(buf, alg)
+// convenience function for populating the offsets buffer from a scalar
+// value's size.
+func setOffsetsForScalar[T int32 | int64](span *ArraySpan, buf []T, valueSize
int64, bufidx int) {
+ buf[0] = 0
+ buf[1] = T(valueSize)
+
+ span.Buffers[bufidx].Buf =
unsafe.Slice((*byte)(unsafe.Pointer(unsafe.SliceData(buf))),
+ 2*int(unsafe.Sizeof(T(0))))
+
+ span.Buffers[bufidx].Owner = nil
+ span.Buffers[bufidx].SelfAlloc = false
}
diff --git a/go/arrow/compute/fieldref.go b/go/arrow/compute/fieldref.go
index ab6d856f85..0c55c36dab 100644
--- a/go/arrow/compute/fieldref.go
+++ b/go/arrow/compute/fieldref.go
@@ -20,12 +20,10 @@ import (
"errors"
"fmt"
"hash/maphash"
- "math/bits"
"reflect"
"strconv"
"strings"
"unicode"
- "unsafe"
"github.com/apache/arrow/go/v16/arrow"
"github.com/apache/arrow/go/v16/arrow/array"
@@ -168,21 +166,6 @@ func (f FieldPath) GetColumn(batch arrow.Record)
(arrow.Array, error) {
return f.getArray(batch.Columns())
}
-func (f FieldPath) hash(h *maphash.Hash) {
- raw := (*reflect.SliceHeader)(unsafe.Pointer(&f)).Data
-
- var b []byte
- s := (*reflect.SliceHeader)(unsafe.Pointer(&b))
- s.Data = raw
- if bits.UintSize == 32 {
- s.Len = arrow.Int32Traits.BytesRequired(len(f))
- } else {
- s.Len = arrow.Int64Traits.BytesRequired(len(f))
- }
- s.Cap = s.Len
- h.Write(b)
-}
-
func (f FieldPath) findAll(fields []arrow.Field) []FieldPath {
_, err := f.GetFieldFromSlice(fields)
if err == nil {
diff --git a/go/internal/hashing/hash_string.go
b/go/arrow/compute/fieldref_hash.go
similarity index 67%
copy from go/internal/hashing/hash_string.go
copy to go/arrow/compute/fieldref_hash.go
index b772c7d7f8..dace05788b 100644
--- a/go/internal/hashing/hash_string.go
+++ b/go/arrow/compute/fieldref_hash.go
@@ -16,11 +16,24 @@
//go:build go1.20 || tinygo
-package hashing
+package compute
-import "unsafe"
+import (
+ "hash/maphash"
+ "math/bits"
+ "unsafe"
-func hashString(val string, alg uint64) uint64 {
- buf := unsafe.Slice(unsafe.StringData(val), len(val))
- return Hash(buf, alg)
+ "github.com/apache/arrow/go/v16/arrow"
+)
+
+func (f FieldPath) hash(h *maphash.Hash) {
+ raw := unsafe.Pointer(unsafe.SliceData(f))
+ var byteLen int
+ if bits.UintSize == 32 {
+ byteLen = arrow.Int32Traits.BytesRequired(len(f))
+ } else {
+ byteLen = arrow.Int64Traits.BytesRequired(len(f))
+ }
+
+ h.Write(unsafe.Slice((*byte)(raw), byteLen))
}
diff --git a/go/arrow/doc.go b/go/arrow/doc.go
index 2f7c8c2acf..19f24c5d0b 100644
--- a/go/arrow/doc.go
+++ b/go/arrow/doc.go
@@ -30,8 +30,6 @@ array is valid (not null). If the array has no null entries,
it is possible to o
# Requirements
-Despite the go.mod stating go1.20, everything is able to be built with go1.19
or higher.
-
To build with tinygo include the noasm build tag.
*/
package arrow
diff --git a/go/arrow/flight/flightsql/driver/driver_test.go
b/go/arrow/flight/flightsql/driver/driver_test.go
index 79955f6099..11b9036519 100644
--- a/go/arrow/flight/flightsql/driver/driver_test.go
+++ b/go/arrow/flight/flightsql/driver/driver_test.go
@@ -619,6 +619,7 @@ func (s *SqlTestSuite)
TestRowsPrematureCloseDuringNextLoop() {
require.NoError(t, err)
require.Equal(t, int64(rowCount), insertedRows)
+ time.Sleep(200 * time.Millisecond)
// Do query
const sqlSelectAll = `SELECT id, name, value FROM ` + tableName
diff --git a/go/arrow/memory/mallocator/mallocator.go
b/go/arrow/memory/mallocator/mallocator.go
index a111f009ec..59d240a106 100644
--- a/go/arrow/memory/mallocator/mallocator.go
+++ b/go/arrow/memory/mallocator/mallocator.go
@@ -30,7 +30,6 @@ package mallocator
import "C"
import (
- "reflect"
"sync/atomic"
"unsafe"
)
@@ -70,18 +69,18 @@ func (alloc *Mallocator) Allocate(size int) []byte {
}
func (alloc *Mallocator) Free(b []byte) {
- sh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
- C.free(unsafe.Pointer(sh.Data))
+ sz := len(b)
+ C.free(getPtr(b))
// Subtract sh.Len via two's complement (since atomic doesn't offer
subtract)
- atomic.AddUint64(&alloc.allocatedBytes, ^(uint64(sh.Len) - 1))
+ atomic.AddUint64(&alloc.allocatedBytes, ^(uint64(sz) - 1))
}
func (alloc *Mallocator) Reallocate(size int, b []byte) []byte {
if size < 0 {
panic("mallocator: negative size")
}
- sh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
- ptr, err := C.realloc_and_initialize(unsafe.Pointer(sh.Data),
C.size_t(sh.Cap), C.size_t(size))
+ cp := cap(b)
+ ptr, err := C.realloc_and_initialize(getPtr(b), C.size_t(cp),
C.size_t(size))
if err != nil {
panic(err)
} else if ptr == nil && size != 0 {
diff --git a/go/arrow/memory/mallocator/mallocator_util.go
b/go/arrow/memory/mallocator/mallocator_util.go
new file mode 100644
index 0000000000..0ab5f8f515
--- /dev/null
+++ b/go/arrow/memory/mallocator/mallocator_util.go
@@ -0,0 +1,26 @@
+// 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 go1.20 || tinygo
+
+package mallocator
+
+import "unsafe"
+
+func getPtr(b []byte) unsafe.Pointer {
+ return unsafe.Pointer(unsafe.SliceData(b))
+}
diff --git a/go/go.mod b/go/go.mod
index 5c297c74d6..2f788c5c26 100644
--- a/go/go.mod
+++ b/go/go.mod
@@ -16,7 +16,7 @@
module github.com/apache/arrow/go/v16
-go 1.20
+go 1.21
require (
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c
diff --git a/go/internal/hashing/hash_string.go
b/go/internal/hashing/hash_string.go
index b772c7d7f8..c8579c1ec5 100644
--- a/go/internal/hashing/hash_string.go
+++ b/go/internal/hashing/hash_string.go
@@ -24,3 +24,7 @@ func hashString(val string, alg uint64) uint64 {
buf := unsafe.Slice(unsafe.StringData(val), len(val))
return Hash(buf, alg)
}
+
+func strToBytes(v string) []byte {
+ return unsafe.Slice(unsafe.StringData(v), len(v))
+}
diff --git a/go/internal/hashing/xxh3_memo_table.go
b/go/internal/hashing/xxh3_memo_table.go
index 283bc1a953..fbb8b33531 100644
--- a/go/internal/hashing/xxh3_memo_table.go
+++ b/go/internal/hashing/xxh3_memo_table.go
@@ -22,7 +22,6 @@ package hashing
import (
"bytes"
"math"
- "reflect"
"unsafe"
)
@@ -183,13 +182,7 @@ func (BinaryMemoTable) valAsByteSlice(val interface{})
[]byte {
case ByteSlice:
return v.Bytes()
case string:
- var out []byte
- h := (*reflect.StringHeader)(unsafe.Pointer(&v))
- s := (*reflect.SliceHeader)(unsafe.Pointer(&out))
- s.Data = h.Data
- s.Len = h.Len
- s.Cap = h.Len
- return out
+ return strToBytes(v)
default:
panic("invalid type for binarymemotable")
}
diff --git a/go/parquet/types.go b/go/parquet/types.go
index 8742c3ba8b..5447e793b4 100644
--- a/go/parquet/types.go
+++ b/go/parquet/types.go
@@ -95,27 +95,13 @@ type int96Traits struct{}
func (int96Traits) BytesRequired(n int) int { return Int96SizeBytes * n }
func (int96Traits) CastFromBytes(b []byte) []Int96 {
- h := (*reflect.SliceHeader)(unsafe.Pointer(&b))
-
- var res []Int96
- s := (*reflect.SliceHeader)(unsafe.Pointer(&res))
- s.Data = h.Data
- s.Len = h.Len / Int96SizeBytes
- s.Cap = h.Cap / Int96SizeBytes
-
- return res
+ return unsafe.Slice((*Int96)(unsafe.Pointer(unsafe.SliceData(b))),
+ len(b)/Int96SizeBytes)
}
func (int96Traits) CastToBytes(b []Int96) []byte {
- h := (*reflect.SliceHeader)(unsafe.Pointer(&b))
-
- var res []byte
- s := (*reflect.SliceHeader)(unsafe.Pointer(&res))
- s.Data = h.Data
- s.Len = h.Len * Int96SizeBytes
- s.Cap = h.Cap * Int96SizeBytes
-
- return res
+ return unsafe.Slice((*byte)(unsafe.Pointer(unsafe.SliceData(b))),
+ len(b)*Int96SizeBytes)
}
// ByteArray is a type to be utilized for representing the Parquet ByteArray
physical type, represented as a byte slice
@@ -142,15 +128,8 @@ func (byteArrayTraits) BytesRequired(n int) int {
}
func (byteArrayTraits) CastFromBytes(b []byte) []ByteArray {
- h := (*reflect.SliceHeader)(unsafe.Pointer(&b))
-
- var res []ByteArray
- s := (*reflect.SliceHeader)(unsafe.Pointer(&res))
- s.Data = h.Data
- s.Len = h.Len / ByteArraySizeBytes
- s.Cap = h.Cap / ByteArraySizeBytes
-
- return res
+ return unsafe.Slice((*ByteArray)(unsafe.Pointer(unsafe.SliceData(b))),
+ len(b)/ByteArraySizeBytes)
}
// FixedLenByteArray is a go type to represent a FixedLengthByteArray as a
byte slice
@@ -177,15 +156,8 @@ func (fixedLenByteArrayTraits) BytesRequired(n int) int {
}
func (fixedLenByteArrayTraits) CastFromBytes(b []byte) []FixedLenByteArray {
- h := (*reflect.SliceHeader)(unsafe.Pointer(&b))
-
- var res []FixedLenByteArray
- s := (*reflect.SliceHeader)(unsafe.Pointer(&res))
- s.Data = h.Data
- s.Len = h.Len / FixedLenByteArraySizeBytes
- s.Cap = h.Cap / FixedLenByteArraySizeBytes
-
- return res
+ return
unsafe.Slice((*FixedLenByteArray)(unsafe.Pointer(unsafe.SliceData(b))),
+ len(b)/FixedLenByteArraySizeBytes)
}
// Creating our own enums allows avoiding the transitive dependency on the