1// Licensed to the Apache Software Foundation (ASF) under one 2// or more contributor license agreements. See the NOTICE file 3// distributed with this work for additional information 4// regarding copyright ownership. The ASF licenses this file 5// to you under the Apache License, Version 2.0 (the 6// "License"); you may not use this file except in compliance 7// with the License. You may obtain a copy of the License at 8// 9// http://www.apache.org/licenses/LICENSE-2.0 10// 11// Unless required by applicable law or agreed to in writing, software 12// distributed under the License is distributed on an "AS IS" BASIS, 13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14// See the License for the specific language governing permissions and 15// limitations under the License. 16 17package array 18 19import ( 20 "strings" 21 "sync/atomic" 22 23 "github.com/apache/arrow/go/v6/arrow" 24 "github.com/apache/arrow/go/v6/arrow/internal/debug" 25 "github.com/apache/arrow/go/v6/arrow/memory" 26) 27 28// Null represents an immutable, degenerate array with no physical storage. 29type Null struct { 30 array 31} 32 33// NewNull returns a new Null array value of size n. 34func NewNull(n int) *Null { 35 a := &Null{} 36 a.refCount = 1 37 data := NewData( 38 arrow.Null, n, 39 []*memory.Buffer{nil}, 40 nil, 41 n, 42 0, 43 ) 44 a.setData(data) 45 data.Release() 46 return a 47} 48 49// NewNullData returns a new Null array value, from data. 50func NewNullData(data *Data) *Null { 51 a := &Null{} 52 a.refCount = 1 53 a.setData(data) 54 return a 55} 56 57func (a *Null) String() string { 58 o := new(strings.Builder) 59 o.WriteString("[") 60 for i := 0; i < a.Len(); i++ { 61 if i > 0 { 62 o.WriteString(" ") 63 } 64 o.WriteString("(null)") 65 } 66 o.WriteString("]") 67 return o.String() 68} 69 70func (a *Null) setData(data *Data) { 71 a.array.setData(data) 72 a.array.nullBitmapBytes = nil 73 a.array.data.nulls = a.array.data.length 74} 75 76type NullBuilder struct { 77 builder 78} 79 80// NewNullBuilder returns a builder, using the provided memory allocator. 81func NewNullBuilder(mem memory.Allocator) *NullBuilder { 82 return &NullBuilder{builder: builder{refCount: 1, mem: mem}} 83} 84 85// Release decreases the reference count by 1. 86// When the reference count goes to zero, the memory is freed. 87func (b *NullBuilder) Release() { 88 debug.Assert(atomic.LoadInt64(&b.refCount) > 0, "too many releases") 89 90 if atomic.AddInt64(&b.refCount, -1) == 0 { 91 if b.nullBitmap != nil { 92 b.nullBitmap.Release() 93 b.nullBitmap = nil 94 } 95 } 96} 97 98func (b *NullBuilder) AppendNull() { 99 b.builder.length++ 100 b.builder.nulls++ 101} 102 103func (*NullBuilder) Reserve(size int) {} 104func (*NullBuilder) Resize(size int) {} 105 106func (*NullBuilder) init(cap int) {} 107func (*NullBuilder) resize(newBits int, init func(int)) {} 108 109// NewArray creates a Null array from the memory buffers used by the builder and resets the NullBuilder 110// so it can be used to build a new array. 111func (b *NullBuilder) NewArray() Interface { 112 return b.NewNullArray() 113} 114 115// NewNullArray creates a Null array from the memory buffers used by the builder and resets the NullBuilder 116// so it can be used to build a new array. 117func (b *NullBuilder) NewNullArray() (a *Null) { 118 data := b.newData() 119 a = NewNullData(data) 120 data.Release() 121 return 122} 123 124func (b *NullBuilder) newData() (data *Data) { 125 data = NewData( 126 arrow.Null, b.length, 127 []*memory.Buffer{nil}, 128 nil, 129 b.nulls, 130 0, 131 ) 132 b.reset() 133 134 return 135} 136 137var ( 138 _ Interface = (*Null)(nil) 139 _ Builder = (*NullBuilder)(nil) 140) 141