in arrow/array/concat.go [226:325]
func concat(data []*Data, mem memory.Allocator) (*Data, error) {
out := &Data{refCount: 1, dtype: data[0].dtype, nulls: 0}
for _, d := range data {
out.length += d.length
if out.nulls == UnknownNullCount || d.nulls == UnknownNullCount {
out.nulls = UnknownNullCount
continue
}
out.nulls += d.nulls
}
out.buffers = make([]*memory.Buffer, len(data[0].buffers))
if out.nulls != 0 && out.dtype.ID() != arrow.NULL {
bm, err := concatBitmaps(gatherBitmaps(data, 0), mem)
if err != nil {
return nil, err
}
out.buffers[0] = bm
}
switch dt := out.dtype.(type) {
case *arrow.NullType:
case *arrow.BooleanType:
bm, err := concatBitmaps(gatherBitmaps(data, 1), mem)
if err != nil {
return nil, err
}
out.buffers[1] = bm
case arrow.FixedWidthDataType:
out.buffers[1] = concatBuffers(gatherBuffersFixedWidthType(data, 1, dt), mem)
case arrow.BinaryDataType:
offsetBuffer, valueRanges, err := concatOffsets(gatherFixedBuffers(data, 1, arrow.Int32SizeBytes), mem)
if err != nil {
return nil, err
}
out.buffers[2] = concatBuffers(gatherBufferRanges(data, 2, valueRanges), mem)
out.buffers[1] = offsetBuffer
case *arrow.ListType:
offsetBuffer, valueRanges, err := concatOffsets(gatherFixedBuffers(data, 1, arrow.Int32SizeBytes), mem)
if err != nil {
return nil, err
}
childData := gatherChildrenRanges(data, 0, valueRanges)
for _, c := range childData {
defer c.Release()
}
out.buffers[1] = offsetBuffer
out.childData = make([]*Data, 1)
out.childData[0], err = concat(childData, mem)
if err != nil {
return nil, err
}
case *arrow.FixedSizeListType:
childData := gatherChildrenMultiplier(data, 0, int(dt.Len()))
for _, c := range childData {
defer c.Release()
}
children, err := concat(childData, mem)
if err != nil {
return nil, err
}
out.childData = []*Data{children}
case *arrow.StructType:
out.childData = make([]*Data, len(dt.Fields()))
for i := range dt.Fields() {
children := gatherChildren(data, i)
for _, c := range children {
defer c.Release()
}
childData, err := concat(children, mem)
if err != nil {
return nil, err
}
out.childData[i] = childData
}
case *arrow.MapType:
offsetBuffer, valueRanges, err := concatOffsets(gatherFixedBuffers(data, 1, arrow.Int32SizeBytes), mem)
if err != nil {
return nil, err
}
childData := gatherChildrenRanges(data, 0, valueRanges)
for _, c := range childData {
defer c.Release()
}
out.buffers[1] = offsetBuffer
out.childData = make([]*Data, 1)
out.childData[0], err = concat(childData, mem)
if err != nil {
return nil, err
}
default:
return nil, xerrors.Errorf("concatenate not implemented for type %s", dt)
}
return out, nil
}