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  }