// 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.package arrayimport ()// Data represents the memory and metadata of an Arrow array.typeDatastruct { refCount atomic.Int64 dtype arrow.DataType nulls int offset int length int// for dictionary arrays: buffers will be the null validity bitmap and the indexes that reference // values in the dictionary member. childData would be empty in a dictionary array buffers []*memory.Buffer// TODO(sgc): should this be an interface? childData []arrow.ArrayData// TODO(sgc): managed by ListArray, StructArray and UnionArray types dictionary *Data// only populated for dictionary arrays}// NewData creates a new Data.func ( arrow.DataType, int, []*memory.Buffer, []arrow.ArrayData, , int) *Data {for , := range {if != nil { .Retain() } }for , := range {if != nil { .Retain() } } := &Data{dtype: ,nulls: ,length: ,offset: ,buffers: ,childData: , } .refCount.Add(1)return}// NewDataWithDictionary creates a new data object, but also sets the provided dictionary into the data if it's not nilfunc ( arrow.DataType, int, []*memory.Buffer, , int, *Data) *Data { := NewData(, , , nil, , )if != nil { .Retain() } .dictionary = return}func ( *Data) () *Data {// don't pass the slices directly, otherwise it retains the connection // we need to make new slices and populate them with the same pointers := make([]*memory.Buffer, len(.buffers))copy(, .buffers) := make([]arrow.ArrayData, len(.childData))copy(, .childData) := NewData(.dtype, .length, , , .nulls, .offset) .SetDictionary(.dictionary)return}// Reset sets the Data for re-use.func ( *Data) ( arrow.DataType, int, []*memory.Buffer, []arrow.ArrayData, , int) {// Retain new buffers before releasing existing buffers in-case they're the same ones to prevent accidental premature // release.for , := range {if != nil { .Retain() } }for , := range .buffers {if != nil { .Release() } } .buffers = // Retain new children data before releasing existing children data in-case they're the same ones to prevent accidental // premature release.for , := range {if != nil { .Retain() } }for , := range .childData {if != nil { .Release() } } .childData = .dtype = .length = .nulls = .offset = }// Retain increases the reference count by 1.// Retain may be called simultaneously from multiple goroutines.func ( *Data) () { .refCount.Add(1)}// Release decreases the reference count by 1.// When the reference count goes to zero, the memory is freed.// Release may be called simultaneously from multiple goroutines.func ( *Data) () {debug.Assert(.refCount.Load() > 0, "too many releases")if .refCount.Add(-1) == 0 {for , := range .buffers {if != nil { .Release() } }for , := range .childData {if != nil { .Release() } }if .dictionary != nil { .dictionary.() } .dictionary, .buffers, .childData = nil, nil, nil }}// DataType returns the DataType of the data.func ( *Data) () arrow.DataType { return .dtype }func ( *Data) ( int) { .nulls = }// NullN returns the number of nulls.func ( *Data) () int { return .nulls }// Len returns the length.func ( *Data) () int { return .length }// Offset returns the offset.func ( *Data) () int { return .offset }// Buffers returns the buffers.func ( *Data) () []*memory.Buffer { return .buffers }func ( *Data) () []arrow.ArrayData { return .childData }// Dictionary returns the ArrayData object for the dictionary member, or nilfunc ( *Data) () arrow.ArrayData { return .dictionary }// SetDictionary allows replacing the dictionary for this particular Data objectfunc ( *Data) ( arrow.ArrayData) {if .dictionary != nil { .dictionary.Release() .dictionary = nil }if .(*Data) != nil { .Retain() .dictionary = .(*Data) }}// SizeInBytes returns the size of the Data and any children and/or dictionary in bytes by// recursively examining the nested structures of children and/or dictionary.// The value returned is an upper-bound since offset is not taken into account.func ( *Data) () uint64 {varuint64if == nil {return0 }for , := range .Buffers() {if != nil { += uint64(.Len()) } }for , := range .Children() { += .SizeInBytes() }if .dictionary != nil { += .dictionary.() }return}// NewSliceData returns a new slice that shares backing data with the input.// The returned Data slice starts at i and extends j-i elements, such as://// slice := data[i:j]//// The returned value must be Release'd after use.//// NewSliceData panics if the slice is outside the valid range of the input Data.// NewSliceData panics if j < i.func ( arrow.ArrayData, , int64) arrow.ArrayData {if > int64(.Len()) || > || .Offset()+int() > .Offset()+.Len() {panic("arrow/array: index out of range") }for , := range .Buffers() {if != nil { .Retain() } }for , := range .Children() {if != nil { .Retain() } }if .(*Data).dictionary != nil { .(*Data).dictionary.Retain() } := &Data{dtype: .DataType(),nulls: UnknownNullCount,length: int( - ),offset: .Offset() + int(),buffers: .Buffers(),childData: .Children(),dictionary: .(*Data).dictionary, } .refCount.Add(1)if .NullN() == 0 { .nulls = 0 }return}func ( *maphash.Hash, arrow.ArrayData) { := .(*Data) .Write((*[bits.UintSize / 8]byte)(unsafe.Pointer(&.length))[:]) .Write((*[bits.UintSize / 8]byte)(unsafe.Pointer(&.length))[:])iflen(.buffers) > 0 && .buffers[0] != nil { .Write(.buffers[0].Bytes()) }for , := range .childData { (, ) }}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.