Files
tidb/pkg/util/serialization/deserialization_util.go
2024-01-29 07:21:29 +00:00

237 lines
6.9 KiB
Go

// Copyright 2023 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package serialization
import (
"bytes"
"time"
"unsafe"
"github.com/pingcap/tidb/pkg/types"
"github.com/pingcap/tidb/pkg/util/chunk"
)
// PosAndBuf is the parameter of all DeserializeXXX functions
type PosAndBuf struct {
Buf []byte
Pos int64
}
// Reset resets data in PosAndBuf
func (p *PosAndBuf) Reset(col *chunk.Column, idx int) {
p.Buf = col.GetBytes(idx)
p.Pos = 0
}
func deserializeBuffer(posAndBuf *PosAndBuf) []byte {
bufLen := DeserializeInt(posAndBuf) // Get buffer length
retVal := posAndBuf.Buf[posAndBuf.Pos : posAndBuf.Pos+int64(bufLen)]
posAndBuf.Pos += int64(bufLen)
return retVal
}
// DeserializeByte deserializes byte type
func DeserializeByte(posAndBuf *PosAndBuf) byte {
retVal := posAndBuf.Buf[posAndBuf.Pos]
posAndBuf.Pos++
return retVal
}
// DeserializeBool deserializes bool type
func DeserializeBool(posAndBuf *PosAndBuf) bool {
retVal := *(*bool)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += BoolLen
return retVal
}
// DeserializeInt deserializes int type
func DeserializeInt(posAndBuf *PosAndBuf) int {
retVal := *(*int)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += IntLen
return retVal
}
// DeserializeInt8 deserializes int8 type
func DeserializeInt8(posAndBuf *PosAndBuf) int8 {
retVal := *(*int8)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += Int8Len
return retVal
}
// DeserializeUint8 deserializes int8 type
func DeserializeUint8(posAndBuf *PosAndBuf) uint8 {
retVal := *(*uint8)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += Uint8Len
return retVal
}
// DeserializeInt32 deserializes int32 type
func DeserializeInt32(posAndBuf *PosAndBuf) int32 {
retVal := *(*int32)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += Int32Len
return retVal
}
// DeserializeUint32 deserializes uint32 type
func DeserializeUint32(posAndBuf *PosAndBuf) uint32 {
retVal := *(*uint32)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += Uint32Len
return retVal
}
// DeserializeUint64 deserializes uint64 type
func DeserializeUint64(posAndBuf *PosAndBuf) uint64 {
retVal := *(*uint64)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += Uint64Len
return retVal
}
// DeserializeInt64 deserializes int64 type
func DeserializeInt64(posAndBuf *PosAndBuf) int64 {
retVal := *(*int64)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += Int64Len
return retVal
}
// DeserializeFloat32 deserializes float32 type
func DeserializeFloat32(posAndBuf *PosAndBuf) float32 {
retVal := *(*float32)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += Float32Len
return retVal
}
// DeserializeFloat64 deserializes float64 type
func DeserializeFloat64(posAndBuf *PosAndBuf) float64 {
retVal := *(*float64)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += Float64Len
return retVal
}
// DeserializeMyDecimal deserializes MyDecimal type
func DeserializeMyDecimal(posAndBuf *PosAndBuf) types.MyDecimal {
retVal := *(*types.MyDecimal)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += types.MyDecimalStructSize
return retVal
}
// DeserializeTime deserializes Time type
func DeserializeTime(posAndBuf *PosAndBuf) types.Time {
retVal := *(*types.Time)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += TimeLen
return retVal
}
// DeserializeTimeDuration deserializes time.Duration type
func DeserializeTimeDuration(posAndBuf *PosAndBuf) time.Duration {
retVal := *(*time.Duration)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += TimeDurationLen
return retVal
}
// DeserializeTypesDuration deserializes types.Duration type
func DeserializeTypesDuration(posAndBuf *PosAndBuf) types.Duration {
retVal := types.Duration{}
retVal.Duration = DeserializeTimeDuration(posAndBuf)
retVal.Fsp = DeserializeInt(posAndBuf)
return retVal
}
// DeserializeJSONTypeCode deserializes JSONTypeCode type
func DeserializeJSONTypeCode(posAndBuf *PosAndBuf) types.JSONTypeCode {
retVal := *(*types.JSONTypeCode)(unsafe.Pointer(&posAndBuf.Buf[posAndBuf.Pos]))
posAndBuf.Pos += JSONTypeCodeLen
return retVal
}
// DeserializeBinaryJSON deserializes BinaryJSON type
func DeserializeBinaryJSON(posAndBuf *PosAndBuf) types.BinaryJSON {
retValue := types.BinaryJSON{}
retValue.TypeCode = DeserializeJSONTypeCode(posAndBuf)
buf := deserializeBuffer(posAndBuf)
retValue.Value = make([]byte, len(buf))
copy(retValue.Value, buf)
return retValue
}
// DeserializeSet deserializes Set type
func DeserializeSet(posAndBuf *PosAndBuf) types.Set {
retValue := types.Set{}
retValue.Value = DeserializeUint64(posAndBuf)
retValue.Name = DeserializeString(posAndBuf)
return retValue
}
// DeserializeEnum deserializes Enum type
func DeserializeEnum(posAndBuf *PosAndBuf) types.Enum {
retValue := types.Enum{}
retValue.Value = DeserializeUint64(posAndBuf)
retValue.Name = DeserializeString(posAndBuf)
return retValue
}
// DeserializeOpaque deserializes Opaque type
func DeserializeOpaque(posAndBuf *PosAndBuf) types.Opaque {
retVal := types.Opaque{}
retVal.TypeCode = DeserializeByte(posAndBuf)
buf := deserializeBuffer(posAndBuf)
retVal.Buf = make([]byte, len(buf))
copy(retVal.Buf, buf)
return retVal
}
// DeserializeString deserializes String type
func DeserializeString(posAndBuf *PosAndBuf) string {
buf := deserializeBuffer(posAndBuf)
return string(buf)
}
// DeserializeBytesBuffer deserializes bytes.Buffer type
func DeserializeBytesBuffer(posAndBuf *PosAndBuf) *bytes.Buffer {
buf := deserializeBuffer(posAndBuf)
tmp := make([]byte, len(buf))
copy(tmp, buf)
return bytes.NewBuffer(tmp)
}
// DeserializeInterface deserializes interface type
func DeserializeInterface(posAndBuf *PosAndBuf) any {
// Get type
dataType := int(posAndBuf.Buf[posAndBuf.Pos])
posAndBuf.Pos += InterfaceTypeCodeLen
switch dataType {
case BoolType:
return DeserializeBool(posAndBuf)
case Int64Type:
return DeserializeInt64(posAndBuf)
case Uint64Type:
return DeserializeUint64(posAndBuf)
case FloatType:
return DeserializeFloat64(posAndBuf)
case StringType:
return DeserializeString(posAndBuf)
case BinaryJSONType:
return DeserializeBinaryJSON(posAndBuf)
case OpaqueType:
return DeserializeOpaque(posAndBuf)
case TimeType:
return DeserializeTime(posAndBuf)
case DurationType:
return DeserializeTypesDuration(posAndBuf)
default:
panic("Invalid data type happens in agg spill deserializing!")
}
}