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-go.git


The following commit(s) were added to refs/heads/main by this push:
     new 281776d9 docs(arrow/memory): document allocator alignment and which 
allocator to use when C retains buffers (#1302)
281776d9 is described below

commit 281776d9292c5229c48c336bca3af4d339369cce
Author: singhpratech <[email protected]>
AuthorDate: Tue Sep 8 15:18:36 2026 -0400

    docs(arrow/memory): document allocator alignment and which allocator to use 
when C retains buffers (#1302)
    
    ### Rationale for this change
    
    Nothing in the `memory` package said what alignment an allocator
    guarantees, or which allocator to
    use for buffers that C will keep after the cgo call. The `cdata` export
    comment named only the
    `CgoArrowAllocator`, which needs the Arrow C++ library, while
    `mallocator` covers the same need
    without it. Discussed in #1297.
    
    ### What changes are included in this PR?
    
    Two sections in the `memory` package comment: the 64-byte alignment
    `GoAllocator` and
    `mallocator.NewMallocator` provide and `NewMallocatorWithAlignment` for
    anything larger; and the
    cgo pointer rule with the two allocators that return C memory. Doc
    comments on `GoAllocator` and
    `NewGoAllocator`. The `ExportArrowRecordBatch` comment now names
    `mallocator.Mallocator` alongside
    `CgoArrowAllocator` and points at the package doc.
    
    ### Are these changes tested?
    
    Documentation only; `go vet` and `go build ./...` pass and `go doc
    ./arrow/memory` renders the new sections.
    
    ### Are there any user-facing changes?
    
    Documentation only.
    
    Closes #1297.
---
 arrow/cdata/interface.go     |  9 ++++++---
 arrow/memory/doc.go          | 22 ++++++++++++++++++++++
 arrow/memory/go_allocator.go |  5 +++++
 3 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/arrow/cdata/interface.go b/arrow/cdata/interface.go
index 03a9e7b0..6641f267 100644
--- a/arrow/cdata/interface.go
+++ b/arrow/cdata/interface.go
@@ -228,9 +228,12 @@ func ExportArrowSchema(schema *arrow.Schema, out 
*CArrowSchema) {
 // stay valid. This is only true until the CGO call returns, at which point 
the garbage collector
 // is free to move things around again. As a result, if the function you're 
calling is going to
 // hold onto the pointers or otherwise continue to reference the memory 
*after* the call returns,
-// you should use the CgoArrowAllocator rather than the GoAllocator (or 
DefaultAllocator) so that
-// the memory which is allocated for the record batch in the first place is 
allocated in C,
-// not by the Go runtime and is therefore not subject to the Garbage 
collection.
+// you should build the record with an allocator that returns C memory rather 
than the GoAllocator
+// (or DefaultAllocator), so that the memory which is allocated for the record 
batch in the first
+// place is allocated in C, not by the Go runtime, and is therefore not 
subject to the Garbage
+// collection: mallocator.Mallocator (libc malloc, no C++ dependency) or, when 
the Arrow C++
+// library is linked, the CgoArrowAllocator behind the 'ccalloc' build tag. 
See the memory
+// package documentation for the alignment each allocator guarantees.
 //
 // The release function on the populated CArrowArray will properly decrease 
the reference counts,
 // and release the memory if the record has already been released. But since 
this must be explicitly
diff --git a/arrow/memory/doc.go b/arrow/memory/doc.go
index 20a28e4e..e8d11e4f 100644
--- a/arrow/memory/doc.go
+++ b/arrow/memory/doc.go
@@ -18,5 +18,27 @@
 Package memory provides support for allocating and manipulating memory at a 
low level.
 
 The build tag 'mallocator' will switch the default allocator to one backed by 
libc malloc. This also requires CGO.
+
+# Alignment
+
+[GoAllocator] (the [DefaultAllocator] unless the 'mallocator' build tag is 
set) returns
+buffers whose start is rounded up to a multiple of 64 bytes, and the 
mallocator package's
+[github.com/apache/arrow-go/v18/arrow/memory/mallocator.NewMallocator] does 
the same for
+libc memory. Neither promises more than 64. A consumer that needs a larger 
alignment (a
+page-aligned buffer for a GPU runtime, mmap or DMA, for example) should 
allocate with
+[github.com/apache/arrow-go/v18/arrow/memory/mallocator.NewMallocatorWithAlignment],
+which takes any power of two.
+
+# Sharing buffers with C
+
+Memory from [GoAllocator] lives on the Go heap. Under the cgo pointer rules
+(https://pkg.go.dev/cmd/cgo#hdr-Passing_pointers) C code may use such a 
pointer only
+for the duration of the cgo call it was passed to; it must not keep it, 
because the
+garbage collector may move or free the memory. Buffers that C will hold on to, 
such as
+arrays exported over the C Data Interface with the cdata package and retained 
by the
+consumer, should therefore be allocated with an allocator that returns C 
memory:
+[github.com/apache/arrow-go/v18/arrow/memory/mallocator.Mallocator] (libc 
malloc, no
+C++ dependency, requires cgo) or, when the Arrow C++ library is linked, the
+CgoArrowAllocator behind the 'ccalloc' build tag.
 */
 package memory
diff --git a/arrow/memory/go_allocator.go b/arrow/memory/go_allocator.go
index 6ccf5f75..b121f087 100644
--- a/arrow/memory/go_allocator.go
+++ b/arrow/memory/go_allocator.go
@@ -16,8 +16,13 @@
 
 package memory
 
+// GoAllocator is an Allocator backed by the Go heap. Buffers it returns start
+// at a 64-byte boundary; Free is a no-op because the garbage collector 
reclaims
+// the memory. Its buffers must not be retained by C code beyond a single cgo
+// call; see the package documentation for allocators that return C memory.
 type GoAllocator struct{}
 
+// NewGoAllocator returns a GoAllocator.
 func NewGoAllocator() *GoAllocator { return &GoAllocator{} }
 
 func (a *GoAllocator) Allocate(size int) []byte {

Reply via email to