From 533c7777b9492dfe23f46d92fd60a20c4bc3e2f8 Mon Sep 17 00:00:00 2001 From: goroutine Date: Tue, 17 Jul 2018 20:09:34 +0800 Subject: [PATCH] tablecodec: make decode much more faster (#7071) --- tablecodec/tablecodec.go | 29 +++++++++++++++++++++-------- tablecodec/tablecodec_test.go | 15 +++++++++++++++ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/tablecodec/tablecodec.go b/tablecodec/tablecodec.go index b53a3c47b10da..d1d26306d61b9 100644 --- a/tablecodec/tablecodec.go +++ b/tablecodec/tablecodec.go @@ -42,9 +42,11 @@ var ( ) const ( - idLen = 8 - prefixLen = 1 + idLen /*tableID*/ + 2 - recordRowKeyLen = prefixLen + idLen /*handle*/ + idLen = 8 + prefixLen = 1 + idLen /*tableID*/ + 2 + recordRowKeyLen = prefixLen + idLen /*handle*/ + tablePrefixLength = 1 + recordPrefixSepLength = 2 ) // TableSplitKeyLen is the length of key 't{table_id}' which is used for table split. @@ -84,25 +86,36 @@ func EncodeRecordKey(recordPrefix kv.Key, h int64) kv.Key { return buf } +func hasTablePrefix(key kv.Key) bool { + return key[0] == tablePrefix[0] +} + +func hasRecordPrefixSep(key kv.Key) bool { + return key[0] == recordPrefixSep[0] && key[1] == recordPrefixSep[1] +} + // DecodeRecordKey decodes the key and gets the tableID, handle. func DecodeRecordKey(key kv.Key) (tableID int64, handle int64, err error) { + if len(key) <= prefixLen { + return 0, 0, errInvalidRecordKey.Gen("invalid record key - %q", key) + } + k := key - if !key.HasPrefix(tablePrefix) { + if !hasTablePrefix(key) { return 0, 0, errInvalidRecordKey.Gen("invalid record key - %q", k) } - key = key[len(tablePrefix):] + key = key[tablePrefixLength:] key, tableID, err = codec.DecodeInt(key) if err != nil { return 0, 0, errors.Trace(err) } - if !key.HasPrefix(recordPrefixSep) { + if !hasRecordPrefixSep(key) { return 0, 0, errInvalidRecordKey.Gen("invalid record key - %q", k) } - key = key[len(recordPrefixSep):] - + key = key[recordPrefixSepLength:] key, handle, err = codec.DecodeInt(key) if err != nil { return 0, 0, errors.Trace(err) diff --git a/tablecodec/tablecodec_test.go b/tablecodec/tablecodec_test.go index 32ad85e59ab15..a16dd291349ee 100644 --- a/tablecodec/tablecodec_test.go +++ b/tablecodec/tablecodec_test.go @@ -20,6 +20,7 @@ import ( "time" . "github.com/pingcap/check" + "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/mysql" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" @@ -359,3 +360,17 @@ func (s *testTableCodecSuite) TestDecodeIndexKey(c *C) { c.Assert(decodeIndexID, Equals, indexID) c.Assert(decodeValues, DeepEquals, valueStrs) } + +func BenchmarkHasTablePrefix(b *testing.B) { + k := kv.Key("foobar") + for i := 0; i < b.N; i++ { + hasTablePrefix(k) + } +} + +func BenchmarkHasTablePrefixBuiltin(b *testing.B) { + k := kv.Key("foobar") + for i := 0; i < b.N; i++ { + k.HasPrefix(tablePrefix) + } +}