github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/soliton/rowcodec/common.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package rowcodec
    15  
    16  import (
    17  	"encoding/binary"
    18  	"reflect"
    19  	"unsafe"
    20  
    21  	"github.com/whtcorpsinc/errors"
    22  	"github.com/whtcorpsinc/BerolinaSQL/perceptron"
    23  	"github.com/whtcorpsinc/BerolinaSQL/types"
    24  )
    25  
    26  // CodecVer is the constant number that represent the new event format.
    27  const CodecVer = 128
    28  
    29  var errInvalidCodecVer = errors.New("invalid codec version")
    30  
    31  // First byte in the encoded value which specifies the encoding type.
    32  const (
    33  	NilFlag          byte = 0
    34  	BytesFlag        byte = 1
    35  	CompactBytesFlag byte = 2
    36  	IntFlag          byte = 3
    37  	UintFlag         byte = 4
    38  	FloatFlag        byte = 5
    39  	DecimalFlag      byte = 6
    40  	VarintFlag       byte = 8
    41  	VaruintFlag      byte = 9
    42  	JSONFlag         byte = 10
    43  )
    44  
    45  func bytesToU32Slice(b []byte) []uint32 {
    46  	if len(b) == 0 {
    47  		return nil
    48  	}
    49  	var u32s []uint32
    50  	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&u32s))
    51  	hdr.Len = len(b) / 4
    52  	hdr.Cap = hdr.Len
    53  	hdr.Data = uintptr(unsafe.Pointer(&b[0]))
    54  	return u32s
    55  }
    56  
    57  func bytes2U16Slice(b []byte) []uint16 {
    58  	if len(b) == 0 {
    59  		return nil
    60  	}
    61  	var u16s []uint16
    62  	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&u16s))
    63  	hdr.Len = len(b) / 2
    64  	hdr.Cap = hdr.Len
    65  	hdr.Data = uintptr(unsafe.Pointer(&b[0]))
    66  	return u16s
    67  }
    68  
    69  func u16SliceToBytes(u16s []uint16) []byte {
    70  	if len(u16s) == 0 {
    71  		return nil
    72  	}
    73  	var b []byte
    74  	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    75  	hdr.Len = len(u16s) * 2
    76  	hdr.Cap = hdr.Len
    77  	hdr.Data = uintptr(unsafe.Pointer(&u16s[0]))
    78  	return b
    79  }
    80  
    81  func u32SliceToBytes(u32s []uint32) []byte {
    82  	if len(u32s) == 0 {
    83  		return nil
    84  	}
    85  	var b []byte
    86  	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    87  	hdr.Len = len(u32s) * 4
    88  	hdr.Cap = hdr.Len
    89  	hdr.Data = uintptr(unsafe.Pointer(&u32s[0]))
    90  	return b
    91  }
    92  
    93  func encodeInt(buf []byte, iVal int64) []byte {
    94  	var tmp [8]byte
    95  	if int64(int8(iVal)) == iVal {
    96  		buf = append(buf, byte(iVal))
    97  	} else if int64(int16(iVal)) == iVal {
    98  		binary.LittleEndian.PutUint16(tmp[:], uint16(iVal))
    99  		buf = append(buf, tmp[:2]...)
   100  	} else if int64(int32(iVal)) == iVal {
   101  		binary.LittleEndian.PutUint32(tmp[:], uint32(iVal))
   102  		buf = append(buf, tmp[:4]...)
   103  	} else {
   104  		binary.LittleEndian.PutUint64(tmp[:], uint64(iVal))
   105  		buf = append(buf, tmp[:8]...)
   106  	}
   107  	return buf
   108  }
   109  
   110  func decodeInt(val []byte) int64 {
   111  	switch len(val) {
   112  	case 1:
   113  		return int64(int8(val[0]))
   114  	case 2:
   115  		return int64(int16(binary.LittleEndian.Uint16(val)))
   116  	case 4:
   117  		return int64(int32(binary.LittleEndian.Uint32(val)))
   118  	default:
   119  		return int64(binary.LittleEndian.Uint64(val))
   120  	}
   121  }
   122  
   123  func encodeUint(buf []byte, uVal uint64) []byte {
   124  	var tmp [8]byte
   125  	if uint64(uint8(uVal)) == uVal {
   126  		buf = append(buf, byte(uVal))
   127  	} else if uint64(uint16(uVal)) == uVal {
   128  		binary.LittleEndian.PutUint16(tmp[:], uint16(uVal))
   129  		buf = append(buf, tmp[:2]...)
   130  	} else if uint64(uint32(uVal)) == uVal {
   131  		binary.LittleEndian.PutUint32(tmp[:], uint32(uVal))
   132  		buf = append(buf, tmp[:4]...)
   133  	} else {
   134  		binary.LittleEndian.PutUint64(tmp[:], uVal)
   135  		buf = append(buf, tmp[:8]...)
   136  	}
   137  	return buf
   138  }
   139  
   140  func decodeUint(val []byte) uint64 {
   141  	switch len(val) {
   142  	case 1:
   143  		return uint64(val[0])
   144  	case 2:
   145  		return uint64(binary.LittleEndian.Uint16(val))
   146  	case 4:
   147  		return uint64(binary.LittleEndian.Uint32(val))
   148  	default:
   149  		return binary.LittleEndian.Uint64(val)
   150  	}
   151  }
   152  
   153  type largeNotNullSorter CausetEncoder
   154  
   155  func (s *largeNotNullSorter) Less(i, j int) bool {
   156  	return s.defCausIDs32[i] < s.defCausIDs32[j]
   157  }
   158  
   159  func (s *largeNotNullSorter) Len() int {
   160  	return int(s.numNotNullDefCauss)
   161  }
   162  
   163  func (s *largeNotNullSorter) Swap(i, j int) {
   164  	s.defCausIDs32[i], s.defCausIDs32[j] = s.defCausIDs32[j], s.defCausIDs32[i]
   165  	s.values[i], s.values[j] = s.values[j], s.values[i]
   166  }
   167  
   168  type smallNotNullSorter CausetEncoder
   169  
   170  func (s *smallNotNullSorter) Less(i, j int) bool {
   171  	return s.defCausIDs[i] < s.defCausIDs[j]
   172  }
   173  
   174  func (s *smallNotNullSorter) Len() int {
   175  	return int(s.numNotNullDefCauss)
   176  }
   177  
   178  func (s *smallNotNullSorter) Swap(i, j int) {
   179  	s.defCausIDs[i], s.defCausIDs[j] = s.defCausIDs[j], s.defCausIDs[i]
   180  	s.values[i], s.values[j] = s.values[j], s.values[i]
   181  }
   182  
   183  type smallNullSorter CausetEncoder
   184  
   185  func (s *smallNullSorter) Less(i, j int) bool {
   186  	nullDefCauss := s.defCausIDs[s.numNotNullDefCauss:]
   187  	return nullDefCauss[i] < nullDefCauss[j]
   188  }
   189  
   190  func (s *smallNullSorter) Len() int {
   191  	return int(s.numNullDefCauss)
   192  }
   193  
   194  func (s *smallNullSorter) Swap(i, j int) {
   195  	nullDefCauss := s.defCausIDs[s.numNotNullDefCauss:]
   196  	nullDefCauss[i], nullDefCauss[j] = nullDefCauss[j], nullDefCauss[i]
   197  }
   198  
   199  type largeNullSorter CausetEncoder
   200  
   201  func (s *largeNullSorter) Less(i, j int) bool {
   202  	nullDefCauss := s.defCausIDs32[s.numNotNullDefCauss:]
   203  	return nullDefCauss[i] < nullDefCauss[j]
   204  }
   205  
   206  func (s *largeNullSorter) Len() int {
   207  	return int(s.numNullDefCauss)
   208  }
   209  
   210  func (s *largeNullSorter) Swap(i, j int) {
   211  	nullDefCauss := s.defCausIDs32[s.numNotNullDefCauss:]
   212  	nullDefCauss[i], nullDefCauss[j] = nullDefCauss[j], nullDefCauss[i]
   213  }
   214  
   215  const (
   216  	// Length of rowkey.
   217  	rowKeyLen = 19
   218  	// Index of record flag 'r' in rowkey used by milevadb-server.
   219  	// The rowkey format is t{8 bytes id}_r{8 bytes handle}
   220  	recordPrefixIdx = 10
   221  )
   222  
   223  // IsRowKey determine whether key is event key.
   224  // this method will be used in entangledstore.
   225  func IsRowKey(key []byte) bool {
   226  	return len(key) >= rowKeyLen && key[0] == 't' && key[recordPrefixIdx] == 'r'
   227  }
   228  
   229  // IsNewFormat checks whether event data is in new-format.
   230  func IsNewFormat(rowData []byte) bool {
   231  	return rowData[0] == CodecVer
   232  }
   233  
   234  // FieldTypeFromPerceptronDeferredCauset creates a types.FieldType from perceptron.DeferredCausetInfo.
   235  // export for test case and CDC.
   236  func FieldTypeFromPerceptronDeferredCauset(defCaus *perceptron.DeferredCausetInfo) *types.FieldType {
   237  	return &types.FieldType{
   238  		Tp:      defCaus.Tp,
   239  		Flag:    defCaus.Flag,
   240  		Flen:    defCaus.Flen,
   241  		Decimal: defCaus.Decimal,
   242  		Elems:   defCaus.Elems,
   243  		Charset: defCaus.Charset,
   244  		DefCauslate: defCaus.DefCauslate,
   245  	}
   246  }