github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/ekv/key_test.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 "errors" 19 "testing" 20 "time" 21 22 . "github.com/whtcorpsinc/check" 23 "github.com/whtcorpsinc/milevadb/soliton/codec" 24 "github.com/whtcorpsinc/milevadb/soliton/testleak" 25 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 26 "github.com/whtcorpsinc/milevadb/types" 27 ) 28 29 var _ = Suite(&testKeySuite{}) 30 31 type testKeySuite struct { 32 } 33 34 func (s *testKeySuite) TestPartialNext(c *C) { 35 defer testleak.AfterTest(c)() 36 sc := &stmtctx.StatementContext{TimeZone: time.Local} 37 // keyA represents a multi column index. 38 keyA, err := codec.EncodeValue(sc, nil, types.NewCauset("abc"), types.NewCauset("def")) 39 c.Check(err, IsNil) 40 keyB, err := codec.EncodeValue(sc, nil, types.NewCauset("abca"), types.NewCauset("def")) 41 c.Check(err, IsNil) 42 43 // We only use first column value to seek. 44 seekKey, err := codec.EncodeValue(sc, nil, types.NewCauset("abc")) 45 c.Check(err, IsNil) 46 47 nextKey := Key(seekKey).Next() 48 cmp := bytes.Compare(nextKey, keyA) 49 c.Assert(cmp, Equals, -1) 50 51 // Use next partial key, we can skip all index keys with first column value equal to "abc". 52 nextPartialKey := Key(seekKey).PrefixNext() 53 cmp = bytes.Compare(nextPartialKey, keyA) 54 c.Assert(cmp, Equals, 1) 55 56 cmp = bytes.Compare(nextPartialKey, keyB) 57 c.Assert(cmp, Equals, -1) 58 } 59 60 func (s *testKeySuite) TestIsPoint(c *C) { 61 tests := []struct { 62 start []byte 63 end []byte 64 isPoint bool 65 }{ 66 { 67 start: Key("rowkey1"), 68 end: Key("rowkey2"), 69 isPoint: true, 70 }, 71 { 72 start: Key("rowkey1"), 73 end: Key("rowkey3"), 74 isPoint: false, 75 }, 76 { 77 start: Key(""), 78 end: []byte{0}, 79 isPoint: true, 80 }, 81 { 82 start: []byte{123, 123, 255, 255}, 83 end: []byte{123, 124, 0, 0}, 84 isPoint: true, 85 }, 86 { 87 start: []byte{123, 123, 255, 255}, 88 end: []byte{123, 124, 0, 1}, 89 isPoint: false, 90 }, 91 { 92 start: []byte{123, 123}, 93 end: []byte{123, 123, 0}, 94 isPoint: true, 95 }, 96 { 97 start: []byte{255}, 98 end: []byte{0}, 99 isPoint: false, 100 }, 101 } 102 for _, tt := range tests { 103 kr := KeyRange{ 104 StartKey: tt.start, 105 EndKey: tt.end, 106 } 107 c.Check(kr.IsPoint(), Equals, tt.isPoint) 108 } 109 } 110 111 func (s *testKeySuite) TestBasicFunc(c *C) { 112 c.Assert(IsTxnRetryableError(nil), IsFalse) 113 c.Assert(IsTxnRetryableError(ErrTxnRetryable), IsTrue) 114 c.Assert(IsTxnRetryableError(errors.New("test")), IsFalse) 115 } 116 117 func (s *testKeySuite) TestHandle(c *C) { 118 ih := IntHandle(100) 119 c.Assert(ih.IsInt(), IsTrue) 120 _, iv, _ := codec.DecodeInt(ih.Encoded()) 121 c.Assert(iv, Equals, ih.IntValue()) 122 ih2 := ih.Next() 123 c.Assert(ih2.IntValue(), Equals, int64(101)) 124 c.Assert(ih.Equal(ih2), IsFalse) 125 c.Assert(ih.Compare(ih2), Equals, -1) 126 c.Assert(ih.String(), Equals, "100") 127 ch := mustNewCommonHandle(c, 100, "abc") 128 c.Assert(ch.IsInt(), IsFalse) 129 ch2 := ch.Next() 130 c.Assert(ch.Equal(ch2), IsFalse) 131 c.Assert(ch.Compare(ch2), Equals, -1) 132 c.Assert(ch2.Encoded(), HasLen, len(ch.Encoded())) 133 c.Assert(ch.NumDefCauss(), Equals, 2) 134 _, d, err := codec.DecodeOne(ch.EncodedDefCaus(0)) 135 c.Assert(err, IsNil) 136 c.Assert(d.GetInt64(), Equals, int64(100)) 137 _, d, err = codec.DecodeOne(ch.EncodedDefCaus(1)) 138 c.Assert(err, IsNil) 139 c.Assert(d.GetString(), Equals, "abc") 140 c.Assert(ch.String(), Equals, "{100, abc}") 141 } 142 143 func (s *testKeySuite) TestPaddingHandle(c *C) { 144 dec := types.NewDecFromInt(1) 145 encoded, err := codec.EncodeKey(new(stmtctx.StatementContext), nil, types.NewDecimalCauset(dec)) 146 c.Assert(err, IsNil) 147 c.Assert(len(encoded), Less, 9) 148 handle, err := NewCommonHandle(encoded) 149 c.Assert(err, IsNil) 150 c.Assert(handle.Encoded(), HasLen, 9) 151 c.Assert(handle.EncodedDefCaus(0), BytesEquals, encoded) 152 newHandle, err := NewCommonHandle(handle.Encoded()) 153 c.Assert(err, IsNil) 154 c.Assert(newHandle.EncodedDefCaus(0), BytesEquals, handle.EncodedDefCaus(0)) 155 } 156 157 func (s *testKeySuite) TestHandleMap(c *C) { 158 m := NewHandleMap() 159 h := IntHandle(1) 160 m.Set(h, 1) 161 v, ok := m.Get(h) 162 c.Assert(ok, IsTrue) 163 c.Assert(v, Equals, 1) 164 m.Delete(h) 165 v, ok = m.Get(h) 166 c.Assert(ok, IsFalse) 167 c.Assert(v, IsNil) 168 ch := mustNewCommonHandle(c, 100, "abc") 169 m.Set(ch, "a") 170 v, ok = m.Get(ch) 171 c.Assert(ok, IsTrue) 172 c.Assert(v, Equals, "a") 173 m.Delete(ch) 174 v, ok = m.Get(ch) 175 c.Assert(ok, IsFalse) 176 c.Assert(v, IsNil) 177 m.Set(ch, "a") 178 ch2 := mustNewCommonHandle(c, 101, "abc") 179 m.Set(ch2, "b") 180 ch3 := mustNewCommonHandle(c, 99, "def") 181 m.Set(ch3, "c") 182 c.Assert(m.Len(), Equals, 3) 183 cnt := 0 184 m.Range(func(h Handle, val interface{}) bool { 185 cnt++ 186 if h.Equal(ch) { 187 c.Assert(val, Equals, "a") 188 } else if h.Equal(ch2) { 189 c.Assert(val, Equals, "b") 190 } else { 191 c.Assert(val, Equals, "c") 192 } 193 if cnt == 2 { 194 return false 195 } 196 return true 197 }) 198 c.Assert(cnt, Equals, 2) 199 } 200 201 func mustNewCommonHandle(c *C, values ...interface{}) *CommonHandle { 202 encoded, err := codec.EncodeKey(new(stmtctx.StatementContext), nil, types.MakeCausets(values...)...) 203 c.Assert(err, IsNil) 204 ch, err := NewCommonHandle(encoded) 205 c.Assert(err, IsNil) 206 return ch 207 } 208 209 func BenchmarkIsPoint(b *testing.B) { 210 b.ReportAllocs() 211 kr := KeyRange{ 212 StartKey: []byte("rowkey1"), 213 EndKey: []byte("rowkey2"), 214 } 215 for i := 0; i < b.N; i++ { 216 kr.IsPoint() 217 } 218 }