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 }