github.com/polarismesh/polaris@v1.17.8/store/boltdb/codec.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package boltdb 19 20 import ( 21 "bytes" 22 "encoding/binary" 23 "fmt" 24 "reflect" 25 "strings" 26 "time" 27 28 "github.com/golang/protobuf/proto" 29 bolt "go.etcd.io/bbolt" 30 ) 31 32 const ( 33 typeUnknown byte = iota 34 typeString 35 typeBool 36 typeTime 37 typeProtobuf 38 typeInt 39 typeInt8 40 typeInt16 41 typeInt32 42 typeInt64 43 typeUint 44 typeUint8 45 typeUint16 46 typeUint32 47 typeUint64 48 ) 49 50 var ( 51 timeType = reflect.TypeOf(time.Now()) 52 messageType = reflect.TypeOf((*proto.Message)(nil)).Elem() 53 numberKindToType = buildNumberKindToType() 54 ) 55 56 func buildNumberKindToType() map[reflect.Kind]byte { 57 values := make(map[reflect.Kind]byte) 58 values[reflect.Int] = typeInt 59 values[reflect.Int8] = typeInt8 60 values[reflect.Int16] = typeInt16 61 values[reflect.Int32] = typeInt32 62 values[reflect.Int64] = typeInt64 63 values[reflect.Uint] = typeUint 64 values[reflect.Uint8] = typeUint8 65 values[reflect.Uint16] = typeUint16 66 values[reflect.Uint32] = typeUint32 67 values[reflect.Uint64] = typeUint64 68 return values 69 } 70 71 func encodeStringBuffer(strValue string) []byte { 72 buf := bytes.NewBuffer(make([]byte, 0, len(strValue)+1)) 73 buf.WriteByte(typeString) 74 buf.WriteString(strValue) 75 return buf.Bytes() 76 } 77 78 func decodeStringBuffer(name string, buf []byte) (string, error) { 79 if len(buf) == 0 { 80 return "", nil 81 } 82 byteType := buf[0] 83 if byteType != typeString { 84 return "", 85 fmt.Errorf("invalid type field %s, want string(%v), actual is %v", name, typeString, byteType) 86 } 87 strBytes := buf[1:] 88 return string(strBytes), nil 89 } 90 91 func encodeIntBuffer(intValue int64, typeByte byte) []byte { 92 buf := bytes.NewBuffer(make([]byte, 0, 9)) 93 buf.WriteByte(typeByte) 94 b := make([]byte, 8) 95 binary.LittleEndian.PutUint64(b, uint64(intValue)) 96 buf.Write(b) 97 return buf.Bytes() 98 } 99 100 func encodeUintBuffer(intValue uint64, typeByte byte) []byte { 101 buf := bytes.NewBuffer(make([]byte, 0, 9)) 102 buf.WriteByte(typeByte) 103 b := make([]byte, 8) 104 binary.LittleEndian.PutUint64(b, intValue) 105 buf.Write(b) 106 return buf.Bytes() 107 } 108 109 func decodeIntBuffer(name string, buf []byte, typeByte byte) (int64, error) { 110 if len(buf) == 0 { 111 return 0, nil 112 } 113 byteType := buf[0] 114 if byteType != typeByte { 115 return 0, fmt.Errorf("invalid type field %s, want int(%v), actual is %v", name, typeByte, byteType) 116 } 117 intBytes := buf[1:] 118 value := binary.LittleEndian.Uint64(intBytes) 119 return int64(value), nil 120 } 121 122 func decodeUintBuffer(name string, buf []byte, typeByte byte) (uint64, error) { 123 if len(buf) == 0 { 124 return 0, nil 125 } 126 byteType := buf[0] 127 if byteType != typeByte { 128 return 0, fmt.Errorf("invalid type field %s, want uint(%v), actual is %v", name, typeByte, byteType) 129 } 130 intBytes := buf[1:] 131 value := binary.LittleEndian.Uint64(intBytes) 132 return value, nil 133 } 134 135 func encodeBoolBuffer(boolValue bool) []byte { 136 buf := bytes.NewBuffer(make([]byte, 0, 2)) 137 buf.WriteByte(typeBool) 138 if boolValue { 139 buf.WriteByte(1) 140 } else { 141 buf.WriteByte(0) 142 } 143 return buf.Bytes() 144 } 145 146 func decodeBoolBuffer(name string, buf []byte) (bool, error) { 147 if len(buf) == 0 { 148 return false, nil 149 } 150 byteType := buf[0] 151 if byteType != typeBool { 152 return false, 153 fmt.Errorf("invalid type field %s, want bool(%v), actual is %v", name, typeBool, byteType) 154 } 155 boolByte := buf[1] 156 return boolByte > 0, nil 157 } 158 159 func encodeRawMap(parent *bolt.Bucket, name string, values map[string]string) error { 160 nameByte := []byte(name) 161 var bucket *bolt.Bucket 162 var err error 163 if bucket = parent.Bucket(nameByte); bucket != nil { 164 err = parent.DeleteBucket(nameByte) 165 if err != nil { 166 return err 167 } 168 } 169 bucket, err = parent.CreateBucket(nameByte) 170 if err != nil { 171 return err 172 } 173 if len(values) == 0 { 174 return nil 175 } 176 for mapKey, mapValue := range values { 177 if err = bucket.Put([]byte(mapKey), []byte(mapValue)); err != nil { 178 return err 179 } 180 } 181 return nil 182 } 183 184 func encodeMapBuffer(parent *bolt.Bucket, name string, mapKeys []reflect.Value, fieldValue *reflect.Value) error { 185 nameByte := []byte(name) 186 var bucket *bolt.Bucket 187 var err error 188 if bucket = parent.Bucket(nameByte); bucket != nil { 189 err = parent.DeleteBucket(nameByte) 190 if err != nil { 191 return err 192 } 193 } 194 bucket, err = parent.CreateBucket(nameByte) 195 if err != nil { 196 return err 197 } 198 if len(mapKeys) == 0 { 199 return nil 200 } 201 for _, mapKey := range mapKeys { 202 keyStr := mapKey.String() 203 mapValue := fieldValue.MapIndex(mapKey) 204 valueStr := mapValue.String() 205 if err = bucket.Put([]byte(keyStr), []byte(valueStr)); err != nil { 206 return err 207 } 208 } 209 return nil 210 } 211 212 func decodeMapBuffer(bucket *bolt.Bucket) (map[string]string, error) { 213 values := make(map[string]string) 214 if bucket == nil { 215 return values, nil 216 } 217 err := bucket.ForEach(func(k, v []byte) error { 218 values[string(k)] = string(v) 219 return nil 220 }) 221 if err != nil { 222 return nil, err 223 } 224 return values, nil 225 } 226 227 func encodeTimeBuffer(timeValue time.Time) []byte { 228 intValue := timeValue.UnixNano() 229 buf := bytes.NewBuffer(make([]byte, 0, 9)) 230 buf.WriteByte(typeTime) 231 b := make([]byte, 8) 232 binary.LittleEndian.PutUint64(b, uint64(intValue)) 233 buf.Write(b) 234 return buf.Bytes() 235 } 236 237 func decodeTimeBuffer(name string, buf []byte) (time.Time, error) { 238 if len(buf) == 0 { 239 return time.Unix(0, 0), nil 240 } 241 byteType := buf[0] 242 if byteType != typeTime { 243 return time.Unix(0, 0), 244 fmt.Errorf("invalid type field %s, want time(%v), actual is %v", name, typeTime, byteType) 245 } 246 intBytes := buf[1:] 247 value := binary.LittleEndian.Uint64(intBytes) 248 return time.Unix(0, int64(value)), nil 249 } 250 251 func encodeMessageBuffer(msg proto.Message) ([]byte, error) { 252 protoBuf, err := proto.Marshal(msg) 253 if err != nil { 254 return nil, err 255 } 256 buf := bytes.NewBuffer(make([]byte, 0, len(protoBuf)+1)) 257 buf.WriteByte(typeProtobuf) 258 buf.Write(protoBuf) 259 return buf.Bytes(), nil 260 } 261 262 func decodeMessageBuffer(msg proto.Message, name string, buf []byte) (proto.Message, error) { 263 if len(buf) == 0 { 264 return nil, nil 265 } 266 byteType := buf[0] 267 if byteType != typeProtobuf { 268 return nil, fmt.Errorf("invalid type field %s, want protoBuf(%v), actual is %v", name, typeProtobuf, byteType) 269 } 270 protoBytes := buf[1:] 271 err := proto.Unmarshal(protoBytes, msg) 272 if err != nil { 273 return nil, err 274 } 275 return msg, nil 276 } 277 278 func serializeObject(parent *bolt.Bucket, value interface{}) (map[string][]byte, error) { 279 rawValue := reflect.ValueOf(value) 280 into := indirect(rawValue) 281 if !into.IsValid() { 282 // nil object 283 return nil, nil 284 } 285 values := make(map[string][]byte) 286 intoType := indirectType(into.Type()) 287 nums := intoType.NumField() 288 var err error 289 for i := 0; i < nums; i++ { 290 field := intoType.Field(i) 291 rawFieldType := field.Type 292 name := toBucketField(field.Name) 293 if field.Anonymous { 294 // 不处理匿名属性 295 log.Warnf("[BlobStore] anonymous field %s, type is %v", name, rawFieldType) 296 continue 297 } 298 fieldValue := into.FieldByName(field.Name) 299 if !fieldValue.CanAddr() { 300 log.Warnf("[BlobStore] addressable field %s, type is %v", name, rawFieldType) 301 continue 302 } 303 if !fieldValue.IsValid() { 304 log.Warnf("[BlobStore] invalid field %s, type is %v", name, rawFieldType) 305 continue 306 } 307 if !fieldValue.CanInterface() { 308 log.Warnf("[BlobStore] private field %s, type is %v", name, rawFieldType) 309 continue 310 } 311 kind := rawFieldType.Kind() 312 switch kind { 313 case reflect.String: 314 strValue := fieldValue.String() 315 values[name] = encodeStringBuffer(strValue) 316 case reflect.Bool: 317 boolValue := fieldValue.Bool() 318 values[name] = encodeBoolBuffer(boolValue) 319 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 320 intValue := fieldValue.Int() 321 values[name] = encodeIntBuffer(intValue, numberKindToType[kind]) 322 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 323 intValue := fieldValue.Uint() 324 values[name] = encodeUintBuffer(intValue, numberKindToType[kind]) 325 case reflect.Map: 326 mapKeys := fieldValue.MapKeys() 327 err := encodeMapBuffer(parent, name, mapKeys, &fieldValue) 328 if err != nil { 329 return nil, err 330 } 331 case reflect.Ptr: 332 if rawFieldType.Implements(messageType) { 333 // protobuf类型 334 elem := fieldValue.Addr().Elem() 335 if elem.IsNil() { 336 continue 337 } 338 msgValue := elem.Interface().(proto.Message) 339 values[name], err = encodeMessageBuffer(msgValue) 340 if err != nil { 341 return nil, err 342 } 343 } 344 case reflect.Struct: 345 if rawFieldType.AssignableTo(timeType) { 346 // 时间类型 347 timeValue := fieldValue.Addr().Elem().Interface().(time.Time) 348 values[name] = encodeTimeBuffer(timeValue) 349 } 350 default: 351 log.Warnf( 352 "[BlobStore] serialize unrecognized field %s, type is %v, kind is %s", name, rawFieldType, kind) 353 continue 354 } 355 } 356 return values, nil 357 } 358 359 func toBucketField(field string) string { 360 return strings.ToLower(field) 361 } 362 363 func deserializeObject(bucket *bolt.Bucket, value interface{}) (interface{}, error) { 364 fromObj := indirect(reflect.ValueOf(value)) 365 if !fromObj.IsValid() { 366 // nil object 367 return nil, nil 368 } 369 toValue := reflect.New(reflect.TypeOf(value).Elem()).Interface() 370 toObj := indirect(reflect.ValueOf(toValue)) 371 intoType := indirectType(toObj.Type()) 372 nums := intoType.NumField() 373 for i := 0; i < nums; i++ { 374 field := intoType.Field(i) 375 rawFieldType := field.Type 376 name := toBucketField(field.Name) 377 if field.Anonymous { 378 // 不处理匿名属性 379 log.Warnf("[BlobStore] anonymous field %s, type is %v", name, rawFieldType) 380 continue 381 } 382 fieldValue := toObj.FieldByName(field.Name) 383 if !fieldValue.CanAddr() { 384 log.Warnf("[BlobStore] addressable field %s, type is %v", name, rawFieldType) 385 continue 386 } 387 if !fieldValue.IsValid() { 388 log.Warnf("[BlobStore] invalid field %s, type is %v", name, rawFieldType) 389 continue 390 } 391 if !fieldValue.CanSet() { 392 log.Warnf("[BlobStore] private field %s, type is %v", name, rawFieldType) 393 continue 394 } 395 kind := rawFieldType.Kind() 396 switch kind { 397 case reflect.String: 398 buf := bucket.Get([]byte(name)) 399 value, err := decodeStringBuffer(name, buf) 400 if err != nil { 401 return nil, err 402 } 403 fieldValue.Set(reflect.ValueOf(value)) 404 case reflect.Bool: 405 buf := bucket.Get([]byte(name)) 406 value, err := decodeBoolBuffer(name, buf) 407 if err != nil { 408 return nil, err 409 } 410 fieldValue.Set(reflect.ValueOf(value)) 411 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 412 buf := bucket.Get([]byte(name)) 413 value, err := decodeIntBuffer(name, buf, numberKindToType[kind]) 414 if err != nil { 415 return nil, err 416 } 417 setIntValue(value, &fieldValue, kind) 418 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 419 buf := bucket.Get([]byte(name)) 420 value, err := decodeUintBuffer(name, buf, numberKindToType[kind]) 421 if err != nil { 422 return nil, err 423 } 424 setUintValue(value, &fieldValue, kind) 425 case reflect.Map: 426 subBucket := bucket.Bucket([]byte(name)) 427 values, err := decodeMapBuffer(subBucket) 428 if err != nil { 429 return nil, err 430 } 431 fieldValue.Set(reflect.ValueOf(values)) 432 case reflect.Ptr: 433 if rawFieldType.Implements(messageType) { 434 // protobuf类型 435 buf := bucket.Get([]byte(name)) 436 if nil == buf { 437 continue 438 } 439 toMsgValue := reflect.New(rawFieldType.Elem()).Interface().(proto.Message) 440 msg, err := decodeMessageBuffer(toMsgValue, name, buf) 441 if err != nil { 442 return nil, err 443 } 444 fieldValue.Set(reflect.ValueOf(msg)) 445 } 446 case reflect.Struct: 447 if rawFieldType.AssignableTo(timeType) { 448 // 时间类型 449 buf := bucket.Get([]byte(name)) 450 value, err := decodeTimeBuffer(name, buf) 451 if err != nil { 452 return nil, err 453 } 454 fieldValue.Set(reflect.ValueOf(value)) 455 } 456 default: 457 log.Warnf("[BlobStore] deserialize unrecognized field %s, type is %v", name, rawFieldType) 458 continue 459 } 460 } 461 return toValue, nil 462 } 463 464 func setIntValue(value int64, fieldValue *reflect.Value, kind reflect.Kind) { 465 switch kind { 466 case reflect.Int: 467 fieldValue.Set(reflect.ValueOf(int(value))) 468 case reflect.Int8: 469 fieldValue.Set(reflect.ValueOf(int8(value))) 470 case reflect.Int16: 471 fieldValue.Set(reflect.ValueOf(int16(value))) 472 case reflect.Int32: 473 fieldValue.Set(reflect.ValueOf(int32(value))) 474 case reflect.Int64: 475 fieldValue.Set(reflect.ValueOf(value)) 476 default: 477 // do nothing 478 } 479 } 480 481 func setUintValue(value uint64, fieldValue *reflect.Value, kind reflect.Kind) { 482 switch kind { 483 case reflect.Uint: 484 fieldValue.Set(reflect.ValueOf(uint(value))) 485 case reflect.Uint8: 486 fieldValue.Set(reflect.ValueOf(uint8(value))) 487 case reflect.Uint16: 488 fieldValue.Set(reflect.ValueOf(uint16(value))) 489 case reflect.Uint32: 490 fieldValue.Set(reflect.ValueOf(uint32(value))) 491 case reflect.Uint64: 492 fieldValue.Set(reflect.ValueOf(value)) 493 default: 494 // do nothing 495 } 496 } 497 498 func indirect(reflectValue reflect.Value) reflect.Value { 499 for reflectValue.Kind() == reflect.Ptr { 500 reflectValue = reflectValue.Elem() 501 } 502 return reflectValue 503 } 504 505 func indirectType(reflectType reflect.Type) reflect.Type { 506 for reflectType.Kind() == reflect.Ptr || reflectType.Kind() == reflect.Slice { 507 reflectType = reflectType.Elem() 508 } 509 return reflectType 510 }