package array
import (
"bytes"
"fmt"
"github.com/apache/arrow-go/v18/arrow"
"github.com/apache/arrow-go/v18/arrow/memory"
"github.com/apache/arrow-go/v18/internal/json"
)
type Map struct {
*List
keys, items arrow .Array
}
var _ ListLike = (*Map )(nil )
func NewMapData (data arrow .ArrayData ) *Map {
a := &Map {List : &List {}}
a .refCount .Add (1 )
a .setData (data .(*Data ))
return a
}
func (a *Map ) KeysSorted () bool { return a .DataType ().(*arrow .MapType ).KeysSorted }
func (a *Map ) validateData (data *Data ) {
if len (data .childData ) != 1 || data .childData [0 ] == nil {
panic ("arrow/array: expected one child array for map array" )
}
if data .childData [0 ].DataType ().ID () != arrow .STRUCT {
panic ("arrow/array: map array child should be struct type" )
}
if data .childData [0 ].NullN () != 0 {
panic ("arrow/array: map array child array should have no nulls" )
}
if len (data .childData [0 ].Children ()) != 2 {
panic ("arrow/array: map array child array should have two fields" )
}
if data .childData [0 ].Children ()[0 ].NullN () != 0 {
panic ("arrow/array: map array keys array should have no nulls" )
}
}
func (a *Map ) setData (data *Data ) {
a .validateData (data )
a .List .setData (data )
a .keys = MakeFromData (data .childData [0 ].Children ()[0 ])
a .items = MakeFromData (data .childData [0 ].Children ()[1 ])
}
func (a *Map ) Keys () arrow .Array { return a .keys }
func (a *Map ) Items () arrow .Array { return a .items }
func (a *Map ) Retain () {
a .List .Retain ()
a .keys .Retain ()
a .items .Retain ()
}
func (a *Map ) Release () {
a .List .Release ()
a .keys .Release ()
a .items .Release ()
}
func arrayEqualMap(left , right *Map ) bool {
return arrayEqualList (left .List , right .List )
}
type MapBuilder struct {
listBuilder *ListBuilder
etype *arrow .MapType
keytype, itemtype arrow .DataType
keyBuilder, itemBuilder Builder
keysSorted bool
}
func NewMapBuilder (mem memory .Allocator , keytype , itemtype arrow .DataType , keysSorted bool ) *MapBuilder {
etype := arrow .MapOf (keytype , itemtype )
etype .KeysSorted = keysSorted
listBldr := NewListBuilder (mem , etype .Elem ())
keyBldr := listBldr .ValueBuilder ().(*StructBuilder ).FieldBuilder (0 )
keyBldr .Retain ()
itemBldr := listBldr .ValueBuilder ().(*StructBuilder ).FieldBuilder (1 )
itemBldr .Retain ()
return &MapBuilder {
listBuilder : listBldr ,
keyBuilder : keyBldr ,
itemBuilder : itemBldr ,
etype : etype ,
keytype : keytype ,
itemtype : itemtype ,
keysSorted : keysSorted ,
}
}
func NewMapBuilderWithType (mem memory .Allocator , dt *arrow .MapType ) *MapBuilder {
listBldr := NewListBuilder (mem , dt .Elem ())
keyBldr := listBldr .ValueBuilder ().(*StructBuilder ).FieldBuilder (0 )
keyBldr .Retain ()
itemBldr := listBldr .ValueBuilder ().(*StructBuilder ).FieldBuilder (1 )
itemBldr .Retain ()
return &MapBuilder {
listBuilder : listBldr ,
keyBuilder : keyBldr ,
itemBuilder : itemBldr ,
etype : dt ,
keytype : dt .KeyType (),
itemtype : dt .ItemType (),
keysSorted : dt .KeysSorted ,
}
}
func (b *MapBuilder ) Type () arrow .DataType { return b .etype }
func (b *MapBuilder ) Retain () {
b .listBuilder .Retain ()
b .keyBuilder .Retain ()
b .itemBuilder .Retain ()
}
func (b *MapBuilder ) Release () {
b .listBuilder .Release ()
b .keyBuilder .Release ()
b .itemBuilder .Release ()
}
func (b *MapBuilder ) Len () int { return b .listBuilder .Len () }
func (b *MapBuilder ) Cap () int { return b .listBuilder .Cap () }
func (b *MapBuilder ) NullN () int { return b .listBuilder .NullN () }
func (b *MapBuilder ) IsNull (i int ) bool {
return b .listBuilder .IsNull (i )
}
func (b *MapBuilder ) Append (v bool ) {
b .adjustStructBuilderLen ()
b .listBuilder .Append (v )
}
func (b *MapBuilder ) AppendWithSize (v bool , _ int ) {
b .Append (v )
}
func (b *MapBuilder ) AppendNull () {
b .Append (false )
}
func (b *MapBuilder ) AppendNulls (n int ) {
for i := 0 ; i < n ; i ++ {
b .AppendNull ()
}
}
func (b *MapBuilder ) SetNull (i int ) {
b .listBuilder .SetNull (i )
}
func (b *MapBuilder ) AppendEmptyValue () {
b .Append (true )
}
func (b *MapBuilder ) AppendEmptyValues (n int ) {
for i := 0 ; i < n ; i ++ {
b .AppendEmptyValue ()
}
}
func (b *MapBuilder ) Reserve (n int ) { b .listBuilder .Reserve (n ) }
func (b *MapBuilder ) Resize (n int ) { b .listBuilder .Resize (n ) }
func (b *MapBuilder ) AppendValues (offsets []int32 , valid []bool ) {
b .adjustStructBuilderLen ()
b .listBuilder .AppendValues (offsets , valid )
}
func (b *MapBuilder ) UnsafeAppendBoolToBitmap (v bool ) {
b .listBuilder .UnsafeAppendBoolToBitmap (v )
}
func (b *MapBuilder ) init (capacity int ) { b .listBuilder .init (capacity ) }
func (b *MapBuilder ) resize (newBits int , init func (int )) { b .listBuilder .resize (newBits , init ) }
func (b *MapBuilder ) adjustStructBuilderLen () {
sb := b .listBuilder .ValueBuilder ().(*StructBuilder )
if sb .Len () < b .keyBuilder .Len () {
valids := make ([]bool , b .keyBuilder .Len ()-sb .Len ())
for i := range valids {
valids [i ] = true
}
sb .AppendValues (valids )
}
}
func (b *MapBuilder ) NewArray () arrow .Array {
return b .NewMapArray ()
}
func (b *MapBuilder ) NewMapArray () (a *Map ) {
if !b .etype .ItemField ().Nullable && b .ItemBuilder ().NullN () > 0 {
panic ("arrow/array: item not nullable" )
}
data := b .newData ()
defer data .Release ()
a = NewMapData (data )
return
}
func (b *MapBuilder ) newData () (data *Data ) {
b .adjustStructBuilderLen ()
values := b .listBuilder .NewListArray ()
defer values .Release ()
data = NewData (b .etype ,
values .Len (), values .data .buffers ,
values .data .childData , values .NullN (), 0 )
return
}
func (b *MapBuilder ) KeyBuilder () Builder { return b .keyBuilder }
func (b *MapBuilder ) ItemBuilder () Builder { return b .itemBuilder }
func (b *MapBuilder ) ValueBuilder () Builder {
return b .listBuilder .ValueBuilder ()
}
func (b *MapBuilder ) AppendValueFromString (s string ) error {
return b .listBuilder .AppendValueFromString (s )
}
func (b *MapBuilder ) UnmarshalOne (dec *json .Decoder ) error {
return b .listBuilder .UnmarshalOne (dec )
}
func (b *MapBuilder ) Unmarshal (dec *json .Decoder ) error {
return b .listBuilder .Unmarshal (dec )
}
func (b *MapBuilder ) UnmarshalJSON (data []byte ) error {
dec := json .NewDecoder (bytes .NewReader (data ))
t , err := dec .Token ()
if err != nil {
return err
}
if delim , ok := t .(json .Delim ); !ok || delim != '[' {
return fmt .Errorf ("map builder must unpack from json array, found %s" , delim )
}
return b .Unmarshal (dec )
}
var (
_ arrow .Array = (*Map )(nil )
_ Builder = (*MapBuilder )(nil )
_ ListLikeBuilder = (*MapBuilder )(nil )
)
The pages are generated with Golds v0.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 .