237 lines
6.9 KiB
Go
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!")
|
|
}
|
|
}
|