github.com/apache/arrow/go/v16@v16.1.0/arrow/array/numericbuilder.gen.go.tmpl (about)

     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  
    17  package array
    18  
    19  import (
    20  	"github.com/apache/arrow/go/v16/arrow"
    21  	"github.com/apache/arrow/go/v16/arrow/bitutil"
    22  	"github.com/apache/arrow/go/v16/arrow/internal/debug"
    23  	"github.com/apache/arrow/go/v16/arrow/memory"
    24  	"github.com/apache/arrow/go/v16/internal/json"
    25  )
    26  
    27  {{range .In}}
    28  
    29  type {{.Name}}Builder struct {
    30  	builder
    31  
    32  {{if .Opt.Parametric -}}
    33  	dtype    *arrow.{{.Name}}Type
    34  {{end -}}
    35  	data    *memory.Buffer
    36  	rawData []{{or .QualifiedType .Type}}
    37  }
    38  
    39  {{if .Opt.Parametric}}
    40  func New{{.Name}}Builder(mem memory.Allocator, dtype *arrow.{{.Name}}Type) *{{.Name}}Builder {
    41  	return &{{.Name}}Builder{builder: builder{refCount:1, mem: mem}, dtype: dtype}
    42  }
    43  
    44  func (b *{{.Name}}Builder) Type() arrow.DataType { return b.dtype }
    45  
    46  {{else}}
    47  func New{{.Name}}Builder(mem memory.Allocator) *{{.Name}}Builder {
    48  	return &{{.Name}}Builder{builder: builder{refCount:1, mem: mem}}
    49  }
    50  
    51  func (b *{{.Name}}Builder) Type() arrow.DataType { return arrow.PrimitiveTypes.{{.Name}} }
    52  {{end}}
    53  
    54  // Release decreases the reference count by 1.
    55  // When the reference count goes to zero, the memory is freed.
    56  func (b *{{.Name}}Builder) Release() {
    57  	debug.Assert(atomic.LoadInt64(&b.refCount) > 0, "too many releases")
    58  
    59  	if atomic.AddInt64(&b.refCount, -1) == 0 {
    60  		if b.nullBitmap != nil {
    61  			b.nullBitmap.Release()
    62  			b.nullBitmap = nil
    63  		}
    64  		if b.data != nil {
    65  			b.data.Release()
    66  			b.data = nil
    67  			b.rawData = nil
    68  		}
    69  	}
    70  }
    71  
    72  func (b *{{.Name}}Builder) Append(v {{or .QualifiedType .Type}}) {
    73  	b.Reserve(1)
    74  	b.UnsafeAppend(v)
    75  }
    76  
    77  func (b *{{.Name}}Builder) AppendNull() {
    78  	b.Reserve(1)
    79  	b.UnsafeAppendBoolToBitmap(false)
    80  }
    81  
    82  func (b *{{.Name}}Builder) AppendNulls(n int) {
    83  	for i := 0; i < n; i++ {
    84  		b.AppendNull()
    85  	}
    86  }
    87  
    88  func (b *{{.Name}}Builder) AppendEmptyValue() {
    89  	b.Append(0)
    90  }
    91  
    92  func (b *{{.Name}}Builder) AppendEmptyValues(n int) {
    93  	for i := 0; i < n; i ++ {
    94  		b.AppendEmptyValue()
    95  	}
    96  }
    97  
    98  func (b *{{.Name}}Builder) UnsafeAppend(v {{or .QualifiedType .Type}}) {
    99  	bitutil.SetBit(b.nullBitmap.Bytes(), b.length)
   100  	b.rawData[b.length] = v
   101  	b.length++
   102  }
   103  
   104  func (b *{{.Name}}Builder) UnsafeAppendBoolToBitmap(isValid bool) {
   105  	if isValid {
   106  		bitutil.SetBit(b.nullBitmap.Bytes(), b.length)
   107  	} else {
   108  		b.nulls++
   109  	}
   110  	b.length++
   111  }
   112  
   113  // AppendValues will append the values in the v slice. The valid slice determines which values
   114  // in v are valid (not null). The valid slice must either be empty or be equal in length to v. If empty,
   115  // all values in v are appended and considered valid.
   116  func (b *{{.Name}}Builder) AppendValues(v []{{or .QualifiedType .Type}}, valid []bool) {
   117  	if len(v) != len(valid) && len(valid) != 0 {
   118  		panic("len(v) != len(valid) && len(valid) != 0")
   119  	}
   120  
   121  	if len(v) == 0 {
   122  		return
   123  	}
   124  
   125  	b.Reserve(len(v))
   126  	arrow.{{.Name}}Traits.Copy(b.rawData[b.length:], v)
   127  	b.builder.unsafeAppendBoolsToBitmap(valid, len(v))
   128  }
   129  
   130  func (b *{{.Name}}Builder) init(capacity int) {
   131  	b.builder.init(capacity)
   132  
   133  	b.data = memory.NewResizableBuffer(b.mem)
   134  	bytesN := arrow.{{.Name}}Traits.BytesRequired(capacity)
   135  	b.data.Resize(bytesN)
   136  	b.rawData = arrow.{{.Name}}Traits.CastFromBytes(b.data.Bytes())
   137  }
   138  
   139  // Reserve ensures there is enough space for appending n elements
   140  // by checking the capacity and calling Resize if necessary.
   141  func (b *{{.Name}}Builder) Reserve(n int) {
   142  	b.builder.reserve(n, b.Resize)
   143  }
   144  
   145  // Resize adjusts the space allocated by b to n elements. If n is greater than b.Cap(),
   146  // additional memory will be allocated. If n is smaller, the allocated memory may reduced.
   147  func (b *{{.Name}}Builder) Resize(n int) {
   148  	nBuilder := n
   149  	if n < minBuilderCapacity {
   150  		n = minBuilderCapacity
   151  	}
   152  
   153  	if b.capacity == 0 {
   154  		b.init(n)
   155  	} else {
   156  		b.builder.resize(nBuilder, b.init)
   157  		b.data.Resize(arrow.{{.Name}}Traits.BytesRequired(n))
   158  		b.rawData = arrow.{{.Name}}Traits.CastFromBytes(b.data.Bytes())
   159  	}
   160  }
   161  
   162  func (b *{{.Name}}Builder) Value(i int) {{or .QualifiedType .Type}} {
   163  	return b.rawData[i]
   164  }
   165  
   166  // NewArray creates a {{.Name}} array from the memory buffers used by the builder and resets the {{.Name}}Builder
   167  // so it can be used to build a new array.
   168  func (b *{{.Name}}Builder) NewArray() arrow.Array {
   169  	return b.New{{.Name}}Array()
   170  }
   171  
   172  // New{{.Name}}Array creates a {{.Name}} array from the memory buffers used by the builder and resets the {{.Name}}Builder
   173  // so it can be used to build a new array.
   174  func (b *{{.Name}}Builder) New{{.Name}}Array() (a *{{.Name}}) {
   175  	data := b.newData()
   176  	a = New{{.Name}}Data(data)
   177  	data.Release()
   178  	return
   179  }
   180  
   181  func (b *{{.Name}}Builder) newData() (data *Data) {
   182  	bytesRequired := arrow.{{.Name}}Traits.BytesRequired(b.length)
   183  	if bytesRequired > 0 && bytesRequired < b.data.Len() {
   184  		// trim buffers
   185  		b.data.Resize(bytesRequired)
   186  	}
   187  {{if .Opt.Parametric -}}
   188  	data = NewData(b.dtype, b.length, []*memory.Buffer{b.nullBitmap, b.data}, nil, b.nulls, 0)
   189  {{else -}}
   190  	data = NewData(arrow.PrimitiveTypes.{{.Name}}, b.length, []*memory.Buffer{b.nullBitmap, b.data}, nil, b.nulls, 0)
   191  {{end -}}
   192  	b.reset()
   193  
   194  	if b.data != nil {
   195  		b.data.Release()
   196  		b.data = nil
   197  		b.rawData = nil
   198  	}
   199  
   200  	return
   201  }
   202  
   203  func (b *{{.Name}}Builder) AppendValueFromString(s string) error {
   204  	if s == NullValueStr {
   205  		b.AppendNull()
   206  		return nil
   207  	}
   208    {{if or (eq .Name "Date32") -}}
   209    	tm, err := time.Parse("2006-01-02", s)
   210      if err != nil {
   211        b.AppendNull()
   212        return err
   213      }
   214      b.Append(arrow.Date32FromTime(tm))
   215    {{else if or (eq .Name "Date64") -}}
   216    	tm, err := time.Parse("2006-01-02", s)
   217      if err != nil {
   218        b.AppendNull()
   219        return err
   220      }
   221      b.Append(arrow.Date64FromTime(tm))
   222    {{else if or (eq .Name "Time32") -}}
   223    	val, err := arrow.Time32FromString(s, b.dtype.Unit)
   224      if err != nil {
   225        b.AppendNull()
   226        return err
   227      }
   228      b.Append(val)
   229    {{else if or (eq .Name "Time64") -}}
   230      val, err := arrow.Time64FromString(s, b.dtype.Unit)
   231      if err != nil {
   232        b.AppendNull()
   233        return err
   234      }
   235      b.Append(val)
   236    {{else if (eq .Name "Duration") -}}
   237  	dur, err := time.ParseDuration(s)
   238  	if err != nil {
   239  		return err
   240  	}
   241  
   242  	b.Append(arrow.Duration(dur / b.dtype.Unit.Multiplier()))
   243    {{else if or (eq .Name "Int8") (eq .Name "Int16") (eq .Name "Int32") (eq .Name "Int64") -}}
   244      v, err := strconv.ParseInt(s, 10, {{.Size}} * 8)
   245      if err != nil {
   246          b.AppendNull()
   247          return err
   248      }
   249      b.Append({{.name}}(v))
   250    {{else if or (eq .Name "Uint8") (eq .Name "Uint16") (eq .Name "Uint32") (eq .Name "Uint64") -}}
   251      v, err := strconv.ParseUint(s, 10, {{.Size}} * 8)
   252      if err != nil {
   253          b.AppendNull()
   254          return err
   255      }
   256      b.Append({{.name}}(v))
   257    {{else if or (eq .Name "Float32") (eq .Name "Float64") -}}
   258      v, err := strconv.ParseFloat(s, {{.Size}} * 8)
   259      if err != nil {
   260        b.AppendNull()
   261        return err
   262      }
   263      b.Append({{.name}}(v))
   264    {{end -}}
   265  	return nil
   266  }
   267  
   268  func (b *{{.Name}}Builder) UnmarshalOne(dec *json.Decoder) error {
   269  	t, err := dec.Token()
   270  	if err != nil {
   271  		return err
   272  	}
   273  
   274  	switch v := t.(type) {
   275  	case nil:
   276  		b.AppendNull()
   277  {{if or (eq .Name "Date32") (eq .Name "Date64") -}}
   278  	case string:
   279  		tm, err := time.Parse("2006-01-02", v)
   280  		if err != nil {
   281  			return &json.UnmarshalTypeError{
   282  				Value: v,
   283  				Type: reflect.TypeOf({{.QualifiedType}}(0)),
   284  				Offset: dec.InputOffset(),
   285  			}
   286  		}
   287  
   288  		b.Append({{.QualifiedType}}FromTime(tm))
   289  	case json.Number:
   290  		n, err := v.Int64()
   291  		if err != nil {
   292  			return &json.UnmarshalTypeError{
   293  				Value: v.String(),
   294  				Type: reflect.TypeOf({{.QualifiedType}}(0)),
   295  				Offset: dec.InputOffset(),
   296  			}
   297  		}
   298  		b.Append({{.QualifiedType}}(n))
   299  	case float64:
   300  		b.Append({{.QualifiedType}}(v))
   301  {{else if or (eq .Name "Time32") (eq .Name "Time64") -}}
   302  	case string:
   303  		tm, err := {{.QualifiedType}}FromString(v, b.dtype.Unit)
   304  		if err != nil {
   305  			return &json.UnmarshalTypeError{
   306  				Value: v,
   307  				Type: reflect.TypeOf({{.QualifiedType}}(0)),
   308  				Offset: dec.InputOffset(),
   309  			}
   310  		}
   311  
   312  		b.Append(tm)
   313  	case json.Number:
   314  		n, err := v.Int64()
   315  		if err != nil {
   316  			return &json.UnmarshalTypeError{
   317  				Value: v.String(),
   318  				Type: reflect.TypeOf({{.QualifiedType}}(0)),
   319  				Offset: dec.InputOffset(),
   320  			}
   321  		}
   322  		b.Append({{.QualifiedType}}(n))
   323  	case float64:
   324  		b.Append({{.QualifiedType}}(v))
   325  {{else if eq .Name "Duration" -}}
   326  	case json.Number:
   327  		n, err := v.Int64()
   328  		if err != nil {
   329  			return &json.UnmarshalTypeError{
   330  				Value: v.String(),
   331  				Type: reflect.TypeOf({{.QualifiedType}}(0)),
   332  				Offset: dec.InputOffset(),
   333  			}
   334  		}
   335  		b.Append({{.QualifiedType}}(n))
   336  	case float64:
   337  		b.Append({{.QualifiedType}}(v))
   338  	case string:
   339  		// be flexible for specifying durations by accepting forms like
   340  		// 3h2m0.5s regardless of the unit and converting it to the proper
   341  		// precision.
   342  		val, err := time.ParseDuration(v)
   343  		if err != nil {
   344  			// if we got an error, maybe it was because the attempt to create
   345  			// a time.Duration (int64) in nanoseconds would overflow. check if
   346  			// the string is just a large number followed by the unit suffix
   347  			if strings.HasSuffix(v, b.dtype.Unit.String()) {
   348  				value, err := strconv.ParseInt(v[:len(v)-len(b.dtype.Unit.String())], 10, 64)
   349  				if err == nil {
   350  					b.Append(arrow.Duration(value))
   351  					break
   352  				}
   353  			}
   354  
   355  			return &json.UnmarshalTypeError{
   356  				Value: v,
   357  				Type: reflect.TypeOf({{.QualifiedType}}(0)),
   358  				Offset: dec.InputOffset(),
   359  			}
   360  		}
   361  
   362  		switch b.dtype.Unit {
   363  		case arrow.Nanosecond:
   364  			b.Append({{.QualifiedType}}(val.Nanoseconds()))
   365  		case arrow.Microsecond:
   366  			b.Append({{.QualifiedType}}(val.Microseconds()))
   367  		case arrow.Millisecond:
   368  			b.Append({{.QualifiedType}}(val.Milliseconds()))
   369  		case arrow.Second:
   370  			b.Append({{.QualifiedType}}(val.Seconds()))
   371  		}
   372  {{else}}
   373  	case string:
   374  {{if or (eq .Name "Float32") (eq .Name "Float64") -}}
   375  		f, err := strconv.ParseFloat(v, {{.Size}}*8)
   376  {{else if eq (printf "%.1s" .Name) "U" -}}
   377  		f, err := strconv.ParseUint(v, 10, {{.Size}}*8)
   378  {{else -}}
   379  		f, err := strconv.ParseInt(v, 10, {{.Size}}*8)
   380  {{end -}}
   381  		if err != nil {
   382  			return &json.UnmarshalTypeError{
   383  				Value: v,
   384  				Type: reflect.TypeOf({{.name}}(0)),
   385  				Offset: dec.InputOffset(),
   386  			}
   387  		}
   388  		b.Append({{.name}}(f))
   389  	case float64:
   390  		b.Append({{.name}}(v))
   391  	case json.Number:
   392  {{if or (eq .Name "Float32") (eq .Name "Float64") -}}
   393  		f, err := strconv.ParseFloat(v.String(), {{.Size}}*8)
   394  {{else if eq (printf "%.1s" .Name) "U" -}}
   395  		f, err := strconv.ParseUint(v.String(), 10, {{.Size}}*8)
   396  {{else -}}
   397  		f, err := strconv.ParseInt(v.String(), 10, {{.Size}}*8)
   398  {{end -}}
   399  		if err != nil {
   400  			return &json.UnmarshalTypeError{
   401  				Value: v.String(),
   402  				Type: reflect.TypeOf({{.name}}(0)),
   403  				Offset: dec.InputOffset(),
   404  			}
   405  		}
   406  		b.Append({{.name}}(f))
   407  {{end}}
   408  	default:
   409  		return &json.UnmarshalTypeError{
   410  			Value: fmt.Sprint(t),
   411  			Type: reflect.TypeOf({{or .QualifiedType .Type}}(0)),
   412  			Offset: dec.InputOffset(),
   413  		}
   414  	}
   415  
   416  	return nil
   417  }
   418  
   419  func (b *{{.Name}}Builder) Unmarshal(dec *json.Decoder) error {
   420  	for dec.More() {
   421  		if err := b.UnmarshalOne(dec); err != nil {
   422  			return err
   423  		}
   424  	}
   425  	return nil
   426  }
   427  
   428  func (b *{{.Name}}Builder) UnmarshalJSON(data []byte) error {
   429  	dec := json.NewDecoder(bytes.NewReader(data))
   430  	t, err := dec.Token()
   431  	if err != nil {
   432  		return err
   433  	}
   434  
   435  	if delim, ok := t.(json.Delim); !ok || delim != '[' {
   436  		return fmt.Errorf("binary builder must unpack from json array, found %s", delim)
   437  	}
   438  
   439  	return b.Unmarshal(dec)
   440  }
   441  {{end}}
   442  
   443  var (
   444  {{- range .In}}
   445  	_ Builder = (*{{.Name}}Builder)(nil)
   446  {{- end}}
   447  )