github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/ekv/key.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 ekv
    15  
    16  import (
    17  	"bytes"
    18  	"encoding/hex"
    19  	"fmt"
    20  	"strconv"
    21  	"strings"
    22  
    23  	"github.com/whtcorpsinc/milevadb/soliton/codec"
    24  	"github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx"
    25  	"github.com/whtcorpsinc/milevadb/types"
    26  )
    27  
    28  // Key represents high-level Key type.
    29  type Key []byte
    30  
    31  // Next returns the next key in byte-order.
    32  func (k Key) Next() Key {
    33  	// add 0x0 to the end of key
    34  	buf := make([]byte, len(k)+1)
    35  	copy(buf, k)
    36  	return buf
    37  }
    38  
    39  // PrefixNext returns the next prefix key.
    40  //
    41  // Assume there are keys like:
    42  //
    43  //   rowkey1
    44  //   rowkey1_column1
    45  //   rowkey1_column2
    46  //   rowKey2
    47  //
    48  // If we seek 'rowkey1' Next, we will get 'rowkey1_column1'.
    49  // If we seek 'rowkey1' PrefixNext, we will get 'rowkey2'.
    50  func (k Key) PrefixNext() Key {
    51  	buf := make([]byte, len(k))
    52  	copy(buf, k)
    53  	var i int
    54  	for i = len(k) - 1; i >= 0; i-- {
    55  		buf[i]++
    56  		if buf[i] != 0 {
    57  			break
    58  		}
    59  	}
    60  	if i == -1 {
    61  		copy(buf, k)
    62  		buf = append(buf, 0)
    63  	}
    64  	return buf
    65  }
    66  
    67  // Cmp returns the comparison result of two key.
    68  // The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
    69  func (k Key) Cmp(another Key) int {
    70  	return bytes.Compare(k, another)
    71  }
    72  
    73  // HasPrefix tests whether the Key begins with prefix.
    74  func (k Key) HasPrefix(prefix Key) bool {
    75  	return bytes.HasPrefix(k, prefix)
    76  }
    77  
    78  // Clone returns a deep copy of the Key.
    79  func (k Key) Clone() Key {
    80  	ck := make([]byte, len(k))
    81  	copy(ck, k)
    82  	return ck
    83  }
    84  
    85  // String implements fmt.Stringer interface.
    86  func (k Key) String() string {
    87  	return hex.EncodeToString(k)
    88  }
    89  
    90  // KeyRange represents a range where StartKey <= key < EndKey.
    91  type KeyRange struct {
    92  	StartKey Key
    93  	EndKey   Key
    94  }
    95  
    96  // IsPoint checks if the key range represents a point.
    97  func (r *KeyRange) IsPoint() bool {
    98  	if len(r.StartKey) != len(r.EndKey) {
    99  		// Works like
   100  		//   return bytes.Equal(r.StartKey.Next(), r.EndKey)
   101  
   102  		startLen := len(r.StartKey)
   103  		return startLen+1 == len(r.EndKey) &&
   104  			r.EndKey[startLen] == 0 &&
   105  			bytes.Equal(r.StartKey, r.EndKey[:startLen])
   106  	}
   107  	// Works like
   108  	//   return bytes.Equal(r.StartKey.PrefixNext(), r.EndKey)
   109  
   110  	i := len(r.StartKey) - 1
   111  	for ; i >= 0; i-- {
   112  		if r.StartKey[i] != 255 {
   113  			break
   114  		}
   115  		if r.EndKey[i] != 0 {
   116  			return false
   117  		}
   118  	}
   119  	if i < 0 {
   120  		// In case all bytes in StartKey are 255.
   121  		return false
   122  	}
   123  	// The byte at diffIdx in StartKey should be one less than the byte at diffIdx in EndKey.
   124  	// And bytes in StartKey and EndKey before diffIdx should be equal.
   125  	diffOneIdx := i
   126  	return r.StartKey[diffOneIdx]+1 == r.EndKey[diffOneIdx] &&
   127  		bytes.Equal(r.StartKey[:diffOneIdx], r.EndKey[:diffOneIdx])
   128  }
   129  
   130  // Handle is the ID of a event.
   131  type Handle interface {
   132  	// IsInt returns if the handle type is int64.
   133  	IsInt() bool
   134  	// IntValue returns the int64 value if IsInt is true, it panics if IsInt returns false.
   135  	IntValue() int64
   136  	// Next returns the minimum handle that is greater than this handle.
   137  	Next() Handle
   138  	// Equal returns if the handle equals to another handle, it panics if the types are different.
   139  	Equal(h Handle) bool
   140  	// Compare returns the comparison result of the two handles, it panics if the types are different.
   141  	Compare(h Handle) int
   142  	// Encoded returns the encoded bytes.
   143  	Encoded() []byte
   144  	// Len returns the length of the encoded bytes.
   145  	Len() int
   146  	// NumDefCauss returns the number of columns of the handle,
   147  	NumDefCauss() int
   148  	// EncodedDefCaus returns the encoded column value at the given column index.
   149  	EncodedDefCaus(idx int) []byte
   150  	// Data returns the data of all columns of a handle.
   151  	Data() ([]types.Causet, error)
   152  	// String implements the fmt.Stringer interface.
   153  	String() string
   154  }
   155  
   156  // IntHandle implement the Handle interface for int64 type handle.
   157  type IntHandle int64
   158  
   159  // IsInt implements the Handle interface.
   160  func (ih IntHandle) IsInt() bool {
   161  	return true
   162  }
   163  
   164  // IntValue implements the Handle interface.
   165  func (ih IntHandle) IntValue() int64 {
   166  	return int64(ih)
   167  }
   168  
   169  // Next implements the Handle interface.
   170  func (ih IntHandle) Next() Handle {
   171  	return IntHandle(int64(ih) + 1)
   172  }
   173  
   174  // Equal implements the Handle interface.
   175  func (ih IntHandle) Equal(h Handle) bool {
   176  	return h.IsInt() && int64(ih) == h.IntValue()
   177  }
   178  
   179  // Compare implements the Handle interface.
   180  func (ih IntHandle) Compare(h Handle) int {
   181  	if !h.IsInt() {
   182  		panic("IntHandle compares to CommonHandle")
   183  	}
   184  	ihVal := ih.IntValue()
   185  	hVal := h.IntValue()
   186  	if ihVal > hVal {
   187  		return 1
   188  	}
   189  	if ihVal < hVal {
   190  		return -1
   191  	}
   192  	return 0
   193  }
   194  
   195  // Encoded implements the Handle interface.
   196  func (ih IntHandle) Encoded() []byte {
   197  	return codec.EncodeInt(nil, int64(ih))
   198  }
   199  
   200  // Len implements the Handle interface.
   201  func (ih IntHandle) Len() int {
   202  	return 8
   203  }
   204  
   205  // NumDefCauss implements the Handle interface, not supported for IntHandle type.
   206  func (ih IntHandle) NumDefCauss() int {
   207  	panic("not supported in IntHandle")
   208  }
   209  
   210  // EncodedDefCaus implements the Handle interface., not supported for IntHandle type.
   211  func (ih IntHandle) EncodedDefCaus(idx int) []byte {
   212  	panic("not supported in IntHandle")
   213  }
   214  
   215  // Data implements the Handle interface.
   216  func (ih IntHandle) Data() ([]types.Causet, error) {
   217  	return []types.Causet{types.NewIntCauset(int64(ih))}, nil
   218  }
   219  
   220  // String implements the Handle interface.
   221  func (ih IntHandle) String() string {
   222  	return strconv.FormatInt(int64(ih), 10)
   223  }
   224  
   225  // CommonHandle implements the Handle interface for non-int64 type handle.
   226  type CommonHandle struct {
   227  	encoded       []byte
   228  	colEndOffsets []uint16
   229  }
   230  
   231  // NewCommonHandle creates a CommonHandle from a encoded bytes which is encoded by code.EncodeKey.
   232  func NewCommonHandle(encoded []byte) (*CommonHandle, error) {
   233  	ch := &CommonHandle{encoded: encoded}
   234  	if len(encoded) < 9 {
   235  		padded := make([]byte, 9)
   236  		copy(padded, encoded)
   237  		ch.encoded = padded
   238  	}
   239  	remain := encoded
   240  	endOff := uint16(0)
   241  	for len(remain) > 0 {
   242  		if remain[0] == 0 {
   243  			// padded data
   244  			break
   245  		}
   246  		var err error
   247  		var col []byte
   248  		col, remain, err = codec.CutOne(remain)
   249  		if err != nil {
   250  			return nil, err
   251  		}
   252  		endOff += uint16(len(col))
   253  		ch.colEndOffsets = append(ch.colEndOffsets, endOff)
   254  	}
   255  	return ch, nil
   256  }
   257  
   258  // IsInt implements the Handle interface.
   259  func (ch *CommonHandle) IsInt() bool {
   260  	return false
   261  }
   262  
   263  // IntValue implements the Handle interface, not supported for CommonHandle type.
   264  func (ch *CommonHandle) IntValue() int64 {
   265  	panic("not supported in CommonHandle")
   266  }
   267  
   268  // Next implements the Handle interface.
   269  func (ch *CommonHandle) Next() Handle {
   270  	return &CommonHandle{
   271  		encoded:       Key(ch.encoded).PrefixNext(),
   272  		colEndOffsets: ch.colEndOffsets,
   273  	}
   274  }
   275  
   276  // Equal implements the Handle interface.
   277  func (ch *CommonHandle) Equal(h Handle) bool {
   278  	return !h.IsInt() && bytes.Equal(ch.encoded, h.Encoded())
   279  }
   280  
   281  // Compare implements the Handle interface.
   282  func (ch *CommonHandle) Compare(h Handle) int {
   283  	if h.IsInt() {
   284  		panic("CommonHandle compares to IntHandle")
   285  	}
   286  	return bytes.Compare(ch.encoded, h.Encoded())
   287  }
   288  
   289  // Encoded implements the Handle interface.
   290  func (ch *CommonHandle) Encoded() []byte {
   291  	return ch.encoded
   292  }
   293  
   294  // Len implements the Handle interface.
   295  func (ch *CommonHandle) Len() int {
   296  	return len(ch.encoded)
   297  }
   298  
   299  // NumDefCauss implements the Handle interface.
   300  func (ch *CommonHandle) NumDefCauss() int {
   301  	return len(ch.colEndOffsets)
   302  }
   303  
   304  // EncodedDefCaus implements the Handle interface.
   305  func (ch *CommonHandle) EncodedDefCaus(idx int) []byte {
   306  	colStartOffset := uint16(0)
   307  	if idx > 0 {
   308  		colStartOffset = ch.colEndOffsets[idx-1]
   309  	}
   310  	return ch.encoded[colStartOffset:ch.colEndOffsets[idx]]
   311  }
   312  
   313  // Data implements the Handle interface.
   314  func (ch *CommonHandle) Data() ([]types.Causet, error) {
   315  	data := make([]types.Causet, 0, ch.NumDefCauss())
   316  	for i := 0; i < ch.NumDefCauss(); i++ {
   317  		encodedDefCaus := ch.EncodedDefCaus(i)
   318  		_, d, err := codec.DecodeOne(encodedDefCaus)
   319  		if err != nil {
   320  			return nil, err
   321  		}
   322  		data = append(data, d)
   323  	}
   324  	return data, nil
   325  }
   326  
   327  // String implements the Handle interface.
   328  func (ch *CommonHandle) String() string {
   329  	data, err := ch.Data()
   330  	if err != nil {
   331  		return err.Error()
   332  	}
   333  	strs := make([]string, 0, ch.NumDefCauss())
   334  	for _, causet := range data {
   335  		str, err := causet.ToString()
   336  		if err != nil {
   337  			return err.Error()
   338  		}
   339  		strs = append(strs, str)
   340  	}
   341  	return fmt.Sprintf("{%s}", strings.Join(strs, ", "))
   342  }
   343  
   344  // HandleMap is the map for Handle.
   345  type HandleMap struct {
   346  	ints map[int64]interface{}
   347  	strs map[string]strHandleVal
   348  }
   349  
   350  type strHandleVal struct {
   351  	h   Handle
   352  	val interface{}
   353  }
   354  
   355  // NewHandleMap creates a new map for handle.
   356  func NewHandleMap() *HandleMap {
   357  	// Initialize the two maps to avoid checking nil.
   358  	return &HandleMap{
   359  		ints: map[int64]interface{}{},
   360  		strs: map[string]strHandleVal{},
   361  	}
   362  }
   363  
   364  // Get gets a value by a Handle.
   365  func (m *HandleMap) Get(h Handle) (v interface{}, ok bool) {
   366  	if h.IsInt() {
   367  		v, ok = m.ints[h.IntValue()]
   368  	} else {
   369  		var strVal strHandleVal
   370  		strVal, ok = m.strs[string(h.Encoded())]
   371  		v = strVal.val
   372  	}
   373  	return
   374  }
   375  
   376  // Set sets a value with a Handle.
   377  func (m *HandleMap) Set(h Handle, val interface{}) {
   378  	if h.IsInt() {
   379  		m.ints[h.IntValue()] = val
   380  	} else {
   381  		m.strs[string(h.Encoded())] = strHandleVal{
   382  			h:   h,
   383  			val: val,
   384  		}
   385  	}
   386  }
   387  
   388  // Delete deletes a entry from the map.
   389  func (m *HandleMap) Delete(h Handle) {
   390  	if h.IsInt() {
   391  		delete(m.ints, h.IntValue())
   392  	} else {
   393  		delete(m.strs, string(h.Encoded()))
   394  	}
   395  }
   396  
   397  // Len returns the length of the map.
   398  func (m *HandleMap) Len() int {
   399  	return len(m.ints) + len(m.strs)
   400  }
   401  
   402  // Range iterates the HandleMap with fn, the fn returns true to continue, returns false to stop.
   403  func (m *HandleMap) Range(fn func(h Handle, val interface{}) bool) {
   404  	for h, val := range m.ints {
   405  		if !fn(IntHandle(h), val) {
   406  			return
   407  		}
   408  	}
   409  	for _, strVal := range m.strs {
   410  		if !fn(strVal.h, strVal.val) {
   411  			return
   412  		}
   413  	}
   414  }
   415  
   416  // BuildHandleFromCausetRow builds ekv.Handle from defcaus in event.
   417  func BuildHandleFromCausetRow(sctx *stmtctx.StatementContext, event []types.Causet, handleOrdinals []int) (Handle, error) {
   418  	pkDts := make([]types.Causet, 0, len(handleOrdinals))
   419  	for _, ordinal := range handleOrdinals {
   420  		pkDts = append(pkDts, event[ordinal])
   421  	}
   422  	handleBytes, err := codec.EncodeKey(sctx, nil, pkDts...)
   423  	if err != nil {
   424  		return nil, err
   425  	}
   426  	handle, err := NewCommonHandle(handleBytes)
   427  	if err != nil {
   428  		return nil, err
   429  	}
   430  	return handle, nil
   431  }