github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/internal/structure/type.go (about) 1 // Copyright 2022 zGraph Authors. All rights reserved. 2 // 3 // Copyright 2015 PingCAP, Inc. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package structure 18 19 import ( 20 "bytes" 21 22 "github.com/pingcap/errors" 23 "github.com/vescale/zgraph/codec" 24 "github.com/vescale/zgraph/storage/kv" 25 ) 26 27 // TypeFlag is for data structure meta/data flag. 28 type TypeFlag byte 29 30 const ( 31 // StringMeta is the flag for string meta. 32 StringMeta TypeFlag = 'S' 33 // StringData is the flag for string data. 34 StringData TypeFlag = 's' 35 // HashMeta is the flag for hash meta. 36 HashMeta TypeFlag = 'H' 37 // HashData is the flag for hash data. 38 HashData TypeFlag = 'h' 39 // ListMeta is the flag for list meta. 40 ListMeta TypeFlag = 'L' 41 // ListData is the flag for list data. 42 ListData TypeFlag = 'l' 43 ) 44 45 // Make linter happy, since encodeHashMetaKey is unused in this repo. 46 var _ = (&TxStructure{}).encodeHashMetaKey 47 48 func (t *TxStructure) encodeStringDataKey(key []byte) kv.Key { 49 // for codec Encode, we may add extra bytes data, so here and following encode 50 // we will use extra length like 4 for a little optimization. 51 ek := make([]byte, 0, len(t.prefix)+len(key)+24) 52 ek = append(ek, t.prefix...) 53 ek = codec.EncodeBytes(ek, key) 54 return codec.EncodeUint(ek, uint64(StringData)) 55 } 56 57 // nolint:unused 58 func (t *TxStructure) encodeHashMetaKey(key []byte) kv.Key { 59 ek := make([]byte, 0, len(t.prefix)+codec.EncodedBytesLength(len(key))+8) 60 ek = append(ek, t.prefix...) 61 ek = codec.EncodeBytes(ek, key) 62 return codec.EncodeUint(ek, uint64(HashMeta)) 63 } 64 65 func (t *TxStructure) encodeHashDataKey(key []byte, field []byte) kv.Key { 66 ek := make([]byte, 0, len(t.prefix)+codec.EncodedBytesLength(len(key))+8+codec.EncodedBytesLength(len(field))) 67 ek = append(ek, t.prefix...) 68 ek = codec.EncodeBytes(ek, key) 69 ek = codec.EncodeUint(ek, uint64(HashData)) 70 return codec.EncodeBytes(ek, field) 71 } 72 73 // EncodeHashDataKey exports for tests. 74 func (t *TxStructure) EncodeHashDataKey(key []byte, field []byte) kv.Key { 75 return t.encodeHashDataKey(key, field) 76 } 77 78 func (t *TxStructure) decodeHashDataKey(ek kv.Key) ([]byte, []byte, error) { 79 var ( 80 key []byte 81 field []byte 82 err error 83 tp uint64 84 ) 85 86 if !bytes.HasPrefix(ek, t.prefix) { 87 return nil, nil, errors.New("invalid encoded hash data key prefix") 88 } 89 90 ek = ek[len(t.prefix):] 91 92 ek, key, err = codec.DecodeBytes(ek, nil) 93 if err != nil { 94 return nil, nil, errors.Trace(err) 95 } 96 97 ek, tp, err = codec.DecodeUint(ek) 98 if err != nil { 99 return nil, nil, errors.Trace(err) 100 } else if TypeFlag(tp) != HashData { 101 return nil, nil, errors.Annotatef(ErrInvalidHashKeyFlag, "invalid encoded hash data key flag %c", byte(tp)) 102 } 103 104 _, field, err = codec.DecodeBytes(ek, nil) 105 return key, field, errors.Trace(err) 106 } 107 108 func (t *TxStructure) hashDataKeyPrefix(key []byte) kv.Key { 109 ek := make([]byte, 0, len(t.prefix)+len(key)+24) 110 ek = append(ek, t.prefix...) 111 ek = codec.EncodeBytes(ek, key) 112 return codec.EncodeUint(ek, uint64(HashData)) 113 } 114 115 func (t *TxStructure) encodeListMetaKey(key []byte) kv.Key { 116 ek := make([]byte, 0, len(t.prefix)+len(key)+24) 117 ek = append(ek, t.prefix...) 118 ek = codec.EncodeBytes(ek, key) 119 return codec.EncodeUint(ek, uint64(ListMeta)) 120 } 121 122 func (t *TxStructure) encodeListDataKey(key []byte, index int64) kv.Key { 123 ek := make([]byte, 0, len(t.prefix)+len(key)+36) 124 ek = append(ek, t.prefix...) 125 ek = codec.EncodeBytes(ek, key) 126 ek = codec.EncodeUint(ek, uint64(ListData)) 127 return codec.EncodeInt(ek, index) 128 }