in memstore/common/upsert_batch_builder.go [154:305]
func (c *columnBuilder) AppendToBuffer(writer *utils.BufferWriter) error {
writer.AlignBytes(1)
// both gotype and array type is variable length
isVariableLength := IsGoType(c.dataType) || IsArrayType(c.dataType)
switch c.GetMode() {
case AllValuesDefault:
return nil
case HasNullVector:
// only non goType needs to write null vector
if !IsGoType(c.dataType) {
for row := 0; row < len(c.values); row++ {
value := c.values[row]
if err := writer.AppendBool(value != nil); err != nil {
return utils.StackError(err, "Failed to write null vector at row %d", row)
}
}
}
fallthrough
case AllValuesPresent:
var offsetWriter, valueWriter *utils.BufferWriter
// variable length data type needs to write offsetVector
if isVariableLength {
// Padding to 4 byte alignment for offset vector
writer.AlignBytes(4)
writerForked := *writer
offsetWriter = &writerForked
// skip offset bytes
writer.SkipBytes((len(c.values) + 1) * 4)
}
// Padding to 8 byte alignment for value vector
writer.AlignBytes(8)
valueWriter = writer
// local byte offset of current value in value vector
currentValueOffset := uint32(0)
// write values starting from current value vector offset
for row := 0; row < len(c.values); row++ {
// write current offset if offsetWriter is defined
if offsetWriter != nil {
err := offsetWriter.AppendUint32(currentValueOffset)
if err != nil {
return utils.StackError(err, "Failed to write offset value at row %d", row)
}
}
value := c.values[row]
// Handle null value.
if value == nil {
// only skip bits when there is no offset vector
if offsetWriter == nil {
valueWriter.SkipBits(DataTypeBits(c.dataType))
}
continue
}
switch c.dataType {
case Bool:
if err := valueWriter.AppendBool(value.(bool)); err != nil {
return utils.StackError(err, "Failed to write bool value at row %d", row)
}
case Int8:
if err := valueWriter.AppendInt8(value.(int8)); err != nil {
return utils.StackError(err, "Failed to write int8 value at row %d", row)
}
case Uint8:
if err := valueWriter.AppendUint8(value.(uint8)); err != nil {
return utils.StackError(err, "Failed to write uint8 value at row %d", row)
}
case Int16:
if err := valueWriter.AppendInt16(value.(int16)); err != nil {
return utils.StackError(err, "Failed to write int16 value at row %d", row)
}
case Uint16:
if err := valueWriter.AppendUint16(value.(uint16)); err != nil {
return utils.StackError(err, "Failed to write uint16 value at row %d", row)
}
case Int32:
if err := valueWriter.AppendInt32(value.(int32)); err != nil {
return utils.StackError(err, "Failed to write int32 value at row %d", row)
}
case Int64:
if err := valueWriter.AppendInt64(value.(int64)); err != nil {
return utils.StackError(err, "Failed to write int64 value at row %d", row)
}
case Uint32:
if err := valueWriter.AppendUint32(value.(uint32)); err != nil {
return utils.StackError(err, "Failed to write uint32 value at row %d", row)
}
case Float32:
if err := valueWriter.AppendFloat32(value.(float32)); err != nil {
return utils.StackError(err, "Failed to write float32 value at row %d", row)
}
case SmallEnum:
if err := valueWriter.AppendUint8(value.(uint8)); err != nil {
return utils.StackError(err, "Failed to write small enum value at row %d", row)
}
case BigEnum:
if err := valueWriter.AppendUint16(value.(uint16)); err != nil {
return utils.StackError(err, "Failed to write big enum value at row %d", row)
}
case UUID:
err := valueWriter.AppendUint64(value.([2]uint64)[0])
if err == nil {
err = writer.AppendUint64(value.([2]uint64)[1])
}
if err != nil {
return utils.StackError(err, "Failed to write uuid value at row %d", row)
}
case GeoPoint:
err := valueWriter.AppendFloat32(value.([2]float32)[0])
if err == nil {
err = writer.AppendFloat32(value.([2]float32)[1])
}
if err != nil {
return utils.StackError(err, "Failed to write geopoint value at row %d", row)
}
case GeoShape:
goVal := value.(GoDataValue)
dataWriter := utils.NewStreamDataWriter(valueWriter)
err := goVal.Write(&dataWriter)
if err != nil {
return utils.StackError(err, "Failed to write geoshape value at row %d", row)
}
// advance current offset
currentValueOffset += uint32(goVal.GetSerBytes())
default:
if IsArrayType(c.dataType) {
arrayValue := value.(*ArrayValue)
bytes := arrayValue.GetSerBytes()
err := arrayValue.Write(valueWriter)
if err != nil {
return utils.StackError(err, "Failed to write array value at row %d", row)
}
// advance current offset
currentValueOffset += uint32(bytes)
}
}
}
// lastly write the final offset into offsetWriter
if offsetWriter != nil {
err := offsetWriter.AppendUint32(currentValueOffset)
if err != nil {
return utils.StackError(err, "Failed to write offset value at row %d", len(c.values))
}
}
}
// Align at byte for bit values.
writer.AlignBytes(1)
return nil
}