From 73118d3d7daaacaae3a48d6954e2ca78dafc2077 Mon Sep 17 00:00:00 2001 From: MyonKeminta Date: Fri, 9 Nov 2018 13:33:04 +0800 Subject: [PATCH 1/3] Update kvproto Signed-off-by: MyonKeminta --- Gopkg.lock | 7 +- Gopkg.toml | 2 +- .../pingcap/kvproto/pkg/kvrpcpb/kvrpcpb.pb.go | 307 ++++++++++-------- 3 files changed, 184 insertions(+), 132 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 0b1a9469d6c3e..d5adffb288c28 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -273,8 +273,8 @@ revision = "8d44bfdf1030639ae7130922c95df12d6d4da3b6" [[projects]] - branch = "master" - digest = "1:84db0209caf3c48beaec43d15bd22ca6256d958b807c2ac626e2425e232e92c4" + branch = "release-2.1" + digest = "1:85aa2923e4dac3cef4dda68972f580cbc10dc1450f019f98a8b7e476f5eb2b07" name = "github.com/pingcap/kvproto" packages = [ "pkg/coprocessor", @@ -287,7 +287,7 @@ "pkg/tikvpb", ] pruneopts = "NUT" - revision = "529c652955d8fa74faf56f91b2f428d5779fd7d5" + revision = "8e3f33ac49297d7c93b61a955531191084a2f685" [[projects]] branch = "master" @@ -561,6 +561,7 @@ "github.com/pingcap/kvproto/pkg/metapb", "github.com/pingcap/kvproto/pkg/tikvpb", "github.com/pingcap/pd/client", + "github.com/pingcap/tidb-tools/tidb-binlog/node", "github.com/pingcap/tidb-tools/tidb-binlog/pump_client", "github.com/pingcap/tipb/go-binlog", "github.com/pingcap/tipb/go-tipb", diff --git a/Gopkg.toml b/Gopkg.toml index 3d9ff447b90dc..4ffa13e39d08d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -74,7 +74,7 @@ required = ["github.com/golang/protobuf/jsonpb"] [[constraint]] name = "github.com/pingcap/kvproto" - branch = "master" + branch = "release-2.1" [[constraint]] name = "gopkg.in/natefinch/lumberjack.v2" diff --git a/vendor/github.com/pingcap/kvproto/pkg/kvrpcpb/kvrpcpb.pb.go b/vendor/github.com/pingcap/kvproto/pkg/kvrpcpb/kvrpcpb.pb.go index 5b221822b95f9..a1d180d3638bd 100644 --- a/vendor/github.com/pingcap/kvproto/pkg/kvrpcpb/kvrpcpb.pb.go +++ b/vendor/github.com/pingcap/kvproto/pkg/kvrpcpb/kvrpcpb.pb.go @@ -556,6 +556,9 @@ type ScanRequest struct { Version uint64 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"` KeyOnly bool `protobuf:"varint,5,opt,name=key_only,json=keyOnly,proto3" json:"key_only,omitempty"` Reverse bool `protobuf:"varint,6,opt,name=reverse,proto3" json:"reverse,omitempty"` + // For compatibility, when scanning forward, the range to scan is [start_key, end_key); and when scanning + // backward, the range is [end_key, start_key). + EndKey []byte `protobuf:"bytes,7,opt,name=end_key,json=endKey,proto3" json:"end_key,omitempty"` } func (m *ScanRequest) Reset() { *m = ScanRequest{} } @@ -605,6 +608,13 @@ func (m *ScanRequest) GetReverse() bool { return false } +func (m *ScanRequest) GetEndKey() []byte { + if m != nil { + return m.EndKey + } + return nil +} + type KvPair struct { Error *KeyError `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` @@ -2868,6 +2878,12 @@ func (m *ScanRequest) MarshalTo(dAtA []byte) (int, error) { } i++ } + if len(m.EndKey) > 0 { + dAtA[i] = 0x3a + i++ + i = encodeVarintKvrpcpb(dAtA, i, uint64(len(m.EndKey))) + i += copy(dAtA[i:], m.EndKey) + } return i, nil } @@ -5338,6 +5354,10 @@ func (m *ScanRequest) Size() (n int) { if m.Reverse { n += 2 } + l = len(m.EndKey) + if l > 0 { + n += 1 + l + sovKvrpcpb(uint64(l)) + } return n } @@ -7947,6 +7967,37 @@ func (m *ScanRequest) Unmarshal(dAtA []byte) error { } } m.Reverse = bool(v != 0) + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EndKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKvrpcpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKvrpcpb + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EndKey = append(m.EndKey[:0], dAtA[iNdEx:postIndex]...) + if m.EndKey == nil { + m.EndKey = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipKvrpcpb(dAtA[iNdEx:]) @@ -15321,133 +15372,133 @@ var ( func init() { proto.RegisterFile("kvrpcpb.proto", fileDescriptorKvrpcpb) } var fileDescriptorKvrpcpb = []byte{ - // 2036 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x5a, 0xef, 0x6e, 0x1b, 0xc7, + // 2047 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x5a, 0x5f, 0x6f, 0x1b, 0xc7, 0x11, 0xf7, 0x1d, 0x8f, 0xe4, 0x71, 0x48, 0x51, 0xcc, 0x4a, 0xb6, 0x19, 0xbb, 0xb1, 0x95, 0x6b, - 0x0c, 0xcb, 0x2a, 0x2a, 0xa3, 0x4a, 0xd0, 0x4f, 0x45, 0x11, 0x58, 0x76, 0x1d, 0xc5, 0x72, 0x2d, - 0xac, 0x54, 0x17, 0x06, 0x9a, 0x32, 0xab, 0xe3, 0x8a, 0x3c, 0xf0, 0x78, 0x7b, 0xbe, 0x5b, 0x52, - 0x22, 0x8a, 0xa0, 0x28, 0x8a, 0x14, 0xc8, 0xc7, 0x16, 0x05, 0x5a, 0x14, 0xcd, 0x03, 0xf4, 0x05, - 0xfa, 0xa5, 0x2f, 0xd0, 0x8f, 0x7d, 0x84, 0xc2, 0x7d, 0x91, 0x62, 0xff, 0xdc, 0x1d, 0x8f, 0xa4, - 0x62, 0xf5, 0x4a, 0x29, 0x9f, 0x78, 0x3b, 0x33, 0xbb, 0x33, 0xbf, 0x99, 0xd9, 0xd9, 0x7f, 0x84, - 0x95, 0xc1, 0x38, 0x0a, 0xdd, 0xf0, 0x78, 0x3b, 0x8c, 0x18, 0x67, 0xa8, 0xaa, 0x9b, 0xb7, 0x1a, - 0x43, 0xca, 0x49, 0x42, 0xbe, 0xb5, 0x42, 0xa3, 0x88, 0x45, 0x69, 0x73, 0xbd, 0xc7, 0x7a, 0x4c, - 0x7e, 0x3e, 0x14, 0x5f, 0x8a, 0xea, 0x7c, 0x01, 0xf6, 0x3e, 0x73, 0x07, 0x7b, 0xc1, 0x09, 0x43, - 0xef, 0x43, 0x23, 0x8c, 0xbc, 0x21, 0x89, 0x26, 0x1d, 0x9f, 0xb9, 0x83, 0xb6, 0xb1, 0x61, 0x6c, - 0x36, 0x70, 0x5d, 0xd3, 0x84, 0x98, 0x10, 0x11, 0xac, 0xce, 0x98, 0x46, 0xb1, 0xc7, 0x82, 0xb6, - 0xb9, 0x61, 0x6c, 0x5a, 0xb8, 0x2e, 0x68, 0x2f, 0x15, 0x09, 0xb5, 0xa0, 0x34, 0xa0, 0x93, 0x76, - 0x49, 0x76, 0x16, 0x9f, 0xe8, 0x5d, 0xb0, 0x65, 0x27, 0xce, 0xfd, 0xb6, 0x25, 0x3b, 0x54, 0x45, - 0xfb, 0x88, 0xfb, 0xce, 0xd7, 0x06, 0xd8, 0xcf, 0xe8, 0xe4, 0x89, 0xb0, 0x14, 0x3d, 0x80, 0x8a, - 0xa0, 0xd3, 0xae, 0xd4, 0x5c, 0xdf, 0x79, 0x67, 0x3b, 0xc1, 0x99, 0x98, 0x88, 0xb5, 0x00, 0xfa, - 0x0e, 0xd4, 0x22, 0xca, 0xa3, 0x09, 0x39, 0xf6, 0xa9, 0x34, 0xa2, 0x86, 0x33, 0x02, 0x5a, 0x87, - 0x32, 0x39, 0x66, 0x11, 0x97, 0x46, 0xd4, 0xb0, 0x6a, 0xa0, 0x1d, 0xb0, 0x5d, 0x16, 0x9c, 0xf8, - 0x9e, 0xcb, 0xa5, 0x19, 0xf5, 0x9d, 0x1b, 0xa9, 0x82, 0x9f, 0x47, 0x1e, 0xa7, 0xbb, 0x9a, 0x8b, - 0x53, 0x39, 0xe7, 0x14, 0x56, 0x72, 0x2c, 0x81, 0x25, 0xe6, 0x24, 0xe2, 0x1d, 0x1e, 0x4b, 0x2b, - 0x2d, 0x5c, 0x95, 0xed, 0xa3, 0x18, 0xdd, 0x85, 0x7a, 0xd2, 0x4f, 0x70, 0x95, 0x6b, 0x20, 0x21, - 0x1d, 0xc5, 0x0b, 0x3c, 0xd3, 0x86, 0xaa, 0xf6, 0xae, 0xb4, 0xa8, 0x81, 0x93, 0xa6, 0xf3, 0x75, - 0x09, 0xaa, 0xbb, 0x2c, 0xe0, 0xf4, 0x8c, 0xa3, 0xdb, 0x02, 0x6c, 0xcf, 0x63, 0x41, 0xc7, 0xeb, - 0x6a, 0xa5, 0xb6, 0x22, 0xec, 0x75, 0xd1, 0x0f, 0xa1, 0xa1, 0x99, 0x34, 0x64, 0x6e, 0x5f, 0xaa, - 0xad, 0xef, 0xac, 0x6d, 0xeb, 0x54, 0xc0, 0x92, 0xf7, 0x44, 0xb0, 0x70, 0x3d, 0xca, 0x1a, 0x68, - 0x03, 0xac, 0x90, 0xd2, 0x48, 0x5a, 0x53, 0xdf, 0x69, 0x24, 0xf2, 0x07, 0x94, 0x46, 0x58, 0x72, - 0x10, 0x02, 0x8b, 0xd3, 0x68, 0xd8, 0x2e, 0x4b, 0x8d, 0xf2, 0x1b, 0x3d, 0x04, 0x3b, 0x8c, 0x3c, - 0x16, 0x79, 0x7c, 0xd2, 0xae, 0x6c, 0x18, 0x9b, 0xcd, 0x9d, 0xb5, 0xd4, 0x87, 0xbb, 0x6c, 0x38, - 0x24, 0x41, 0xf7, 0x20, 0xf2, 0x70, 0x2a, 0x84, 0x3e, 0x86, 0x55, 0x2f, 0x66, 0x3e, 0xe1, 0xc2, - 0x42, 0x9f, 0x8e, 0xa9, 0xdf, 0xae, 0xca, 0x7e, 0x37, 0xd3, 0x7e, 0x7b, 0x09, 0x7f, 0x5f, 0xb0, - 0x71, 0xd3, 0xcb, 0xb5, 0xd1, 0x07, 0xd0, 0x0c, 0x18, 0xef, 0x9c, 0x78, 0xbe, 0xdf, 0x71, 0x89, - 0xdb, 0xa7, 0x6d, 0x7b, 0xc3, 0xd8, 0xb4, 0x71, 0x23, 0x60, 0xfc, 0x27, 0x9e, 0xef, 0xef, 0x0a, - 0x9a, 0x8c, 0xcb, 0x24, 0x70, 0x3b, 0x3e, 0xeb, 0xb5, 0x6b, 0x92, 0x5f, 0x15, 0xed, 0x7d, 0xd6, - 0x13, 0x71, 0xe9, 0x93, 0xa0, 0xeb, 0xd3, 0x0e, 0xf7, 0x86, 0xb4, 0x0d, 0x92, 0x0b, 0x8a, 0x74, - 0xe4, 0x0d, 0xa9, 0x10, 0x88, 0x5d, 0x12, 0x74, 0xba, 0x94, 0x13, 0xcf, 0x6f, 0xd7, 0x95, 0x80, - 0x20, 0x3d, 0x96, 0x94, 0x4f, 0x2d, 0xdb, 0x6a, 0x95, 0x85, 0xfb, 0x48, 0xb7, 0xf3, 0x7a, 0xc4, - 0xa2, 0xd1, 0xd0, 0x79, 0x0c, 0xf0, 0x49, 0x36, 0xc2, 0x4d, 0xa8, 0x9e, 0x12, 0x8f, 0x77, 0x86, - 0x2a, 0x29, 0x4a, 0xb8, 0x22, 0x9a, 0xcf, 0x63, 0xf4, 0x1e, 0x40, 0x18, 0x31, 0x97, 0xc6, 0xb1, - 0xe0, 0x99, 0x92, 0x57, 0xd3, 0x94, 0xe7, 0xb1, 0xf3, 0x63, 0xb0, 0x0f, 0x5d, 0x12, 0xc8, 0xd9, - 0xb7, 0x0e, 0x65, 0xce, 0x38, 0xf1, 0xf5, 0x08, 0xaa, 0x21, 0x12, 0x5d, 0x8b, 0xd3, 0xee, 0x4c, - 0x7f, 0xda, 0x75, 0x7e, 0x6b, 0x00, 0x1c, 0xa6, 0x76, 0xa2, 0xfb, 0x50, 0x3e, 0x15, 0xd9, 0x3a, - 0x37, 0x7f, 0x12, 0x25, 0x58, 0xf1, 0xd1, 0x3d, 0xb0, 0xe4, 0x0c, 0x37, 0xcf, 0x93, 0x93, 0x6c, - 0x21, 0xd6, 0x25, 0x9c, 0xe8, 0x1c, 0x59, 0x24, 0x26, 0xd8, 0xce, 0x04, 0xea, 0x4f, 0xce, 0xa8, - 0xab, 0x8c, 0x88, 0xd1, 0x47, 0x79, 0x7f, 0x1b, 0x3a, 0x21, 0x93, 0xce, 0x99, 0xdb, 0x72, 0x41, - 0xf8, 0x28, 0x1f, 0x04, 0x73, 0xa6, 0x57, 0x86, 0x72, 0x3a, 0x32, 0x4e, 0x17, 0xe0, 0x29, 0xe5, - 0x98, 0xbe, 0x1e, 0xd1, 0x98, 0xa3, 0x2d, 0xa8, 0xba, 0x6a, 0xce, 0x68, 0xad, 0xad, 0xa9, 0xe4, - 0x94, 0x74, 0x9c, 0x08, 0x24, 0x93, 0xd1, 0xcc, 0x4d, 0xc6, 0xa4, 0xac, 0x95, 0xd4, 0xcc, 0xd6, - 0x4d, 0xe7, 0xd7, 0x50, 0x97, 0x5a, 0xe2, 0x90, 0x05, 0x31, 0x45, 0x3f, 0xc8, 0xa6, 0x9c, 0xa8, - 0x5b, 0x5a, 0x57, 0x73, 0x3b, 0xa9, 0xb7, 0xb2, 0x9a, 0xa5, 0xb3, 0x4d, 0x96, 0xb6, 0xfb, 0x50, - 0x56, 0xb2, 0xb3, 0x1e, 0x4f, 0x8a, 0x1f, 0x56, 0x7c, 0x91, 0x05, 0x63, 0xe2, 0x8f, 0xa8, 0xae, - 0x12, 0xaa, 0xe1, 0xfc, 0xc3, 0x80, 0xba, 0xf0, 0x40, 0x11, 0xa0, 0xb7, 0xa1, 0xa6, 0x2a, 0x56, - 0x06, 0x57, 0x95, 0xb0, 0x67, 0x74, 0x22, 0xd4, 0xf9, 0xde, 0xd0, 0x53, 0x95, 0x72, 0x05, 0xab, - 0xc6, 0xb4, 0x27, 0xac, 0x9c, 0x27, 0xc4, 0x34, 0x1b, 0xd0, 0x49, 0x87, 0x05, 0xfe, 0x44, 0xd6, - 0x05, 0x1b, 0x57, 0x07, 0x74, 0xf2, 0x22, 0xf0, 0xa5, 0xfb, 0x22, 0x2a, 0xe4, 0xa8, 0xac, 0x0c, - 0x36, 0x4e, 0x9a, 0xce, 0x2b, 0xa8, 0x3c, 0x1b, 0x1f, 0x10, 0x6f, 0xca, 0x0d, 0xc6, 0x5b, 0xdc, - 0x30, 0x1f, 0x9d, 0xc5, 0x8e, 0xe9, 0x43, 0x43, 0xf9, 0xa5, 0x78, 0x68, 0xee, 0x41, 0x39, 0x24, - 0x5e, 0x24, 0x66, 0x67, 0x69, 0xb3, 0xbe, 0xb3, 0x9a, 0xd9, 0x24, 0x6d, 0xc6, 0x8a, 0xeb, 0xbc, - 0x00, 0xfb, 0xf9, 0x88, 0xcb, 0xba, 0x84, 0x6e, 0x83, 0xc9, 0x42, 0x39, 0x76, 0x73, 0xa7, 0x9e, - 0xca, 0xbf, 0x08, 0xb1, 0xc9, 0xc2, 0x0b, 0x9b, 0xfe, 0xa5, 0x09, 0xab, 0x07, 0x11, 0x95, 0x13, - 0xb2, 0x48, 0x5c, 0x1f, 0x42, 0x6d, 0xa8, 0x0d, 0x4a, 0x6c, 0xcf, 0xfc, 0x99, 0x98, 0x8a, 0x33, - 0x99, 0xb9, 0xe5, 0xbd, 0x34, 0xbf, 0xbc, 0x7f, 0x17, 0x56, 0x54, 0xae, 0xe4, 0xc3, 0xdf, 0x90, - 0xc4, 0x97, 0x59, 0x0e, 0xa4, 0xcb, 0x79, 0x39, 0xb7, 0x9c, 0xa3, 0x1d, 0xb8, 0x1e, 0x0f, 0xbc, - 0xb0, 0xe3, 0xb2, 0x20, 0xe6, 0x11, 0xf1, 0x02, 0xde, 0x71, 0xfb, 0xd4, 0x1d, 0xe8, 0x8c, 0x58, - 0x13, 0xcc, 0xdd, 0x94, 0xb7, 0x2b, 0x58, 0x4e, 0x08, 0xad, 0xcc, 0x0d, 0xc5, 0xc3, 0xf8, 0x00, - 0x2a, 0x92, 0x3b, 0xef, 0x8b, 0x34, 0xb7, 0xb4, 0x80, 0xf3, 0x37, 0x03, 0x56, 0xc4, 0x62, 0xe5, - 0x15, 0x2a, 0x1c, 0x73, 0x3e, 0x32, 0x17, 0xf8, 0x08, 0x81, 0x35, 0xa0, 0x93, 0xb8, 0x5d, 0xda, - 0x28, 0x6d, 0x36, 0xb0, 0xfc, 0x46, 0xf7, 0xa0, 0xe9, 0x4a, 0xad, 0x33, 0xde, 0x5d, 0x51, 0x54, - 0xdd, 0xf5, 0x53, 0xcb, 0x2e, 0xb7, 0x2a, 0xb8, 0x72, 0xec, 0x05, 0x3e, 0xeb, 0x39, 0x3e, 0x34, - 0x13, 0x53, 0x2f, 0xbf, 0xfa, 0x38, 0x3d, 0x58, 0xd9, 0x1b, 0x86, 0x2c, 0x4a, 0x1d, 0x93, 0x4b, - 0x32, 0xe3, 0x02, 0x49, 0x36, 0x0f, 0xd2, 0x5c, 0x00, 0xd2, 0x79, 0x05, 0xcd, 0x44, 0x51, 0x71, - 0x58, 0xeb, 0xd3, 0xb0, 0x6a, 0x09, 0x86, 0x5f, 0xc1, 0xfa, 0x23, 0xc2, 0xdd, 0x3e, 0x66, 0xbe, - 0x7f, 0x4c, 0xdc, 0xc1, 0x55, 0xc6, 0xd8, 0x89, 0xe1, 0xfa, 0x8c, 0xf2, 0x2b, 0x88, 0x5a, 0x0c, - 0xcd, 0x5d, 0x9f, 0x92, 0x60, 0x14, 0x2e, 0x67, 0x21, 0x9c, 0x43, 0x5f, 0x9a, 0x47, 0xef, 0xfc, - 0xd1, 0x80, 0xd5, 0x54, 0xeb, 0x15, 0x2c, 0x8c, 0xf3, 0x89, 0x55, 0x5a, 0x94, 0x58, 0x03, 0x58, - 0x95, 0x01, 0x28, 0xb8, 0x2b, 0x48, 0x62, 0x6a, 0x4e, 0xcd, 0xdb, 0xf3, 0xf7, 0x05, 0x3e, 0xb4, - 0x32, 0x65, 0x97, 0xbe, 0x02, 0xfd, 0xde, 0x80, 0x55, 0xb1, 0xd8, 0x89, 0x4a, 0x5d, 0x04, 0xdb, - 0x5d, 0xa8, 0x0f, 0xc9, 0xd9, 0x4c, 0x4a, 0xc3, 0x90, 0x9c, 0x25, 0x09, 0x9d, 0xdb, 0x29, 0x94, - 0xce, 0xdb, 0x29, 0x58, 0x53, 0x3b, 0x05, 0xe7, 0x4f, 0x06, 0xb4, 0x32, 0x9b, 0xae, 0x20, 0x0d, - 0xee, 0x43, 0x59, 0x2c, 0x36, 0x6a, 0xd6, 0x2d, 0x3c, 0x22, 0x2a, 0xbe, 0xf3, 0x21, 0x54, 0x8f, - 0xce, 0xd4, 0xce, 0xba, 0x05, 0x25, 0x7e, 0x16, 0xe8, 0x93, 0x93, 0xf8, 0x44, 0x37, 0xa0, 0x12, - 0x73, 0xc2, 0x47, 0xc9, 0x29, 0x4d, 0xb7, 0xc4, 0x3e, 0x0b, 0x61, 0x1a, 0x33, 0x7f, 0x4c, 0x8b, - 0x7a, 0xf9, 0x42, 0xa5, 0xe3, 0x62, 0xc9, 0x8c, 0xbe, 0x0f, 0x35, 0x7e, 0x16, 0x74, 0xbc, 0xe0, - 0x84, 0xc5, 0x6d, 0x4b, 0x02, 0xce, 0x34, 0x6b, 0x74, 0xd8, 0xe6, 0xea, 0x23, 0x76, 0x5e, 0xc3, - 0x5a, 0xce, 0xf8, 0x2b, 0x28, 0x3d, 0x2f, 0xa1, 0xf6, 0x74, 0xb7, 0x88, 0x9b, 0xde, 0x03, 0x88, - 0xc9, 0x09, 0xed, 0x84, 0xcc, 0x0b, 0xb8, 0xf6, 0x51, 0x4d, 0x50, 0x0e, 0x04, 0xc1, 0xe9, 0x03, - 0x88, 0x71, 0xaf, 0x00, 0xc1, 0x67, 0xb0, 0x82, 0xc9, 0xe9, 0xd2, 0x0e, 0x11, 0x4d, 0x30, 0xdd, - 0x13, 0x7d, 0xef, 0x60, 0xba, 0x27, 0x0e, 0x83, 0x66, 0x32, 0xfc, 0x92, 0x17, 0xba, 0x73, 0xb6, - 0x95, 0xb1, 0xc4, 0x73, 0x30, 0x5a, 0x12, 0x9e, 0x85, 0x4a, 0x34, 0x4a, 0x2b, 0x45, 0xf9, 0x4a, - 0xa2, 0x94, 0x4a, 0x97, 0xbd, 0x9c, 0x9f, 0x02, 0xc2, 0xe4, 0x54, 0x96, 0xd9, 0x82, 0xa0, 0x2e, - 0x56, 0x5e, 0xe7, 0x22, 0xf7, 0x4b, 0x58, 0xcb, 0x29, 0x5e, 0x36, 0xb0, 0x6e, 0x06, 0x6c, 0x89, - 0x8b, 0xd5, 0x7c, 0xfe, 0xad, 0xe5, 0xb4, 0x5c, 0xfa, 0x2a, 0xf5, 0x39, 0xb4, 0x30, 0x39, 0x7d, - 0x4c, 0x7d, 0x5a, 0xec, 0x58, 0xf3, 0xf6, 0x29, 0xf5, 0x0b, 0x78, 0x67, 0x4a, 0xc3, 0xb2, 0xc3, - 0xd2, 0x83, 0xeb, 0x89, 0xc3, 0x8a, 0x83, 0xb8, 0x48, 0x64, 0x08, 0xdc, 0x98, 0x55, 0xb4, 0x6c, - 0x2c, 0x63, 0x40, 0x7a, 0x68, 0x12, 0xf4, 0xe8, 0xd2, 0x2f, 0x0f, 0x6e, 0x42, 0x95, 0x06, 0xdd, - 0xa9, 0xdd, 0x42, 0x85, 0x06, 0xdd, 0x67, 0x74, 0x22, 0xa6, 0x4e, 0x4e, 0xef, 0xb2, 0x71, 0x7d, - 0x65, 0xc8, 0x20, 0x7d, 0x1b, 0xd8, 0xe6, 0x4a, 0x9f, 0x0a, 0xe3, 0xa5, 0xc2, 0xfd, 0x8b, 0x21, - 0xcb, 0xeb, 0x15, 0x5e, 0x00, 0x4d, 0x5f, 0xf3, 0x58, 0xf9, 0x6b, 0x1e, 0x85, 0xbf, 0x9c, 0xe2, - 0xef, 0xc1, 0x6a, 0x6a, 0x5b, 0x71, 0xe0, 0xef, 0x43, 0x69, 0x30, 0x3e, 0xb7, 0xb4, 0x08, 0x9e, - 0xf3, 0xb1, 0x7c, 0x29, 0x90, 0x2e, 0xce, 0x43, 0x32, 0xce, 0x0f, 0x9d, 0x99, 0x4b, 0xcb, 0xbf, - 0x1b, 0x59, 0x31, 0x2c, 0xea, 0xcc, 0x07, 0x50, 0x89, 0x84, 0x09, 0x0b, 0xaf, 0x19, 0x54, 0xfc, - 0xb5, 0x80, 0xd8, 0xe2, 0x50, 0xe2, 0xf6, 0x3b, 0xd3, 0xfe, 0xad, 0x09, 0xca, 0xfe, 0xff, 0xea, - 0x63, 0x1f, 0xd6, 0xf3, 0x76, 0x5f, 0xaa, 0xa3, 0xbf, 0x34, 0xa0, 0xf6, 0x7c, 0xec, 0xba, 0xf2, - 0xe1, 0x03, 0xdd, 0x05, 0x8b, 0x4f, 0x42, 0xba, 0xe8, 0xb6, 0x4b, 0x32, 0x72, 0x2f, 0x22, 0x66, - 0xfe, 0x45, 0xe4, 0x36, 0xd4, 0xf4, 0x36, 0x97, 0xc7, 0x7a, 0x87, 0x6b, 0x2b, 0x82, 0x7a, 0x2e, - 0x89, 0xfb, 0x4c, 0x6c, 0x94, 0xe5, 0xfe, 0x42, 0xbd, 0x7f, 0x80, 0x24, 0xbd, 0x94, 0x3b, 0x99, - 0x1f, 0x29, 0x33, 0x64, 0xe3, 0x9b, 0xde, 0x5d, 0xd2, 0x2d, 0x8a, 0x39, 0xbd, 0x0f, 0xfa, 0x8d, - 0x01, 0xb6, 0xe8, 0x2e, 0xef, 0xb5, 0xfe, 0x1f, 0x10, 0x53, 0x6f, 0x34, 0xa5, 0xdc, 0x1b, 0xcd, - 0xdb, 0x11, 0x7c, 0xa5, 0x6d, 0x90, 0xa7, 0x90, 0xe4, 0xce, 0x7d, 0xf6, 0xea, 0x33, 0x31, 0x52, - 0xdf, 0xb9, 0x6f, 0x41, 0x45, 0xde, 0x85, 0x25, 0x31, 0x42, 0x39, 0x41, 0x19, 0x13, 0xac, 0x25, - 0x84, 0xac, 0x54, 0x9d, 0x9c, 0x86, 0xf2, 0xb2, 0xd2, 0x06, 0xac, 0x25, 0x9c, 0x43, 0x58, 0x13, - 0xc4, 0xa7, 0x94, 0x3f, 0x9a, 0x88, 0x54, 0x5d, 0xc6, 0xd2, 0xec, 0xfc, 0xce, 0x80, 0xf5, 0xfc, - 0xa8, 0xcb, 0xde, 0xe4, 0xde, 0x03, 0x4b, 0x1c, 0x7f, 0xe6, 0x9e, 0x20, 0x12, 0xb7, 0x62, 0xc9, - 0x76, 0x3e, 0x87, 0x9b, 0xa9, 0x1d, 0x87, 0x2a, 0x70, 0x45, 0x10, 0x9e, 0x9f, 0x06, 0xce, 0x5f, - 0x0d, 0x68, 0xcf, 0xab, 0x58, 0x36, 0xdc, 0xf9, 0x27, 0xc2, 0xc4, 0x01, 0xd6, 0x37, 0x3b, 0xe0, - 0x33, 0x40, 0x87, 0xa1, 0xef, 0x71, 0xf5, 0xde, 0x57, 0x74, 0x99, 0x10, 0x23, 0xe4, 0x96, 0x09, - 0x41, 0x10, 0xa5, 0xf3, 0x0f, 0x06, 0xac, 0xe5, 0xc6, 0x2f, 0x0e, 0xdc, 0x01, 0xcb, 0xa7, 0x27, - 0x5c, 0x1f, 0xcc, 0x9a, 0xf9, 0x87, 0x4a, 0x2c, 0x79, 0xe8, 0x03, 0x28, 0x47, 0x5e, 0xaf, 0xcf, - 0x75, 0xd8, 0x67, 0x85, 0x14, 0xd3, 0xf9, 0x02, 0xde, 0xfd, 0x59, 0x20, 0xce, 0x8c, 0x8f, 0x69, - 0xcc, 0x23, 0x36, 0xb9, 0xe2, 0x5d, 0x0e, 0x85, 0x5b, 0x8b, 0xd4, 0x2f, 0x39, 0x25, 0xb6, 0xbe, - 0x07, 0x90, 0xbd, 0xac, 0x22, 0x80, 0xca, 0x4f, 0x59, 0x34, 0x24, 0x7e, 0xeb, 0x1a, 0xaa, 0x42, - 0x69, 0x9f, 0x9d, 0xb6, 0x0c, 0x64, 0x83, 0xf5, 0x89, 0xd7, 0xeb, 0xb7, 0xcc, 0xad, 0x0d, 0x68, - 0xe6, 0x9f, 0x53, 0x51, 0x05, 0xcc, 0xc3, 0xbd, 0xd6, 0x35, 0xf1, 0x8b, 0x77, 0x5b, 0xc6, 0xd6, - 0x36, 0x98, 0x2f, 0x42, 0xd1, 0xf5, 0x60, 0xc4, 0xd5, 0x18, 0x8f, 0xa9, 0xaf, 0xc6, 0x10, 0x55, - 0xa8, 0x65, 0xa2, 0x06, 0xd8, 0xc9, 0xf5, 0x65, 0xab, 0xf4, 0x68, 0xeb, 0x9f, 0x6f, 0xee, 0x18, - 0xff, 0x7a, 0x73, 0xc7, 0xf8, 0xf7, 0x9b, 0x3b, 0xc6, 0x9f, 0xff, 0x73, 0xe7, 0x1a, 0xb4, 0x5d, - 0x36, 0xdc, 0x0e, 0xbd, 0xa0, 0xe7, 0x92, 0x70, 0x9b, 0x7b, 0x83, 0xf1, 0xf6, 0x60, 0x2c, 0xff, - 0x4c, 0x70, 0x5c, 0x91, 0x3f, 0x1f, 0xfe, 0x37, 0x00, 0x00, 0xff, 0xff, 0xc3, 0x3e, 0x6a, 0x3d, - 0xa0, 0x20, 0x00, 0x00, + 0x0c, 0xcb, 0x2a, 0x2a, 0xa3, 0x4a, 0xd0, 0xa7, 0xa2, 0x08, 0x2c, 0xb9, 0x8e, 0x62, 0xb9, 0x16, + 0x56, 0xaa, 0x0b, 0x03, 0x4d, 0x98, 0xd5, 0x71, 0x45, 0x1e, 0x78, 0xbc, 0x3d, 0xdf, 0xad, 0x28, + 0x11, 0x45, 0x50, 0x14, 0x45, 0x0a, 0xe4, 0xb1, 0x45, 0x81, 0x16, 0x45, 0xf3, 0x01, 0xfa, 0x05, + 0xfa, 0xd2, 0x2f, 0xd0, 0xc7, 0x3e, 0xf4, 0x03, 0x14, 0xee, 0x17, 0x29, 0xf6, 0xcf, 0xdd, 0xf1, + 0x48, 0xca, 0x56, 0xaf, 0x94, 0xf2, 0xc4, 0xdb, 0x99, 0xd9, 0x9d, 0xf9, 0xcd, 0xcc, 0xce, 0xfe, + 0x23, 0x2c, 0x0d, 0x46, 0x51, 0xe8, 0x86, 0x47, 0x9b, 0x61, 0xc4, 0x38, 0x43, 0x55, 0xdd, 0xbc, + 0xd5, 0x18, 0x52, 0x4e, 0x12, 0xf2, 0xad, 0x25, 0x1a, 0x45, 0x2c, 0x4a, 0x9b, 0xab, 0x3d, 0xd6, + 0x63, 0xf2, 0xf3, 0xa1, 0xf8, 0x52, 0x54, 0xe7, 0x4b, 0xb0, 0xf7, 0x98, 0x3b, 0xd8, 0x0d, 0x8e, + 0x19, 0x7a, 0x1f, 0x1a, 0x61, 0xe4, 0x0d, 0x49, 0x34, 0xee, 0xf8, 0xcc, 0x1d, 0xb4, 0x8d, 0x35, + 0x63, 0xbd, 0x81, 0xeb, 0x9a, 0x26, 0xc4, 0x84, 0x88, 0x60, 0x75, 0x46, 0x34, 0x8a, 0x3d, 0x16, + 0xb4, 0xcd, 0x35, 0x63, 0xdd, 0xc2, 0x75, 0x41, 0x7b, 0xa1, 0x48, 0xa8, 0x05, 0xa5, 0x01, 0x1d, + 0xb7, 0x4b, 0xb2, 0xb3, 0xf8, 0x44, 0xef, 0x82, 0x2d, 0x3b, 0x71, 0xee, 0xb7, 0x2d, 0xd9, 0xa1, + 0x2a, 0xda, 0x87, 0xdc, 0x77, 0xbe, 0x31, 0xc0, 0x7e, 0x4a, 0xc7, 0x8f, 0x85, 0xa5, 0xe8, 0x01, + 0x54, 0x04, 0x9d, 0x76, 0xa5, 0xe6, 0xfa, 0xd6, 0x3b, 0x9b, 0x09, 0xce, 0xc4, 0x44, 0xac, 0x05, + 0xd0, 0x77, 0xa0, 0x16, 0x51, 0x1e, 0x8d, 0xc9, 0x91, 0x4f, 0xa5, 0x11, 0x35, 0x9c, 0x11, 0xd0, + 0x2a, 0x94, 0xc9, 0x11, 0x8b, 0xb8, 0x34, 0xa2, 0x86, 0x55, 0x03, 0x6d, 0x81, 0xed, 0xb2, 0xe0, + 0xd8, 0xf7, 0x5c, 0x2e, 0xcd, 0xa8, 0x6f, 0xdd, 0x48, 0x15, 0xfc, 0x3c, 0xf2, 0x38, 0xdd, 0xd6, + 0x5c, 0x9c, 0xca, 0x39, 0xa7, 0xb0, 0x94, 0x63, 0x09, 0x2c, 0x31, 0x27, 0x11, 0xef, 0xf0, 0x58, + 0x5a, 0x69, 0xe1, 0xaa, 0x6c, 0x1f, 0xc6, 0xe8, 0x2e, 0xd4, 0x93, 0x7e, 0x82, 0xab, 0x5c, 0x03, + 0x09, 0xe9, 0x30, 0x9e, 0xe3, 0x99, 0x36, 0x54, 0xb5, 0x77, 0xa5, 0x45, 0x0d, 0x9c, 0x34, 0x9d, + 0x6f, 0x4a, 0x50, 0xdd, 0x66, 0x01, 0xa7, 0x67, 0x1c, 0xdd, 0x16, 0x60, 0x7b, 0x1e, 0x0b, 0x3a, + 0x5e, 0x57, 0x2b, 0xb5, 0x15, 0x61, 0xb7, 0x8b, 0x7e, 0x08, 0x0d, 0xcd, 0xa4, 0x21, 0x73, 0xfb, + 0x52, 0x6d, 0x7d, 0x6b, 0x65, 0x53, 0xa7, 0x02, 0x96, 0xbc, 0xc7, 0x82, 0x85, 0xeb, 0x51, 0xd6, + 0x40, 0x6b, 0x60, 0x85, 0x94, 0x46, 0xd2, 0x9a, 0xfa, 0x56, 0x23, 0x91, 0xdf, 0xa7, 0x34, 0xc2, + 0x92, 0x83, 0x10, 0x58, 0x9c, 0x46, 0xc3, 0x76, 0x59, 0x6a, 0x94, 0xdf, 0xe8, 0x21, 0xd8, 0x61, + 0xe4, 0xb1, 0xc8, 0xe3, 0xe3, 0x76, 0x65, 0xcd, 0x58, 0x6f, 0x6e, 0xad, 0xa4, 0x3e, 0xdc, 0x66, + 0xc3, 0x21, 0x09, 0xba, 0xfb, 0x91, 0x87, 0x53, 0x21, 0xf4, 0x31, 0x2c, 0x7b, 0x31, 0xf3, 0x09, + 0x17, 0x16, 0xfa, 0x74, 0x44, 0xfd, 0x76, 0x55, 0xf6, 0xbb, 0x99, 0xf6, 0xdb, 0x4d, 0xf8, 0x7b, + 0x82, 0x8d, 0x9b, 0x5e, 0xae, 0x8d, 0x3e, 0x80, 0x66, 0xc0, 0x78, 0xe7, 0xd8, 0xf3, 0xfd, 0x8e, + 0x4b, 0xdc, 0x3e, 0x6d, 0xdb, 0x6b, 0xc6, 0xba, 0x8d, 0x1b, 0x01, 0xe3, 0x3f, 0xf1, 0x7c, 0x7f, + 0x5b, 0xd0, 0x64, 0x5c, 0xc6, 0x81, 0xdb, 0xf1, 0x59, 0xaf, 0x5d, 0x93, 0xfc, 0xaa, 0x68, 0xef, + 0xb1, 0x9e, 0x88, 0x4b, 0x9f, 0x04, 0x5d, 0x9f, 0x76, 0xb8, 0x37, 0xa4, 0x6d, 0x90, 0x5c, 0x50, + 0xa4, 0x43, 0x6f, 0x48, 0x85, 0x40, 0xec, 0x92, 0xa0, 0xd3, 0xa5, 0x9c, 0x78, 0x7e, 0xbb, 0xae, + 0x04, 0x04, 0x69, 0x47, 0x52, 0x3e, 0xb5, 0x6c, 0xab, 0x55, 0x16, 0xee, 0x23, 0xdd, 0xce, 0xab, + 0x13, 0x16, 0x9d, 0x0c, 0x9d, 0x1d, 0x80, 0x4f, 0xb2, 0x11, 0x6e, 0x42, 0xf5, 0x94, 0x78, 0xbc, + 0x33, 0x54, 0x49, 0x51, 0xc2, 0x15, 0xd1, 0x7c, 0x16, 0xa3, 0xf7, 0x00, 0xc2, 0x88, 0xb9, 0x34, + 0x8e, 0x05, 0xcf, 0x94, 0xbc, 0x9a, 0xa6, 0x3c, 0x8b, 0x9d, 0x1f, 0x83, 0x7d, 0xe0, 0x92, 0x40, + 0xce, 0xbe, 0x55, 0x28, 0x73, 0xc6, 0x89, 0xaf, 0x47, 0x50, 0x0d, 0x91, 0xe8, 0x5a, 0x9c, 0x76, + 0xa7, 0xfa, 0xd3, 0xae, 0xf3, 0x1b, 0x03, 0xe0, 0x20, 0xb5, 0x13, 0xdd, 0x87, 0xf2, 0xa9, 0xc8, + 0xd6, 0x99, 0xf9, 0x93, 0x28, 0xc1, 0x8a, 0x8f, 0xee, 0x81, 0x25, 0x67, 0xb8, 0x79, 0x9e, 0x9c, + 0x64, 0x0b, 0xb1, 0x2e, 0xe1, 0x44, 0xe7, 0xc8, 0x3c, 0x31, 0xc1, 0x76, 0xc6, 0x50, 0x7f, 0x7c, + 0x46, 0x5d, 0x65, 0x44, 0x8c, 0x3e, 0xca, 0xfb, 0xdb, 0xd0, 0x09, 0x99, 0x74, 0xce, 0xdc, 0x96, + 0x0b, 0xc2, 0x47, 0xf9, 0x20, 0x98, 0x53, 0xbd, 0x32, 0x94, 0x93, 0x91, 0x71, 0xba, 0x00, 0x4f, + 0x28, 0xc7, 0xf4, 0xd5, 0x09, 0x8d, 0x39, 0xda, 0x80, 0xaa, 0xab, 0xe6, 0x8c, 0xd6, 0xda, 0x9a, + 0x48, 0x4e, 0x49, 0xc7, 0x89, 0x40, 0x32, 0x19, 0xcd, 0xdc, 0x64, 0x4c, 0xca, 0x5a, 0x49, 0xcd, + 0x6c, 0xdd, 0x74, 0x7e, 0x05, 0x75, 0xa9, 0x25, 0x0e, 0x59, 0x10, 0x53, 0xf4, 0x83, 0x6c, 0xca, + 0x89, 0xba, 0xa5, 0x75, 0x35, 0x37, 0x93, 0x7a, 0x2b, 0xab, 0x59, 0x3a, 0xdb, 0x64, 0x69, 0xbb, + 0x0f, 0x65, 0x25, 0x3b, 0xed, 0xf1, 0xa4, 0xf8, 0x61, 0xc5, 0x17, 0x59, 0x30, 0x22, 0xfe, 0x09, + 0xd5, 0x55, 0x42, 0x35, 0x9c, 0x7f, 0x19, 0x50, 0x17, 0x1e, 0x28, 0x02, 0xf4, 0x36, 0xd4, 0x54, + 0xc5, 0xca, 0xe0, 0xaa, 0x12, 0xf6, 0x94, 0x8e, 0x85, 0x3a, 0xdf, 0x1b, 0x7a, 0xaa, 0x52, 0x2e, + 0x61, 0xd5, 0x98, 0xf4, 0x84, 0x95, 0xf3, 0x84, 0x98, 0x66, 0x03, 0x3a, 0xee, 0xb0, 0xc0, 0x1f, + 0xcb, 0xba, 0x60, 0xe3, 0xea, 0x80, 0x8e, 0x9f, 0x07, 0xbe, 0x74, 0x5f, 0x44, 0x85, 0x1c, 0x95, + 0x95, 0xc1, 0xc6, 0x49, 0x53, 0xcc, 0x0e, 0x1a, 0x74, 0xa5, 0xfe, 0xaa, 0xd4, 0x5f, 0xa1, 0x41, + 0xf7, 0x29, 0x1d, 0x3b, 0x2f, 0xa1, 0xf2, 0x74, 0xb4, 0x4f, 0xbc, 0x09, 0xff, 0x18, 0x6f, 0xf1, + 0xcf, 0x6c, 0xd8, 0xe6, 0x7b, 0xac, 0x0f, 0x0d, 0xe5, 0xb0, 0xe2, 0x31, 0xbb, 0x07, 0xe5, 0x90, + 0x78, 0x91, 0x98, 0xb6, 0xa5, 0xf5, 0xfa, 0xd6, 0x72, 0x66, 0x93, 0xb4, 0x19, 0x2b, 0xae, 0xf3, + 0x1c, 0xec, 0x67, 0x27, 0x5c, 0x16, 0x2c, 0x74, 0x1b, 0x4c, 0x16, 0xca, 0xb1, 0x9b, 0x5b, 0xf5, + 0x54, 0xfe, 0x79, 0x88, 0x4d, 0x16, 0x5e, 0xd8, 0xf4, 0xaf, 0x4c, 0x58, 0xde, 0x8f, 0xa8, 0x9c, + 0xa9, 0x45, 0x02, 0xfe, 0x10, 0x6a, 0x43, 0x6d, 0x50, 0x62, 0x7b, 0xe6, 0xcf, 0xc4, 0x54, 0x9c, + 0xc9, 0xcc, 0xac, 0xfb, 0xa5, 0xd9, 0x75, 0xff, 0xbb, 0xb0, 0xa4, 0x92, 0x28, 0x9f, 0x17, 0x0d, + 0x49, 0x7c, 0x91, 0x25, 0x47, 0xba, 0xce, 0x97, 0x73, 0xeb, 0x3c, 0xda, 0x82, 0xeb, 0xf1, 0xc0, + 0x0b, 0x3b, 0x2e, 0x0b, 0x62, 0x1e, 0x11, 0x2f, 0xe0, 0x1d, 0xb7, 0x4f, 0xdd, 0x81, 0x4e, 0x95, + 0x15, 0xc1, 0xdc, 0x4e, 0x79, 0xdb, 0x82, 0xe5, 0x84, 0xd0, 0xca, 0xdc, 0x50, 0x3c, 0x8c, 0x0f, + 0xa0, 0x22, 0xb9, 0xb3, 0xbe, 0x48, 0x73, 0x4b, 0x0b, 0x38, 0x7f, 0x35, 0x60, 0x49, 0xac, 0x62, + 0x5e, 0xa1, 0x8a, 0x32, 0xe3, 0x23, 0x73, 0x8e, 0x8f, 0x10, 0x58, 0x03, 0x3a, 0x8e, 0xdb, 0xa5, + 0xb5, 0xd2, 0x7a, 0x03, 0xcb, 0x6f, 0x74, 0x0f, 0x9a, 0xae, 0xd4, 0x3a, 0xe5, 0xdd, 0x25, 0x45, + 0xd5, 0x5d, 0x3f, 0xb5, 0xec, 0x72, 0xab, 0x82, 0x2b, 0x47, 0x5e, 0xe0, 0xb3, 0x9e, 0xe3, 0x43, + 0x33, 0x31, 0xf5, 0xf2, 0xcb, 0x92, 0xd3, 0x83, 0xa5, 0xdd, 0x61, 0xc8, 0xa2, 0xd4, 0x31, 0xb9, + 0x24, 0x33, 0x2e, 0x90, 0x64, 0xb3, 0x20, 0xcd, 0x39, 0x20, 0x9d, 0x97, 0xd0, 0x4c, 0x14, 0x15, + 0x87, 0xb5, 0x3a, 0x09, 0xab, 0x96, 0x60, 0xf8, 0x25, 0xac, 0x3e, 0x22, 0xdc, 0xed, 0x63, 0xe6, + 0xfb, 0x47, 0xc4, 0x1d, 0x5c, 0x65, 0x8c, 0x9d, 0x18, 0xae, 0x4f, 0x29, 0xbf, 0x82, 0xa8, 0xc5, + 0xd0, 0xdc, 0xf6, 0x29, 0x09, 0x4e, 0xc2, 0xc5, 0xac, 0x90, 0x33, 0xe8, 0x4b, 0xb3, 0xe8, 0x9d, + 0x3f, 0x18, 0xb0, 0x9c, 0x6a, 0xbd, 0x82, 0x15, 0x73, 0x36, 0xb1, 0x4a, 0xf3, 0x12, 0x6b, 0x00, + 0xcb, 0x32, 0x00, 0x05, 0xb7, 0x0b, 0x49, 0x4c, 0xcd, 0x89, 0x79, 0x7b, 0xfe, 0x86, 0xc1, 0x87, + 0x56, 0xa6, 0xec, 0xd2, 0x57, 0xa0, 0xdf, 0x19, 0xb0, 0x2c, 0x16, 0x3b, 0x51, 0xa9, 0x8b, 0x60, + 0xbb, 0x0b, 0xf5, 0x21, 0x39, 0x9b, 0x4a, 0x69, 0x18, 0x92, 0xb3, 0x24, 0xa1, 0x73, 0x5b, 0x88, + 0xd2, 0x79, 0x5b, 0x08, 0x6b, 0x62, 0x0b, 0xe1, 0xfc, 0xd1, 0x80, 0x56, 0x66, 0xd3, 0x15, 0xa4, + 0xc1, 0x7d, 0x28, 0x8b, 0xc5, 0x46, 0xcd, 0xba, 0xb9, 0x67, 0x47, 0xc5, 0x77, 0x3e, 0x84, 0xea, + 0xe1, 0x99, 0xda, 0x72, 0xb7, 0xa0, 0xc4, 0xcf, 0x02, 0x7d, 0xa4, 0x12, 0x9f, 0xe8, 0x06, 0x54, + 0x62, 0x4e, 0xf8, 0x49, 0x72, 0x7c, 0xd3, 0x2d, 0xe7, 0xef, 0x06, 0x20, 0x4c, 0x63, 0xe6, 0x8f, + 0x68, 0x51, 0x2f, 0x5f, 0xa8, 0x74, 0x5c, 0x2c, 0x99, 0xd1, 0xf7, 0xa1, 0xc6, 0xcf, 0x82, 0x8e, + 0x17, 0x1c, 0xb3, 0xb8, 0x6d, 0x49, 0xc0, 0x99, 0x66, 0x8d, 0x0e, 0xdb, 0x5c, 0x7d, 0xc4, 0xce, + 0x2b, 0x58, 0xc9, 0x19, 0x7f, 0x05, 0xa5, 0xe7, 0x05, 0xd4, 0x9e, 0x6c, 0x17, 0x71, 0xd3, 0x7b, + 0x00, 0x31, 0x39, 0xa6, 0x9d, 0x90, 0x79, 0x01, 0xd7, 0x3e, 0xaa, 0x09, 0xca, 0xbe, 0x20, 0x38, + 0x7d, 0x00, 0x31, 0xee, 0x15, 0x20, 0xf8, 0x0c, 0x96, 0x30, 0x39, 0x5d, 0xd8, 0xe9, 0xa2, 0x09, + 0xa6, 0x7b, 0xac, 0x2f, 0x24, 0x4c, 0xf7, 0xd8, 0x61, 0xd0, 0x4c, 0x86, 0x5f, 0xf0, 0x42, 0x77, + 0xce, 0xb6, 0x32, 0x96, 0x78, 0xf6, 0x4f, 0x16, 0x84, 0x67, 0xae, 0x12, 0x8d, 0xd2, 0x4a, 0x51, + 0xbe, 0x94, 0x28, 0xa5, 0xd2, 0x45, 0x2f, 0xe7, 0xa7, 0x80, 0x30, 0x39, 0x95, 0x65, 0xb6, 0x20, + 0xa8, 0x8b, 0x95, 0xd7, 0x99, 0xc8, 0x7d, 0x0e, 0x2b, 0x39, 0xc5, 0x8b, 0x06, 0xd6, 0xcd, 0x80, + 0x2d, 0x70, 0xb1, 0x9a, 0xcd, 0xbf, 0x95, 0x9c, 0x96, 0x4b, 0x5f, 0xa5, 0xbe, 0x80, 0x16, 0x26, + 0xa7, 0x3b, 0xd4, 0xa7, 0xc5, 0x8e, 0x35, 0x6f, 0x9f, 0x52, 0xbf, 0x80, 0x77, 0x26, 0x34, 0x2c, + 0x3a, 0x2c, 0x3d, 0xb8, 0x9e, 0x38, 0xac, 0x38, 0x88, 0x8b, 0x44, 0x86, 0xc0, 0x8d, 0x69, 0x45, + 0x8b, 0xc6, 0x32, 0x02, 0xa4, 0x87, 0x26, 0x41, 0x8f, 0x2e, 0xfc, 0x56, 0x61, 0xe2, 0xc0, 0x5f, + 0xca, 0x1d, 0xf8, 0x3f, 0x87, 0x95, 0x9c, 0xde, 0x45, 0xe3, 0xfa, 0xda, 0x90, 0x41, 0xfa, 0x36, + 0xb0, 0xcd, 0x94, 0x3e, 0x15, 0xc6, 0x4b, 0x85, 0xfb, 0x67, 0x43, 0x96, 0xd7, 0x2b, 0xbc, 0x19, + 0x9a, 0xbc, 0xff, 0xb1, 0xf2, 0xf7, 0x3f, 0x0a, 0x7f, 0x39, 0xc5, 0xdf, 0x83, 0xe5, 0xd4, 0xb6, + 0xe2, 0xc0, 0xdf, 0x87, 0xd2, 0x60, 0x74, 0x6e, 0x69, 0x11, 0x3c, 0xe7, 0x63, 0xf9, 0x84, 0x20, + 0x5d, 0x9c, 0x87, 0x64, 0x9c, 0x1f, 0x3a, 0x33, 0x97, 0x96, 0x7f, 0x33, 0xb2, 0x62, 0x58, 0xd4, + 0x99, 0x0f, 0xa0, 0x12, 0x09, 0x13, 0xe6, 0x5e, 0x33, 0xa8, 0xf8, 0x6b, 0x01, 0xb1, 0xc5, 0xa1, + 0xc4, 0xed, 0x77, 0x26, 0xfd, 0x5b, 0x13, 0x94, 0xbd, 0xff, 0xd5, 0xc7, 0x3e, 0xac, 0xe6, 0xed, + 0xbe, 0x54, 0x47, 0x7f, 0x65, 0x40, 0xed, 0xd9, 0xc8, 0x75, 0xe5, 0x8b, 0x08, 0xba, 0x0b, 0x16, + 0x1f, 0x87, 0x74, 0xde, 0x6d, 0x97, 0x64, 0xe4, 0x9e, 0x4a, 0xcc, 0xfc, 0x53, 0xc9, 0x6d, 0xa8, + 0xe9, 0x6d, 0x2e, 0x8f, 0xf5, 0x0e, 0xd7, 0x56, 0x04, 0xf5, 0x8e, 0x12, 0xf7, 0x99, 0xd8, 0x28, + 0xcb, 0xfd, 0x85, 0x7a, 0x18, 0x01, 0x49, 0x7a, 0x21, 0x77, 0x32, 0x3f, 0x52, 0x66, 0xc8, 0xc6, + 0x9b, 0x1e, 0x64, 0xd2, 0x2d, 0x8a, 0x39, 0xb9, 0x0f, 0xfa, 0xb5, 0x01, 0xb6, 0xe8, 0x2e, 0xef, + 0xb5, 0xfe, 0x1f, 0x10, 0x13, 0x8f, 0x37, 0xa5, 0xdc, 0xe3, 0xcd, 0xdb, 0x11, 0x7c, 0xad, 0x6d, + 0x90, 0xa7, 0x90, 0xe4, 0x32, 0x7e, 0xfa, 0xea, 0x33, 0x31, 0x52, 0x5f, 0xc6, 0x6f, 0x40, 0x45, + 0xde, 0x85, 0x25, 0x31, 0x42, 0x39, 0x41, 0x19, 0x13, 0xac, 0x25, 0x84, 0xac, 0x54, 0x9d, 0x9c, + 0x86, 0xf2, 0xb2, 0xd2, 0x06, 0xac, 0x25, 0x9c, 0x03, 0x58, 0x11, 0xc4, 0x27, 0x94, 0x3f, 0x1a, + 0x8b, 0x54, 0x5d, 0xc4, 0xd2, 0xec, 0xfc, 0xd6, 0x80, 0xd5, 0xfc, 0xa8, 0x8b, 0xde, 0xe4, 0xde, + 0x03, 0x4b, 0x1c, 0x7f, 0x66, 0xde, 0x26, 0x12, 0xb7, 0x62, 0xc9, 0x76, 0xbe, 0x80, 0x9b, 0xa9, + 0x1d, 0x07, 0x2a, 0x70, 0x45, 0x10, 0x9e, 0x9f, 0x06, 0xce, 0x5f, 0x0c, 0x68, 0xcf, 0xaa, 0x58, + 0x34, 0xdc, 0xd9, 0xb7, 0xc3, 0xc4, 0x01, 0xd6, 0x9b, 0x1d, 0xf0, 0x19, 0xa0, 0x83, 0xd0, 0xf7, + 0xb8, 0x7a, 0x08, 0x2c, 0xba, 0x4c, 0x88, 0x11, 0x72, 0xcb, 0x84, 0x20, 0x88, 0xd2, 0xf9, 0x7b, + 0x03, 0x56, 0x72, 0xe3, 0x17, 0x07, 0xee, 0x80, 0xe5, 0xd3, 0x63, 0xae, 0x0f, 0x66, 0xcd, 0xfc, + 0x0b, 0x26, 0x96, 0x3c, 0xf4, 0x01, 0x94, 0x23, 0xaf, 0xd7, 0xe7, 0x3a, 0xec, 0xd3, 0x42, 0x8a, + 0xe9, 0x7c, 0x09, 0xef, 0xfe, 0x2c, 0x10, 0x67, 0xc6, 0x1d, 0x1a, 0xf3, 0x88, 0x8d, 0xaf, 0x78, + 0x97, 0x43, 0xe1, 0xd6, 0x3c, 0xf5, 0x0b, 0x4e, 0x89, 0x8d, 0xef, 0x01, 0x64, 0x4f, 0xae, 0x08, + 0xa0, 0xf2, 0x53, 0x16, 0x0d, 0x89, 0xdf, 0xba, 0x86, 0xaa, 0x50, 0xda, 0x63, 0xa7, 0x2d, 0x03, + 0xd9, 0x60, 0x7d, 0xe2, 0xf5, 0xfa, 0x2d, 0x73, 0x63, 0x0d, 0x9a, 0xf9, 0x77, 0x56, 0x54, 0x01, + 0xf3, 0x60, 0xb7, 0x75, 0x4d, 0xfc, 0xe2, 0xed, 0x96, 0xb1, 0xb1, 0x09, 0xe6, 0xf3, 0x50, 0x74, + 0xdd, 0x3f, 0xe1, 0x6a, 0x8c, 0x1d, 0xea, 0xab, 0x31, 0x44, 0x15, 0x6a, 0x99, 0xa8, 0x01, 0x76, + 0x72, 0x7d, 0xd9, 0x2a, 0x3d, 0xda, 0xf8, 0xc7, 0xeb, 0x3b, 0xc6, 0x3f, 0x5f, 0xdf, 0x31, 0xfe, + 0xfd, 0xfa, 0x8e, 0xf1, 0xa7, 0xff, 0xdc, 0xb9, 0x06, 0x6d, 0x97, 0x0d, 0x37, 0x43, 0x2f, 0xe8, + 0xb9, 0x24, 0xdc, 0xe4, 0xde, 0x60, 0xb4, 0x39, 0x18, 0xc9, 0x7f, 0x19, 0x1c, 0x55, 0xe4, 0xcf, + 0x87, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x98, 0xac, 0xa6, 0xa9, 0xb9, 0x20, 0x00, 0x00, } From f17ec48038eae422ff95442c83be7f01c6c42ab1 Mon Sep 17 00:00:00 2001 From: MyonKeminta <9948422+MyonKeminta@users.noreply.github.com> Date: Thu, 8 Nov 2018 18:21:40 +0800 Subject: [PATCH 2/3] tikvclient: Add endKey param to Scanner (#8178) Signed-off-by: MyonKeminta --- ddl/db_test.go | 10 +-- ddl/delete_range.go | 2 +- ddl/index.go | 2 +- kv/buffer_store.go | 16 ++-- kv/buffer_store_test.go | 2 +- kv/kv.go | 10 ++- kv/mem_buffer_test.go | 20 ++--- kv/memdb_buffer.go | 16 ++-- kv/mock.go | 12 +-- kv/mock_test.go | 4 +- kv/union_store.go | 8 +- kv/union_store_test.go | 18 ++--- session/txn.go | 16 ++-- store/mockstore/mocktikv/mock_tikv_test.go | 24 +++++- store/mockstore/mocktikv/rpc.go | 6 +- store/store_test.go | 29 ++++---- store/tikv/delete_range_test.go | 2 +- store/tikv/lock_test.go | 4 +- store/tikv/safepoint_test.go | 2 +- store/tikv/scan.go | 7 +- store/tikv/scan_mock_test.go | 10 ++- store/tikv/scan_test.go | 86 +++++++++++----------- store/tikv/snapshot.go | 10 +-- store/tikv/snapshot_test.go | 4 +- store/tikv/store_test.go | 2 +- store/tikv/ticlient_test.go | 4 +- store/tikv/txn.go | 10 +-- structure/hash.go | 2 +- table/tables/index.go | 6 +- table/tables/tables.go | 4 +- util/admin/admin.go | 2 +- util/prefix_helper.go | 4 +- 32 files changed, 192 insertions(+), 162 deletions(-) diff --git a/ddl/db_test.go b/ddl/db_test.go index 9b9c0d9a80bb9..0044961c6836b 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -1865,7 +1865,7 @@ func (s *testDBSuite) TestTruncateTable(c *C) { hasOldTableData := true for i := 0; i < waitForCleanDataRound; i++ { err = kv.RunInNewTxn(s.store, false, func(txn kv.Transaction) error { - it, err1 := txn.Seek(tablePrefix) + it, err1 := txn.Iter(tablePrefix, nil) if err1 != nil { return err1 } @@ -2793,7 +2793,7 @@ func (s *testDBSuite) TestAlterTableDropPartition(c *C) { s.tk.MustExec("drop table if exists tr;") s.tk.MustExec(` create table tr( - id int, name varchar(50), + id int, name varchar(50), purchased date ) partition by range( year(purchased) ) ( @@ -2884,7 +2884,7 @@ func checkPartitionDelRangeDone(c *C, s *testDBSuite, partitionPrefix kv.Key) bo hasOldPartitionData := true for i := 0; i < waitForCleanDataRound; i++ { err := kv.RunInNewTxn(s.store, false, func(txn kv.Transaction) error { - it, err := txn.Seek(partitionPrefix) + it, err := txn.Iter(partitionPrefix, nil) if err != nil { return err } @@ -2935,7 +2935,7 @@ func (s *testDBSuite) TestTruncatePartitionAndDropTable(c *C) { s.tk.MustExec("drop table if exists t3;") s.tk.MustExec("set @@session.tidb_enable_table_partition=1;") s.tk.MustExec(`create table t3( - id int, name varchar(50), + id int, name varchar(50), purchased date ) partition by range( year(purchased) ) ( @@ -2974,7 +2974,7 @@ func (s *testDBSuite) TestTruncatePartitionAndDropTable(c *C) { s.tk.MustExec("drop table if exists t4;") s.tk.MustExec("set @@session.tidb_enable_table_partition=1;") s.tk.MustExec(`create table t4( - id int, name varchar(50), + id int, name varchar(50), purchased date ) partition by range( year(purchased) ) ( diff --git a/ddl/delete_range.go b/ddl/delete_range.go index aa1bf30640ad3..fba35867f37b0 100644 --- a/ddl/delete_range.go +++ b/ddl/delete_range.go @@ -154,7 +154,7 @@ func (dr *delRange) doTask(ctx sessionctx.Context, r util.DelRangeTask) error { finish := true dr.keys = dr.keys[:0] err := kv.RunInNewTxn(dr.store, false, func(txn kv.Transaction) error { - iter, err := txn.Seek(oldStartKey) + iter, err := txn.Iter(oldStartKey, nil) if err != nil { return errors.Trace(err) } diff --git a/ddl/index.go b/ddl/index.go index b546cf256cb96..92dbd2723c5ad 100644 --- a/ddl/index.go +++ b/ddl/index.go @@ -1192,7 +1192,7 @@ func iterateSnapshotRows(store kv.Storage, priority int, t table.Table, version return errors.Trace(err) } firstKey := t.RecordKey(seekHandle) - it, err := snap.Seek(firstKey) + it, err := snap.Iter(firstKey, nil) if err != nil { return errors.Trace(err) } diff --git a/kv/buffer_store.go b/kv/buffer_store.go index 5e798db5c8875..2317a0f324437 100644 --- a/kv/buffer_store.go +++ b/kv/buffer_store.go @@ -74,26 +74,26 @@ func (s *BufferStore) Get(k Key) ([]byte, error) { return val, nil } -// Seek implements the Retriever interface. -func (s *BufferStore) Seek(k Key) (Iterator, error) { - bufferIt, err := s.MemBuffer.Seek(k) +// Iter implements the Retriever interface. +func (s *BufferStore) Iter(k Key, upperBound Key) (Iterator, error) { + bufferIt, err := s.MemBuffer.Iter(k, upperBound) if err != nil { return nil, errors.Trace(err) } - retrieverIt, err := s.r.Seek(k) + retrieverIt, err := s.r.Iter(k, upperBound) if err != nil { return nil, errors.Trace(err) } return NewUnionIter(bufferIt, retrieverIt, false) } -// SeekReverse implements the Retriever interface. -func (s *BufferStore) SeekReverse(k Key) (Iterator, error) { - bufferIt, err := s.MemBuffer.SeekReverse(k) +// IterReverse implements the Retriever interface. +func (s *BufferStore) IterReverse(k Key) (Iterator, error) { + bufferIt, err := s.MemBuffer.IterReverse(k) if err != nil { return nil, errors.Trace(err) } - retrieverIt, err := s.r.SeekReverse(k) + retrieverIt, err := s.r.IterReverse(k) if err != nil { return nil, errors.Trace(err) } diff --git a/kv/buffer_store_test.go b/kv/buffer_store_test.go index af84a9294cd24..1af716011c2a4 100644 --- a/kv/buffer_store_test.go +++ b/kv/buffer_store_test.go @@ -53,7 +53,7 @@ func (s testBufferStoreSuite) TestSaveTo(c *C) { err := bs.SaveTo(mutator) c.Check(err, IsNil) - iter, err := mutator.Seek(nil) + iter, err := mutator.Iter(nil, nil) c.Check(err, IsNil) for iter.Valid() { cmp := bytes.Compare(iter.Key(), iter.Value()) diff --git a/kv/kv.go b/kv/kv.go index 1c9230ed65a6a..01ed6a8556eee 100644 --- a/kv/kv.go +++ b/kv/kv.go @@ -82,15 +82,17 @@ type Retriever interface { // Get gets the value for key k from kv store. // If corresponding kv pair does not exist, it returns nil and ErrNotExist. Get(k Key) ([]byte, error) - // Seek creates an Iterator positioned on the first entry that k <= entry's key. + // Iter creates an Iterator positioned on the first entry that k <= entry's key. // If such entry is not found, it returns an invalid Iterator with no error. + // It yields only keys that < upperBound. If upperBound is nil, it means the upperBound is unbounded. // The Iterator must be Closed after use. - Seek(k Key) (Iterator, error) + Iter(k Key, upperBound Key) (Iterator, error) - // SeekReverse creates a reversed Iterator positioned on the first entry which key is less than k. + // IterReverse creates a reversed Iterator positioned on the first entry which key is less than k. // The returned iterator will iterate from greater key to smaller key. // If k is nil, the returned iterator will be positioned at the last key. - SeekReverse(k Key) (Iterator, error) + // TODO: Add lower bound limit + IterReverse(k Key) (Iterator, error) } // Mutator is the interface wraps the basic Set and Delete methods. diff --git a/kv/mem_buffer_test.go b/kv/mem_buffer_test.go index 92807b528da2d..e7ec5a1f4f9e6 100644 --- a/kv/mem_buffer_test.go +++ b/kv/mem_buffer_test.go @@ -76,7 +76,7 @@ func valToStr(c *C, iter Iterator) string { func checkNewIterator(c *C, buffer MemBuffer) { for i := startIndex; i < testCount; i++ { val := encodeInt(i * indexStep) - iter, err := buffer.Seek(val) + iter, err := buffer.Iter(val, nil) c.Assert(err, IsNil) c.Assert([]byte(iter.Key()), BytesEquals, val) c.Assert(decodeInt([]byte(valToStr(c, iter))), Equals, i*indexStep) @@ -86,7 +86,7 @@ func checkNewIterator(c *C, buffer MemBuffer) { // Test iterator Next() for i := startIndex; i < testCount-1; i++ { val := encodeInt(i * indexStep) - iter, err := buffer.Seek(val) + iter, err := buffer.Iter(val, nil) c.Assert(err, IsNil) c.Assert([]byte(iter.Key()), BytesEquals, val) c.Assert(valToStr(c, iter), Equals, string(val)) @@ -102,7 +102,7 @@ func checkNewIterator(c *C, buffer MemBuffer) { } // Non exist and beyond maximum seek test - iter, err := buffer.Seek(encodeInt(testCount * indexStep)) + iter, err := buffer.Iter(encodeInt(testCount*indexStep), nil) c.Assert(err, IsNil) c.Assert(iter.Valid(), IsFalse) @@ -110,7 +110,7 @@ func checkNewIterator(c *C, buffer MemBuffer) { // it returns the smallest key that larger than the one we are seeking inBetween := encodeInt((testCount-1)*indexStep - 1) last := encodeInt((testCount - 1) * indexStep) - iter, err = buffer.Seek(inBetween) + iter, err = buffer.Iter(inBetween, nil) c.Assert(err, IsNil) c.Assert(iter.Valid(), IsTrue) c.Assert([]byte(iter.Key()), Not(BytesEquals), inBetween) @@ -140,7 +140,7 @@ func (s *testKVSuite) TestNewIterator(c *C) { defer testleak.AfterTest(c)() for _, buffer := range s.bs { // should be invalid - iter, err := buffer.Seek(nil) + iter, err := buffer.Iter(nil, nil) c.Assert(err, IsNil) c.Assert(iter.Valid(), IsFalse) @@ -155,7 +155,7 @@ func (s *testKVSuite) TestIterNextUntil(c *C) { buffer := NewMemDbBuffer(DefaultTxnMembufCap) insertData(c, buffer) - iter, err := buffer.Seek(nil) + iter, err := buffer.Iter(nil, nil) c.Assert(err, IsNil) err = NextUntil(iter, func(k Key) bool { @@ -168,7 +168,7 @@ func (s *testKVSuite) TestIterNextUntil(c *C) { func (s *testKVSuite) TestBasicNewIterator(c *C) { defer testleak.AfterTest(c)() for _, buffer := range s.bs { - it, err := buffer.Seek([]byte("2")) + it, err := buffer.Iter([]byte("2"), nil) c.Assert(err, IsNil) c.Assert(it.Valid(), IsFalse) } @@ -193,7 +193,7 @@ func (s *testKVSuite) TestNewIteratorMin(c *C) { } cnt := 0 - it, err := buffer.Seek(nil) + it, err := buffer.Iter(nil, nil) c.Assert(err, IsNil) for it.Valid() { cnt++ @@ -201,7 +201,7 @@ func (s *testKVSuite) TestNewIteratorMin(c *C) { } c.Assert(cnt, Equals, 6) - it, err = buffer.Seek([]byte("DATA_test_main_db_tbl_tbl_test_record__00000000000000000000")) + it, err = buffer.Iter([]byte("DATA_test_main_db_tbl_tbl_test_record__00000000000000000000"), nil) c.Assert(err, IsNil) c.Assert(string(it.Key()), Equals, "DATA_test_main_db_tbl_tbl_test_record__00000000000000000001") } @@ -294,7 +294,7 @@ func benchIterator(b *testing.B, buffer MemBuffer) { } b.ResetTimer() for i := 0; i < b.N; i++ { - iter, err := buffer.Seek(nil) + iter, err := buffer.Iter(nil, nil) if err != nil { b.Error(err) } diff --git a/kv/memdb_buffer.go b/kv/memdb_buffer.go index a4aaf7496ce0f..9a57e2cfe16fc 100644 --- a/kv/memdb_buffer.go +++ b/kv/memdb_buffer.go @@ -50,14 +50,10 @@ func NewMemDbBuffer(cap int) MemBuffer { } } -// Seek creates an Iterator. -func (m *memDbBuffer) Seek(k Key) (Iterator, error) { - var i Iterator - if k == nil { - i = &memDbIter{iter: m.db.NewIterator(&util.Range{}), reverse: false} - } else { - i = &memDbIter{iter: m.db.NewIterator(&util.Range{Start: []byte(k)}), reverse: false} - } +// Iter creates an Iterator. +func (m *memDbBuffer) Iter(k Key, upperBound Key) (Iterator, error) { + i := &memDbIter{iter: m.db.NewIterator(&util.Range{Start: []byte(k), Limit: []byte(upperBound)}), reverse: false} + err := i.Next() if err != nil { return nil, errors.Trace(err) @@ -69,7 +65,7 @@ func (m *memDbBuffer) SetCap(cap int) { } -func (m *memDbBuffer) SeekReverse(k Key) (Iterator, error) { +func (m *memDbBuffer) IterReverse(k Key) (Iterator, error) { var i *memDbIter if k == nil { i = &memDbIter{iter: m.db.NewIterator(&util.Range{}), reverse: true} @@ -161,7 +157,7 @@ func (i *memDbIter) Close() { // WalkMemBuffer iterates all buffered kv pairs in memBuf func WalkMemBuffer(memBuf MemBuffer, f func(k Key, v []byte) error) error { - iter, err := memBuf.Seek(nil) + iter, err := memBuf.Iter(nil, nil) if err != nil { return errors.Trace(err) } diff --git a/kv/mock.go b/kv/mock.go index 9fb8a0559c33d..6fc5a1ed52508 100644 --- a/kv/mock.go +++ b/kv/mock.go @@ -68,11 +68,11 @@ func (t *mockTxn) Get(k Key) ([]byte, error) { return nil, nil } -func (t *mockTxn) Seek(k Key) (Iterator, error) { +func (t *mockTxn) Iter(k Key, upperBound Key) (Iterator, error) { return nil, nil } -func (t *mockTxn) SeekReverse(k Key) (Iterator, error) { +func (t *mockTxn) IterReverse(k Key) (Iterator, error) { return nil, nil } @@ -211,10 +211,10 @@ func (s *mockSnapshot) BatchGet(keys []Key) (map[string][]byte, error) { return m, nil } -func (s *mockSnapshot) Seek(k Key) (Iterator, error) { - return s.store.Seek(k) +func (s *mockSnapshot) Iter(k Key, upperBound Key) (Iterator, error) { + return s.store.Iter(k, upperBound) } -func (s *mockSnapshot) SeekReverse(k Key) (Iterator, error) { - return s.store.SeekReverse(k) +func (s *mockSnapshot) IterReverse(k Key) (Iterator, error) { + return s.store.IterReverse(k) } diff --git a/kv/mock_test.go b/kv/mock_test.go index 93dc59490b4a4..2c1db84cf8a97 100644 --- a/kv/mock_test.go +++ b/kv/mock_test.go @@ -46,8 +46,8 @@ func (s testMockSuite) TestInterface(c *C) { if transaction.IsReadOnly() { transaction.Get(Key("lock")) transaction.Set(Key("lock"), []byte{}) - transaction.Seek(Key("lock")) - transaction.SeekReverse(Key("lock")) + transaction.Iter(Key("lock"), nil) + transaction.IterReverse(Key("lock")) } transaction.Commit(context.Background()) diff --git a/kv/union_store.go b/kv/union_store.go index 6e3111f3ca240..82e3a96223334 100644 --- a/kv/union_store.go +++ b/kv/union_store.go @@ -127,18 +127,18 @@ func (lmb *lazyMemBuffer) Delete(k Key) error { return lmb.mb.Delete(k) } -func (lmb *lazyMemBuffer) Seek(k Key) (Iterator, error) { +func (lmb *lazyMemBuffer) Iter(k Key, upperBound Key) (Iterator, error) { if lmb.mb == nil { return invalidIterator{}, nil } - return lmb.mb.Seek(k) + return lmb.mb.Iter(k, upperBound) } -func (lmb *lazyMemBuffer) SeekReverse(k Key) (Iterator, error) { +func (lmb *lazyMemBuffer) IterReverse(k Key) (Iterator, error) { if lmb.mb == nil { return invalidIterator{}, nil } - return lmb.mb.SeekReverse(k) + return lmb.mb.IterReverse(k) } func (lmb *lazyMemBuffer) Size() int { diff --git a/kv/union_store_test.go b/kv/union_store_test.go index 6241e853582de..2b06b2f39d605 100644 --- a/kv/union_store_test.go +++ b/kv/union_store_test.go @@ -63,46 +63,46 @@ func (s *testUnionStoreSuite) TestSeek(c *C) { s.store.Set([]byte("2"), []byte("2")) s.store.Set([]byte("3"), []byte("3")) - iter, err := s.us.Seek(nil) + iter, err := s.us.Iter(nil, nil) c.Assert(err, IsNil) checkIterator(c, iter, [][]byte{[]byte("1"), []byte("2"), []byte("3")}, [][]byte{[]byte("1"), []byte("2"), []byte("3")}) - iter, err = s.us.Seek([]byte("2")) + iter, err = s.us.Iter([]byte("2"), nil) c.Assert(err, IsNil) checkIterator(c, iter, [][]byte{[]byte("2"), []byte("3")}, [][]byte{[]byte("2"), []byte("3")}) s.us.Set([]byte("4"), []byte("4")) - iter, err = s.us.Seek([]byte("2")) + iter, err = s.us.Iter([]byte("2"), nil) c.Assert(err, IsNil) checkIterator(c, iter, [][]byte{[]byte("2"), []byte("3"), []byte("4")}, [][]byte{[]byte("2"), []byte("3"), []byte("4")}) s.us.Delete([]byte("3")) - iter, err = s.us.Seek([]byte("2")) + iter, err = s.us.Iter([]byte("2"), nil) c.Assert(err, IsNil) checkIterator(c, iter, [][]byte{[]byte("2"), []byte("4")}, [][]byte{[]byte("2"), []byte("4")}) } -func (s *testUnionStoreSuite) TestSeekReverse(c *C) { +func (s *testUnionStoreSuite) TestIterReverse(c *C) { defer testleak.AfterTest(c)() s.store.Set([]byte("1"), []byte("1")) s.store.Set([]byte("2"), []byte("2")) s.store.Set([]byte("3"), []byte("3")) - iter, err := s.us.SeekReverse(nil) + iter, err := s.us.IterReverse(nil) c.Assert(err, IsNil) checkIterator(c, iter, [][]byte{[]byte("3"), []byte("2"), []byte("1")}, [][]byte{[]byte("3"), []byte("2"), []byte("1")}) - iter, err = s.us.SeekReverse([]byte("3")) + iter, err = s.us.IterReverse([]byte("3")) c.Assert(err, IsNil) checkIterator(c, iter, [][]byte{[]byte("2"), []byte("1")}, [][]byte{[]byte("2"), []byte("1")}) s.us.Set([]byte("0"), []byte("0")) - iter, err = s.us.SeekReverse([]byte("3")) + iter, err = s.us.IterReverse([]byte("3")) c.Assert(err, IsNil) checkIterator(c, iter, [][]byte{[]byte("2"), []byte("1"), []byte("0")}, [][]byte{[]byte("2"), []byte("1"), []byte("0")}) s.us.Delete([]byte("1")) - iter, err = s.us.SeekReverse([]byte("3")) + iter, err = s.us.IterReverse([]byte("3")) c.Assert(err, IsNil) checkIterator(c, iter, [][]byte{[]byte("2"), []byte("0")}, [][]byte{[]byte("2"), []byte("0")}) } diff --git a/session/txn.go b/session/txn.go index 5b37b63ad29f3..6e391335fc966 100644 --- a/session/txn.go +++ b/session/txn.go @@ -159,26 +159,26 @@ func (st *TxnState) Delete(k kv.Key) error { return st.buf.Delete(k) } -// Seek overrides the Transaction interface. -func (st *TxnState) Seek(k kv.Key) (kv.Iterator, error) { - bufferIt, err := st.buf.Seek(k) +// Iter overrides the Transaction interface. +func (st *TxnState) Iter(k kv.Key, upperBound kv.Key) (kv.Iterator, error) { + bufferIt, err := st.buf.Iter(k, upperBound) if err != nil { return nil, errors.Trace(err) } - retrieverIt, err := st.Transaction.Seek(k) + retrieverIt, err := st.Transaction.Iter(k, upperBound) if err != nil { return nil, errors.Trace(err) } return kv.NewUnionIter(bufferIt, retrieverIt, false) } -// SeekReverse overrides the Transaction interface. -func (st *TxnState) SeekReverse(k kv.Key) (kv.Iterator, error) { - bufferIt, err := st.buf.SeekReverse(k) +// IterReverse overrides the Transaction interface. +func (st *TxnState) IterReverse(k kv.Key) (kv.Iterator, error) { + bufferIt, err := st.buf.IterReverse(k) if err != nil { return nil, errors.Trace(err) } - retrieverIt, err := st.Transaction.SeekReverse(k) + retrieverIt, err := st.Transaction.IterReverse(k) if err != nil { return nil, errors.Trace(err) } diff --git a/store/mockstore/mocktikv/mock_tikv_test.go b/store/mockstore/mocktikv/mock_tikv_test.go index 807a4267134ba..a4af86f037a28 100644 --- a/store/mockstore/mocktikv/mock_tikv_test.go +++ b/store/mockstore/mocktikv/mock_tikv_test.go @@ -119,7 +119,11 @@ func (s *testMockTiKVSuite) mustDeleteOK(c *C, key string, startTS, commitTS uin } func (s *testMockTiKVSuite) mustScanOK(c *C, start string, limit int, ts uint64, expect ...string) { - pairs := s.store.Scan([]byte(start), nil, limit, ts, kvrpcpb.IsolationLevel_SI) + s.mustRangeScanOK(c, start, "", limit, ts, expect...) +} + +func (s *testMockTiKVSuite) mustRangeScanOK(c *C, start, end string, limit int, ts uint64, expect ...string) { + pairs := s.store.Scan([]byte(start), []byte(end), limit, ts, kvrpcpb.IsolationLevel_SI) c.Assert(len(pairs)*2, Equals, len(expect)) for i := 0; i < len(pairs); i++ { c.Assert(pairs[i].Err, IsNil) @@ -129,7 +133,11 @@ func (s *testMockTiKVSuite) mustScanOK(c *C, start string, limit int, ts uint64, } func (s *testMockTiKVSuite) mustReverseScanOK(c *C, end string, limit int, ts uint64, expect ...string) { - pairs := s.store.ReverseScan(nil, []byte(end), limit, ts, kvrpcpb.IsolationLevel_SI) + s.mustRangeReverseScanOK(c, "", end, limit, ts, expect...) +} + +func (s *testMockTiKVSuite) mustRangeReverseScanOK(c *C, start, end string, limit int, ts uint64, expect ...string) { + pairs := s.store.ReverseScan([]byte(start), []byte(end), limit, ts, kvrpcpb.IsolationLevel_SI) c.Assert(len(pairs)*2, Equals, len(expect)) for i := 0; i < len(pairs); i++ { c.Assert(pairs[i].Err, IsNil) @@ -249,6 +257,9 @@ func (s *testMockTiKVSuite) TestReverseScan(c *C) { s.mustReverseScanOK(c, "C\x00", 3, 10, "C", "C10", "A", "A10") s.mustReverseScanOK(c, "C\x00", 4, 10, "C", "C10", "A", "A10") s.mustReverseScanOK(c, "B", 1, 10, "A", "A10") + s.mustRangeReverseScanOK(c, "", "E", 5, 10, "C", "C10", "A", "A10") + s.mustRangeReverseScanOK(c, "", "C\x00", 5, 10, "C", "C10", "A", "A10") + s.mustRangeReverseScanOK(c, "A\x00", "C", 5, 10) } checkV10() @@ -260,6 +271,9 @@ func (s *testMockTiKVSuite) TestReverseScan(c *C) { s.mustReverseScanOK(c, "Z", 5, 20, "E", "E10", "D", "D20", "C", "C10", "B", "B20", "A", "A10") s.mustReverseScanOK(c, "C\x00", 5, 20, "C", "C10", "B", "B20", "A", "A10") s.mustReverseScanOK(c, "A\x00", 1, 20, "A", "A10") + s.mustRangeReverseScanOK(c, "B", "D", 5, 20, "C", "C10", "B", "B20") + s.mustRangeReverseScanOK(c, "B", "D\x00", 5, 20, "D", "D20", "C", "C10", "B", "B20") + s.mustRangeReverseScanOK(c, "B\x00", "D\x00", 5, 20, "D", "D20", "C", "C10") } checkV10() checkV20() @@ -308,6 +322,9 @@ func (s *testMockTiKVSuite) TestScan(c *C) { s.mustScanOK(c, "A\x00", 3, 10, "C", "C10", "E", "E10") s.mustScanOK(c, "C", 4, 10, "C", "C10", "E", "E10") s.mustScanOK(c, "F", 1, 10) + s.mustRangeScanOK(c, "", "E", 5, 10, "A", "A10", "C", "C10") + s.mustRangeScanOK(c, "", "C\x00", 5, 10, "A", "A10", "C", "C10") + s.mustRangeScanOK(c, "A\x00", "C", 5, 10) } checkV10() @@ -319,6 +336,9 @@ func (s *testMockTiKVSuite) TestScan(c *C) { s.mustScanOK(c, "", 5, 20, "A", "A10", "B", "B20", "C", "C10", "D", "D20", "E", "E10") s.mustScanOK(c, "C", 5, 20, "C", "C10", "D", "D20", "E", "E10") s.mustScanOK(c, "D\x00", 1, 20, "E", "E10") + s.mustRangeScanOK(c, "B", "D", 5, 20, "B", "B20", "C", "C10") + s.mustRangeScanOK(c, "B", "D\x00", 5, 20, "B", "B20", "C", "C10", "D", "D20") + s.mustRangeScanOK(c, "B\x00", "D\x00", 5, 20, "C", "C10", "D", "D20") } checkV10() checkV20() diff --git a/store/mockstore/mocktikv/rpc.go b/store/mockstore/mocktikv/rpc.go index 93a24331d9d9d..8a51bce389ccb 100644 --- a/store/mockstore/mocktikv/rpc.go +++ b/store/mockstore/mocktikv/rpc.go @@ -229,7 +229,11 @@ func (h *rpcHandler) handleKvScan(req *kvrpcpb.ScanRequest) *kvrpcpb.ScanRespons if !h.checkKeyInRegion(req.GetStartKey()) { panic("KvScan: startKey not in region") } - pairs := h.mvccStore.Scan(req.GetStartKey(), h.endKey, int(req.GetLimit()), req.GetVersion(), h.isolationLevel) + endKey := h.endKey + if len(req.EndKey) > 0 && (len(endKey) == 0 || bytes.Compare(req.EndKey, endKey) < 0) { + endKey = req.EndKey + } + pairs := h.mvccStore.Scan(req.GetStartKey(), endKey, int(req.GetLimit()), req.GetVersion(), h.isolationLevel) return &kvrpcpb.ScanResponse{ Pairs: convertToPbPairs(pairs), } diff --git a/store/store_test.go b/store/store_test.go index b69f92dbb7014..95ef4c131b4e9 100644 --- a/store/store_test.go +++ b/store/store_test.go @@ -97,7 +97,7 @@ func valToStr(c *C, iter kv.Iterator) string { func checkSeek(c *C, txn kv.Transaction) { for i := startIndex; i < testCount; i++ { val := encodeInt(i * indexStep) - iter, err := txn.Seek(val) + iter, err := txn.Iter(val, nil) c.Assert(err, IsNil) c.Assert([]byte(iter.Key()), BytesEquals, val) c.Assert(decodeInt([]byte(valToStr(c, iter))), Equals, i*indexStep) @@ -107,7 +107,7 @@ func checkSeek(c *C, txn kv.Transaction) { // Test iterator Next() for i := startIndex; i < testCount-1; i++ { val := encodeInt(i * indexStep) - iter, err := txn.Seek(val) + iter, err := txn.Iter(val, nil) c.Assert(err, IsNil) c.Assert([]byte(iter.Key()), BytesEquals, val) c.Assert(valToStr(c, iter), Equals, string(val)) @@ -123,7 +123,7 @@ func checkSeek(c *C, txn kv.Transaction) { } // Non exist and beyond maximum seek test - iter, err := txn.Seek(encodeInt(testCount * indexStep)) + iter, err := txn.Iter(encodeInt(testCount*indexStep), nil) c.Assert(err, IsNil) c.Assert(iter.Valid(), IsFalse) @@ -131,7 +131,7 @@ func checkSeek(c *C, txn kv.Transaction) { // it returns the smallest key that larger than the one we are seeking inBetween := encodeInt((testCount-1)*indexStep - 1) last := encodeInt((testCount - 1) * indexStep) - iter, err = txn.Seek(inBetween) + iter, err = txn.Iter(inBetween, nil) c.Assert(err, IsNil) c.Assert(iter.Valid(), IsTrue) c.Assert([]byte(iter.Key()), Not(BytesEquals), inBetween) @@ -278,7 +278,7 @@ func (s *testKVSuite) TestDelete2(c *C) { txn, err = s.s.Begin() c.Assert(err, IsNil) - it, err := txn.Seek([]byte("DATA_test_tbl_department_record__0000000001_0003")) + it, err := txn.Iter([]byte("DATA_test_tbl_department_record__0000000001_0003"), nil) c.Assert(err, IsNil) for it.Valid() { err = txn.Delete([]byte(it.Key())) @@ -290,7 +290,7 @@ func (s *testKVSuite) TestDelete2(c *C) { txn, err = s.s.Begin() c.Assert(err, IsNil) - it, _ = txn.Seek([]byte("DATA_test_tbl_department_record__000000000")) + it, _ = txn.Iter([]byte("DATA_test_tbl_department_record__000000000"), nil) c.Assert(it.Valid(), IsFalse) txn.Commit(context.Background()) } @@ -312,7 +312,7 @@ func (s *testKVSuite) TestBasicSeek(c *C) { c.Assert(err, IsNil) defer txn.Commit(context.Background()) - it, err := txn.Seek([]byte("2")) + it, err := txn.Iter([]byte("2"), nil) c.Assert(err, IsNil) c.Assert(it.Valid(), Equals, false) txn.Delete([]byte("1")) @@ -333,30 +333,30 @@ func (s *testKVSuite) TestBasicTable(c *C) { err = txn.Set([]byte("1"), []byte("1")) c.Assert(err, IsNil) - it, err := txn.Seek([]byte("0")) + it, err := txn.Iter([]byte("0"), nil) c.Assert(err, IsNil) c.Assert(string(it.Key()), Equals, "1") err = txn.Set([]byte("0"), []byte("0")) c.Assert(err, IsNil) - it, err = txn.Seek([]byte("0")) + it, err = txn.Iter([]byte("0"), nil) c.Assert(err, IsNil) c.Assert(string(it.Key()), Equals, "0") err = txn.Delete([]byte("0")) c.Assert(err, IsNil) txn.Delete([]byte("1")) - it, err = txn.Seek([]byte("0")) + it, err = txn.Iter([]byte("0"), nil) c.Assert(err, IsNil) c.Assert(string(it.Key()), Equals, "2") err = txn.Delete([]byte("3")) c.Assert(err, IsNil) - it, err = txn.Seek([]byte("2")) + it, err = txn.Iter([]byte("2"), nil) c.Assert(err, IsNil) c.Assert(string(it.Key()), Equals, "2") - it, err = txn.Seek([]byte("3")) + it, err = txn.Iter([]byte("3"), nil) c.Assert(err, IsNil) c.Assert(string(it.Key()), Equals, "4") err = txn.Delete([]byte("2")) @@ -411,13 +411,14 @@ func (s *testKVSuite) TestSeekMin(c *C) { txn.Set([]byte(row.key), []byte(row.value)) } - it, err := txn.Seek(nil) + it, err := txn.Iter(nil, nil) + c.Assert(err, IsNil) for it.Valid() { fmt.Printf("%s, %s\n", it.Key(), it.Value()) it.Next() } - it, err = txn.Seek([]byte("DATA_test_main_db_tbl_tbl_test_record__00000000000000000000")) + it, err = txn.Iter([]byte("DATA_test_main_db_tbl_tbl_test_record__00000000000000000000"), nil) c.Assert(err, IsNil) c.Assert(string(it.Key()), Equals, "DATA_test_main_db_tbl_tbl_test_record__00000000000000000001") diff --git a/store/tikv/delete_range_test.go b/store/tikv/delete_range_test.go index 7864eb0954878..ee0b3c6c73126 100644 --- a/store/tikv/delete_range_test.go +++ b/store/tikv/delete_range_test.go @@ -50,7 +50,7 @@ func (s *testDeleteRangeSuite) TearDownTest(c *C) { func (s *testDeleteRangeSuite) checkData(c *C, expectedData map[string]string) { txn, err := s.store.Begin() c.Assert(err, IsNil) - it, err := txn.Seek([]byte("a")) + it, err := txn.Iter([]byte("a"), nil) c.Assert(err, IsNil) // Scan all data and save into a map diff --git a/store/tikv/lock_test.go b/store/tikv/lock_test.go index 20bedba474f10..31e0c4597b121 100644 --- a/store/tikv/lock_test.go +++ b/store/tikv/lock_test.go @@ -116,7 +116,7 @@ func (s *testLockSuite) TestScanLockResolveWithSeek(c *C) { txn, err := s.store.Begin() c.Assert(err, IsNil) - iter, err := txn.Seek([]byte("a")) + iter, err := txn.Iter([]byte("a"), nil) c.Assert(err, IsNil) for ch := byte('a'); ch <= byte('z'); ch++ { c.Assert(iter.Valid(), IsTrue) @@ -133,7 +133,7 @@ func (s *testLockSuite) TestScanLockResolveWithSeekKeyOnly(c *C) { txn, err := s.store.Begin() c.Assert(err, IsNil) txn.SetOption(kv.KeyOnly, true) - iter, err := txn.Seek([]byte("a")) + iter, err := txn.Iter([]byte("a"), nil) c.Assert(err, IsNil) for ch := byte('a'); ch <= byte('z'); ch++ { c.Assert(iter.Valid(), IsTrue) diff --git a/store/tikv/safepoint_test.go b/store/tikv/safepoint_test.go index 29b640a1d48fd..76e3449d9a95f 100644 --- a/store/tikv/safepoint_test.go +++ b/store/tikv/safepoint_test.go @@ -100,7 +100,7 @@ func (s *testSafePointSuite) TestSafePoint(c *C) { s.waitUntilErrorPlugIn(txn3.startTS) - _, seekerr := txn3.Seek(encodeKey(s.prefix, "")) + _, seekerr := txn3.Iter(encodeKey(s.prefix, ""), nil) c.Assert(seekerr, NotNil) isFallBehind = terror.ErrorEqual(errors.Cause(geterr2), ErrGCTooEarly) isMayFallBehind = terror.ErrorEqual(errors.Cause(geterr2), ErrPDServerTimeout.GenWithStackByArgs("start timestamp may fall behind safe point")) diff --git a/store/tikv/scan.go b/store/tikv/scan.go index d5c140f6a7e3f..c3d5c555ba37b 100644 --- a/store/tikv/scan.go +++ b/store/tikv/scan.go @@ -30,10 +30,11 @@ type Scanner struct { cache []*pb.KvPair idx int nextStartKey []byte + endKey []byte eof bool } -func newScanner(snapshot *tikvSnapshot, startKey []byte, batchSize int) (*Scanner, error) { +func newScanner(snapshot *tikvSnapshot, startKey []byte, endKey []byte, batchSize int) (*Scanner, error) { // It must be > 1. Otherwise scanner won't skipFirst. if batchSize <= 1 { batchSize = scanBatchSize @@ -43,6 +44,7 @@ func newScanner(snapshot *tikvSnapshot, startKey []byte, batchSize int) (*Scanne batchSize: batchSize, valid: true, nextStartKey: startKey, + endKey: endKey, } err := scanner.Next() if kv.IsErrNotFound(err) { @@ -147,6 +149,7 @@ func (s *Scanner) getData(bo *Backoffer) error { Type: tikvrpc.CmdScan, Scan: &pb.ScanRequest{ StartKey: s.nextStartKey, + EndKey: s.endKey, Limit: uint32(s.batchSize), Version: s.startTS(), KeyOnly: s.snapshot.keyOnly, @@ -199,7 +202,7 @@ func (s *Scanner) getData(bo *Backoffer) error { // No more data in current Region. Next getData() starts // from current Region's endKey. s.nextStartKey = loc.EndKey - if len(loc.EndKey) == 0 { + if len(loc.EndKey) == 0 || (len(s.endKey) > 0 && kv.Key(s.nextStartKey).Cmp(kv.Key(s.endKey)) >= 0) { // Current Region is the last one. s.eof = true } diff --git a/store/tikv/scan_mock_test.go b/store/tikv/scan_mock_test.go index af453a985ff32..94b720314f2bd 100644 --- a/store/tikv/scan_mock_test.go +++ b/store/tikv/scan_mock_test.go @@ -41,11 +41,19 @@ func (s *testScanMockSuite) TestScanMultipleRegions(c *C) { txn, err = store.Begin() c.Assert(err, IsNil) snapshot := newTiKVSnapshot(store, kv.Version{Ver: txn.StartTS()}) - scanner, err := newScanner(snapshot, []byte("a"), 10) + scanner, err := newScanner(snapshot, []byte("a"), nil, 10) c.Assert(err, IsNil) for ch := byte('a'); ch <= byte('z'); ch++ { c.Assert([]byte{ch}, BytesEquals, []byte(scanner.Key())) c.Assert(scanner.Next(), IsNil) } c.Assert(scanner.Valid(), IsFalse) + + scanner, err = newScanner(snapshot, []byte("a"), []byte("i"), 10) + c.Assert(err, IsNil) + for ch := byte('a'); ch <= byte('h'); ch++ { + c.Assert([]byte{ch}, BytesEquals, []byte(scanner.Key())) + c.Assert(scanner.Next(), IsNil) + } + c.Assert(scanner.Valid(), IsFalse) } diff --git a/store/tikv/scan_test.go b/store/tikv/scan_test.go index e4897bc2de2b7..ff9184d0c0323 100644 --- a/store/tikv/scan_test.go +++ b/store/tikv/scan_test.go @@ -40,7 +40,7 @@ func (s *testScanSuite) SetUpSuite(c *C) { func (s *testScanSuite) TearDownSuite(c *C) { txn := s.beginTxn(c) - scanner, err := txn.Seek(encodeKey(s.prefix, "")) + scanner, err := txn.Iter(encodeKey(s.prefix, ""), nil) c.Assert(err, IsNil) c.Assert(scanner, NotNil) for scanner.Valid() { @@ -62,7 +62,25 @@ func (s *testScanSuite) beginTxn(c *C) *tikvTxn { return txn.(*tikvTxn) } -func (s *testScanSuite) TestSeek(c *C) { +func (s *testScanSuite) TestScan(c *C) { + check := func(c *C, scan kv.Iterator, rowNum int, keyOnly bool) { + for i := 0; i < rowNum; i++ { + k := scan.Key() + c.Assert([]byte(k), BytesEquals, encodeKey(s.prefix, s08d("key", i))) + if !keyOnly { + v := scan.Value() + c.Assert(v, BytesEquals, valueBytes(i)) + } + // Because newScan return first item without calling scan.Next() just like go-hbase, + // for-loop count will decrease 1. + if i < rowNum-1 { + scan.Next() + } + } + scan.Next() + c.Assert(scan.Valid(), IsFalse) + } + for _, rowNum := range s.rowNums { txn := s.beginTxn(c) for i := 0; i < rowNum; i++ { @@ -76,57 +94,35 @@ func (s *testScanSuite) TestSeek(c *C) { val, err := txn2.Get(encodeKey(s.prefix, s08d("key", 0))) c.Assert(err, IsNil) c.Assert(val, BytesEquals, valueBytes(0)) - scan, err := txn2.Seek(encodeKey(s.prefix, "")) + // Test scan without upperBound + scan, err := txn2.Iter(encodeKey(s.prefix, ""), nil) c.Assert(err, IsNil) - - for i := 0; i < rowNum; i++ { - k := scan.Key() - c.Assert([]byte(k), BytesEquals, encodeKey(s.prefix, s08d("key", i))) - v := scan.Value() - c.Assert(v, BytesEquals, valueBytes(i)) - // Because newScan return first item without calling scan.Next() just like go-hbase, - // for-loop count will decrease 1. - if i < rowNum-1 { - scan.Next() - } - } - scan.Next() - c.Assert(scan.Valid(), IsFalse) + check(c, scan, rowNum, false) + // Test scan with upperBound + upperBound := rowNum / 2 + scan, err = txn2.Iter(encodeKey(s.prefix, ""), encodeKey(s.prefix, s08d("key", upperBound))) + c.Assert(err, IsNil) + check(c, scan, upperBound, false) txn3 := s.beginTxn(c) txn3.SetOption(kv.KeyOnly, true) - scan, err = txn3.Seek(encodeKey(s.prefix, "")) + // Test scan without upper bound + scan, err = txn3.Iter(encodeKey(s.prefix, ""), nil) c.Assert(err, IsNil) - - for i := 0; i < rowNum; i++ { - k := scan.Key() - c.Assert([]byte(k), BytesEquals, encodeKey(s.prefix, s08d("key", i))) - // Because newScan return first item without calling scan.Next() just like go-hbase, - // for-loop count will decrease 1. - if i < rowNum-1 { - scan.Next() - } - } - scan.Next() - c.Assert(scan.Valid(), IsFalse) + check(c, scan, rowNum, true) + // test scan with upper bound + scan, err = txn3.Iter(encodeKey(s.prefix, ""), encodeKey(s.prefix, s08d("key", upperBound))) + c.Assert(err, IsNil) + check(c, scan, upperBound, true) // Restore KeyOnly to false txn3.SetOption(kv.KeyOnly, false) - scan, err = txn3.Seek(encodeKey(s.prefix, "")) + scan, err = txn3.Iter(encodeKey(s.prefix, ""), nil) c.Assert(err, IsNil) - - for i := 0; i < rowNum; i++ { - k := scan.Key() - c.Assert([]byte(k), BytesEquals, encodeKey(s.prefix, s08d("key", i))) - v := scan.Value() - c.Assert(v, BytesEquals, valueBytes(i)) - // Because newScan return first item without calling scan.Next() just like go-hbase, - // for-loop count will decrease 1. - if i < rowNum-1 { - scan.Next() - } - } - scan.Next() - c.Assert(scan.Valid(), IsFalse) + check(c, scan, rowNum, true) + // test scan with upper bound + scan, err = txn3.Iter(encodeKey(s.prefix, ""), encodeKey(s.prefix, s08d("key", upperBound))) + c.Assert(err, IsNil) + check(c, scan, upperBound, true) } } diff --git a/store/tikv/snapshot.go b/store/tikv/snapshot.go index c4c14e984e57d..51eaa4a89b216 100644 --- a/store/tikv/snapshot.go +++ b/store/tikv/snapshot.go @@ -280,14 +280,14 @@ func (s *tikvSnapshot) get(bo *Backoffer, k kv.Key) ([]byte, error) { } } -// Seek return a list of key-value pair after `k`. -func (s *tikvSnapshot) Seek(k kv.Key) (kv.Iterator, error) { - scanner, err := newScanner(s, k, scanBatchSize) +// Iter return a list of key-value pair after `k`. +func (s *tikvSnapshot) Iter(k kv.Key, upperBound kv.Key) (kv.Iterator, error) { + scanner, err := newScanner(s, k, upperBound, scanBatchSize) return scanner, errors.Trace(err) } -// SeekReverse creates a reversed Iterator positioned on the first entry which key is less than k. -func (s *tikvSnapshot) SeekReverse(k kv.Key) (kv.Iterator, error) { +// IterReverse creates a reversed Iterator positioned on the first entry which key is less than k. +func (s *tikvSnapshot) IterReverse(k kv.Key) (kv.Iterator, error) { return nil, kv.ErrNotImplemented } diff --git a/store/tikv/snapshot_test.go b/store/tikv/snapshot_test.go index 4ea695f224e4b..61d5da2112863 100644 --- a/store/tikv/snapshot_test.go +++ b/store/tikv/snapshot_test.go @@ -42,7 +42,7 @@ func (s *testSnapshotSuite) SetUpSuite(c *C) { func (s *testSnapshotSuite) TearDownSuite(c *C) { txn := s.beginTxn(c) - scanner, err := txn.Seek(encodeKey(s.prefix, "")) + scanner, err := txn.Iter(encodeKey(s.prefix, ""), nil) c.Assert(err, IsNil) c.Assert(scanner, NotNil) for scanner.Valid() { @@ -70,7 +70,7 @@ func (s *testSnapshotSuite) checkAll(keys []kv.Key, c *C) { m, err := snapshot.BatchGet(keys) c.Assert(err, IsNil) - scan, err := txn.Seek(encodeKey(s.prefix, "")) + scan, err := txn.Iter(encodeKey(s.prefix, ""), nil) c.Assert(err, IsNil) cnt := 0 for scan.Valid() { diff --git a/store/tikv/store_test.go b/store/tikv/store_test.go index 00735eee64a3f..116f4b875748e 100644 --- a/store/tikv/store_test.go +++ b/store/tikv/store_test.go @@ -229,7 +229,7 @@ func (s *testStoreSuite) TestRequestPriority(c *C) { // Cover Seek request. client.priority = pb.CommandPri_High txn.SetOption(kv.Priority, kv.PriorityHigh) - iter, err := txn.Seek([]byte("key")) + iter, err := txn.Iter([]byte("key"), nil) c.Assert(err, IsNil) for iter.Valid() { c.Assert(iter.Next(), IsNil) diff --git a/store/tikv/ticlient_test.go b/store/tikv/ticlient_test.go index 1b4ea24ad5c82..e67b9c7562c57 100644 --- a/store/tikv/ticlient_test.go +++ b/store/tikv/ticlient_test.go @@ -61,7 +61,7 @@ func clearStorage(store kv.Storage) error { if err != nil { return errors.Trace(err) } - iter, err := txn.Seek(nil) + iter, err := txn.Iter(nil, nil) if err != nil { return errors.Trace(err) } @@ -93,7 +93,7 @@ func (s *testTiclientSuite) SetUpSuite(c *C) { func (s *testTiclientSuite) TearDownSuite(c *C) { // Clean all data, or it may pollute other data. txn := s.beginTxn(c) - scanner, err := txn.Seek(encodeKey(s.prefix, "")) + scanner, err := txn.Iter(encodeKey(s.prefix, ""), nil) c.Assert(err, IsNil) c.Assert(scanner, NotNil) for scanner.Valid() { diff --git a/store/tikv/txn.go b/store/tikv/txn.go index 18b7e1a17d31f..1c4464bc49488 100644 --- a/store/tikv/txn.go +++ b/store/tikv/txn.go @@ -115,23 +115,23 @@ func (txn *tikvTxn) String() string { return fmt.Sprintf("%d", txn.StartTS()) } -func (txn *tikvTxn) Seek(k kv.Key) (kv.Iterator, error) { +func (txn *tikvTxn) Iter(k kv.Key, upperBound kv.Key) (kv.Iterator, error) { metrics.TiKVTxnCmdCounter.WithLabelValues("seek").Inc() start := time.Now() defer func() { metrics.TiKVTxnCmdHistogram.WithLabelValues("seek").Observe(time.Since(start).Seconds()) }() - return txn.us.Seek(k) + return txn.us.Iter(k, upperBound) } -// SeekReverse creates a reversed Iterator positioned on the first entry which key is less than k. -func (txn *tikvTxn) SeekReverse(k kv.Key) (kv.Iterator, error) { +// IterReverse creates a reversed Iterator positioned on the first entry which key is less than k. +func (txn *tikvTxn) IterReverse(k kv.Key) (kv.Iterator, error) { metrics.TiKVTxnCmdCounter.WithLabelValues("seek_reverse").Inc() start := time.Now() defer func() { metrics.TiKVTxnCmdHistogram.WithLabelValues("seek_reverse").Observe(time.Since(start).Seconds()) }() - return txn.us.SeekReverse(k) + return txn.us.IterReverse(k) } func (txn *tikvTxn) Delete(k kv.Key) error { diff --git a/structure/hash.go b/structure/hash.go index 8b04016c37bc1..bfa13118cce8c 100644 --- a/structure/hash.go +++ b/structure/hash.go @@ -238,7 +238,7 @@ func (t *TxStructure) HClear(key []byte) error { func (t *TxStructure) iterateHash(key []byte, fn func(k []byte, v []byte) error) error { dataPrefix := t.hashDataKeyPrefix(key) - it, err := t.reader.Seek(dataPrefix) + it, err := t.reader.Iter(dataPrefix, nil) if err != nil { return errors.Trace(err) } diff --git a/table/tables/index.go b/table/tables/index.go index e11993001bfac..c36d55c698cb1 100644 --- a/table/tables/index.go +++ b/table/tables/index.go @@ -240,7 +240,7 @@ func (c *index) Delete(sc *stmtctx.StatementContext, m kv.Mutator, indexedValues // Drop removes the KV index from store. func (c *index) Drop(rm kv.RetrieverMutator) error { - it, err := rm.Seek(c.prefix) + it, err := rm.Iter(c.prefix, nil) if err != nil { return errors.Trace(err) } @@ -270,7 +270,7 @@ func (c *index) Seek(sc *stmtctx.StatementContext, r kv.Retriever, indexedValues return nil, false, errors.Trace(err) } - it, err := r.Seek(key) + it, err := r.Iter(key, nil) if err != nil { return nil, false, errors.Trace(err) } @@ -284,7 +284,7 @@ func (c *index) Seek(sc *stmtctx.StatementContext, r kv.Retriever, indexedValues // SeekFirst returns an iterator which points to the first entry of the KV index. func (c *index) SeekFirst(r kv.Retriever) (iter table.IndexIterator, err error) { - it, err := r.Seek(c.prefix) + it, err := r.Iter(c.prefix, nil) if err != nil { return nil, errors.Trace(err) } diff --git a/table/tables/tables.go b/table/tables/tables.go index 8660f8625e27e..4a75d3f7e84d3 100644 --- a/table/tables/tables.go +++ b/table/tables/tables.go @@ -766,7 +766,7 @@ func (t *tableCommon) buildIndexForRow(ctx sessionctx.Context, rm kv.RetrieverMu // IterRecords implements table.Table IterRecords interface. func (t *tableCommon) IterRecords(ctx sessionctx.Context, startKey kv.Key, cols []*table.Column, fn table.RecordIterFunc) error { - it, err := ctx.Txn().Seek(startKey) + it, err := ctx.Txn().Iter(startKey, nil) if err != nil { return errors.Trace(err) } @@ -896,7 +896,7 @@ func (t *tableCommon) RebaseAutoID(ctx sessionctx.Context, newBase int64, isSetS // Seek implements table.Table Seek interface. func (t *tableCommon) Seek(ctx sessionctx.Context, h int64) (int64, bool, error) { seekKey := tablecodec.EncodeRowKeyWithHandle(t.physicalTableID, h) - iter, err := ctx.Txn().Seek(seekKey) + iter, err := ctx.Txn().Iter(seekKey, nil) if !iter.Valid() || !iter.Key().HasPrefix(t.RecordPrefix()) { // No more records in the table, skip to the end. return 0, false, nil diff --git a/util/admin/admin.go b/util/admin/admin.go index 325d09df98fc4..a76d5f416e8d1 100644 --- a/util/admin/admin.go +++ b/util/admin/admin.go @@ -636,7 +636,7 @@ func rowWithCols(sessCtx sessionctx.Context, txn kv.Retriever, t table.Table, h // genExprs use to calculate generated column value. func iterRecords(sessCtx sessionctx.Context, retriever kv.Retriever, t table.Table, startKey kv.Key, cols []*table.Column, fn table.RecordIterFunc, genExprs map[string]expression.Expression) error { - it, err := retriever.Seek(startKey) + it, err := retriever.Iter(startKey, nil) if err != nil { return errors.Trace(err) } diff --git a/util/prefix_helper.go b/util/prefix_helper.go index ccfd1ece9d633..a2c5d76dfd168 100644 --- a/util/prefix_helper.go +++ b/util/prefix_helper.go @@ -26,7 +26,7 @@ import ( // ScanMetaWithPrefix scans metadata with the prefix. func ScanMetaWithPrefix(retriever kv.Retriever, prefix kv.Key, filter func(kv.Key, []byte) bool) error { - iter, err := retriever.Seek(prefix) + iter, err := retriever.Iter(prefix, nil) if err != nil { return errors.Trace(err) } @@ -56,7 +56,7 @@ func ScanMetaWithPrefix(retriever kv.Retriever, prefix kv.Key, filter func(kv.Ke // DelKeyWithPrefix deletes keys with prefix. func DelKeyWithPrefix(rm kv.RetrieverMutator, prefix kv.Key) error { var keys []kv.Key - iter, err := rm.Seek(prefix) + iter, err := rm.Iter(prefix, nil) if err != nil { return errors.Trace(err) } From 3159f3427cd2f1ee116f226f5ff061ac1a8de16f Mon Sep 17 00:00:00 2001 From: MyonKeminta <9948422+MyonKeminta@users.noreply.github.com> Date: Fri, 9 Nov 2018 18:49:00 +0800 Subject: [PATCH 3/3] *: Make use of the upperBound of ticlient's kv_scan interface to ensure no overbound scan will happen (#8081) --- ddl/delete_range.go | 8 ++------ ddl/index.go | 22 ++++++++++++++++++---- ddl/reorg.go | 2 +- store/tikv/scan.go | 5 +++++ structure/hash.go | 2 +- table/tables/index.go | 8 +++++--- table/tables/tables.go | 6 +++--- util/admin/admin.go | 6 ++++-- util/prefix_helper.go | 4 ++-- 9 files changed, 41 insertions(+), 22 deletions(-) diff --git a/ddl/delete_range.go b/ddl/delete_range.go index fba35867f37b0..4b12de2d2f419 100644 --- a/ddl/delete_range.go +++ b/ddl/delete_range.go @@ -14,7 +14,6 @@ package ddl import ( - "bytes" "encoding/hex" "fmt" "math" @@ -154,7 +153,7 @@ func (dr *delRange) doTask(ctx sessionctx.Context, r util.DelRangeTask) error { finish := true dr.keys = dr.keys[:0] err := kv.RunInNewTxn(dr.store, false, func(txn kv.Transaction) error { - iter, err := txn.Iter(oldStartKey, nil) + iter, err := txn.Iter(oldStartKey, r.EndKey) if err != nil { return errors.Trace(err) } @@ -164,10 +163,7 @@ func (dr *delRange) doTask(ctx sessionctx.Context, r util.DelRangeTask) error { if !iter.Valid() { break } - finish = bytes.Compare(iter.Key(), r.EndKey) >= 0 - if finish { - break - } + finish = false dr.keys = append(dr.keys, iter.Key().Clone()) newStartKey = iter.Key().Next() diff --git a/ddl/index.go b/ddl/index.go index 92dbd2723c5ad..5eedd76f3dbc0 100644 --- a/ddl/index.go +++ b/ddl/index.go @@ -619,7 +619,7 @@ func (w *addIndexWorker) fetchRowColVals(txn kv.Transaction, taskRange reorgInde // taskDone means that the added handle is out of taskRange.endHandle. taskDone := false oprStartTime := startTime - err := iterateSnapshotRows(w.sessCtx.GetStore(), w.priority, w.table, txn.StartTS(), taskRange.startHandle, + err := iterateSnapshotRows(w.sessCtx.GetStore(), w.priority, w.table, txn.StartTS(), taskRange.startHandle, taskRange.endHandle, taskRange.endIncluded, func(handle int64, recordKey kv.Key, rawRow []byte) (bool, error) { oprEndTime := time.Now() w.logSlowOperations(oprEndTime.Sub(oprStartTime), "iterateSnapshotRows in fetchRowColVals", 0) @@ -1183,7 +1183,7 @@ func allocateIndexID(tblInfo *model.TableInfo) int64 { // recordIterFunc is used for low-level record iteration. type recordIterFunc func(h int64, rowKey kv.Key, rawRecord []byte) (more bool, err error) -func iterateSnapshotRows(store kv.Storage, priority int, t table.Table, version uint64, seekHandle int64, fn recordIterFunc) error { +func iterateSnapshotRows(store kv.Storage, priority int, t table.Table, version uint64, startHandle int64, endHandle int64, endIncluded bool, fn recordIterFunc) error { ver := kv.Version{Ver: version} snap, err := store.GetSnapshot(ver) @@ -1191,8 +1191,22 @@ func iterateSnapshotRows(store kv.Storage, priority int, t table.Table, version if err != nil { return errors.Trace(err) } - firstKey := t.RecordKey(seekHandle) - it, err := snap.Iter(firstKey, nil) + firstKey := t.RecordKey(startHandle) + + // Calculate the exclusive upper bound + var upperBound kv.Key + if endIncluded { + if endHandle == math.MaxInt64 { + upperBound = t.RecordKey(endHandle).PrefixNext() + } else { + // PrefixNext is time costing. Try to avoid it if possible. + upperBound = t.RecordKey(endHandle + 1) + } + } else { + upperBound = t.RecordKey(endHandle) + } + + it, err := snap.Iter(firstKey, upperBound) if err != nil { return errors.Trace(err) } diff --git a/ddl/reorg.go b/ddl/reorg.go index 10cf2d85b9064..035146c9976b1 100644 --- a/ddl/reorg.go +++ b/ddl/reorg.go @@ -304,7 +304,7 @@ func getTableRange(d *ddlCtx, tbl table.PhysicalTable, snapshotVer uint64, prior startHandle = math.MinInt64 endHandle = math.MaxInt64 // Get the start handle of this partition. - err = iterateSnapshotRows(d.store, priority, tbl, snapshotVer, math.MinInt64, + err = iterateSnapshotRows(d.store, priority, tbl, snapshotVer, math.MinInt64, math.MaxInt64, true, func(h int64, rowKey kv.Key, rawRecord []byte) (bool, error) { startHandle = h return false, nil diff --git a/store/tikv/scan.go b/store/tikv/scan.go index c3d5c555ba37b..1ce05ecc6089d 100644 --- a/store/tikv/scan.go +++ b/store/tikv/scan.go @@ -98,6 +98,11 @@ func (s *Scanner) Next() error { } current := s.cache[s.idx] + if len(s.endKey) > 0 && kv.Key(current.Key).Cmp(kv.Key(s.endKey)) >= 0 { + s.eof = true + s.Close() + return nil + } // Try to resolve the lock if current.GetError() != nil { // 'current' would be modified if the lock being resolved diff --git a/structure/hash.go b/structure/hash.go index bfa13118cce8c..e0f7b32cdb726 100644 --- a/structure/hash.go +++ b/structure/hash.go @@ -238,7 +238,7 @@ func (t *TxStructure) HClear(key []byte) error { func (t *TxStructure) iterateHash(key []byte, fn func(k []byte, v []byte) error) error { dataPrefix := t.hashDataKeyPrefix(key) - it, err := t.reader.Iter(dataPrefix, nil) + it, err := t.reader.Iter(dataPrefix, dataPrefix.PrefixNext()) if err != nil { return errors.Trace(err) } diff --git a/table/tables/index.go b/table/tables/index.go index c36d55c698cb1..f4580d0e93978 100644 --- a/table/tables/index.go +++ b/table/tables/index.go @@ -240,7 +240,7 @@ func (c *index) Delete(sc *stmtctx.StatementContext, m kv.Mutator, indexedValues // Drop removes the KV index from store. func (c *index) Drop(rm kv.RetrieverMutator) error { - it, err := rm.Iter(c.prefix, nil) + it, err := rm.Iter(c.prefix, c.prefix.PrefixNext()) if err != nil { return errors.Trace(err) } @@ -270,7 +270,8 @@ func (c *index) Seek(sc *stmtctx.StatementContext, r kv.Retriever, indexedValues return nil, false, errors.Trace(err) } - it, err := r.Iter(key, nil) + upperBound := c.prefix.PrefixNext() + it, err := r.Iter(key, upperBound) if err != nil { return nil, false, errors.Trace(err) } @@ -284,7 +285,8 @@ func (c *index) Seek(sc *stmtctx.StatementContext, r kv.Retriever, indexedValues // SeekFirst returns an iterator which points to the first entry of the KV index. func (c *index) SeekFirst(r kv.Retriever) (iter table.IndexIterator, err error) { - it, err := r.Iter(c.prefix, nil) + upperBound := c.prefix.PrefixNext() + it, err := r.Iter(c.prefix, upperBound) if err != nil { return nil, errors.Trace(err) } diff --git a/table/tables/tables.go b/table/tables/tables.go index 4a75d3f7e84d3..c24dd25d7f1d3 100644 --- a/table/tables/tables.go +++ b/table/tables/tables.go @@ -766,7 +766,8 @@ func (t *tableCommon) buildIndexForRow(ctx sessionctx.Context, rm kv.RetrieverMu // IterRecords implements table.Table IterRecords interface. func (t *tableCommon) IterRecords(ctx sessionctx.Context, startKey kv.Key, cols []*table.Column, fn table.RecordIterFunc) error { - it, err := ctx.Txn().Iter(startKey, nil) + prefix := t.RecordPrefix() + it, err := ctx.Txn().Iter(startKey, prefix.PrefixNext()) if err != nil { return errors.Trace(err) } @@ -782,7 +783,6 @@ func (t *tableCommon) IterRecords(ctx sessionctx.Context, startKey kv.Key, cols for _, col := range cols { colMap[col.ID] = &col.FieldType } - prefix := t.RecordPrefix() defaultVals := make([]types.Datum, len(cols)) for it.Valid() && it.Key().HasPrefix(prefix) { // first kv pair is row lock information. @@ -896,7 +896,7 @@ func (t *tableCommon) RebaseAutoID(ctx sessionctx.Context, newBase int64, isSetS // Seek implements table.Table Seek interface. func (t *tableCommon) Seek(ctx sessionctx.Context, h int64) (int64, bool, error) { seekKey := tablecodec.EncodeRowKeyWithHandle(t.physicalTableID, h) - iter, err := ctx.Txn().Iter(seekKey, nil) + iter, err := ctx.Txn().Iter(seekKey, t.RecordPrefix().PrefixNext()) if !iter.Valid() || !iter.Key().HasPrefix(t.RecordPrefix()) { // No more records in the table, skip to the end. return 0, false, nil diff --git a/util/admin/admin.go b/util/admin/admin.go index a76d5f416e8d1..a137c41ab410f 100644 --- a/util/admin/admin.go +++ b/util/admin/admin.go @@ -636,7 +636,10 @@ func rowWithCols(sessCtx sessionctx.Context, txn kv.Retriever, t table.Table, h // genExprs use to calculate generated column value. func iterRecords(sessCtx sessionctx.Context, retriever kv.Retriever, t table.Table, startKey kv.Key, cols []*table.Column, fn table.RecordIterFunc, genExprs map[string]expression.Expression) error { - it, err := retriever.Iter(startKey, nil) + prefix := t.RecordPrefix() + keyUpperBound := prefix.PrefixNext() + + it, err := retriever.Iter(startKey, keyUpperBound) if err != nil { return errors.Trace(err) } @@ -663,7 +666,6 @@ func iterRecords(sessCtx sessionctx.Context, retriever kv.Retriever, t table.Tab } } - prefix := t.RecordPrefix() for it.Valid() && it.Key().HasPrefix(prefix) { // first kv pair is row lock information. // TODO: check valid lock diff --git a/util/prefix_helper.go b/util/prefix_helper.go index a2c5d76dfd168..15fe13491291b 100644 --- a/util/prefix_helper.go +++ b/util/prefix_helper.go @@ -26,7 +26,7 @@ import ( // ScanMetaWithPrefix scans metadata with the prefix. func ScanMetaWithPrefix(retriever kv.Retriever, prefix kv.Key, filter func(kv.Key, []byte) bool) error { - iter, err := retriever.Iter(prefix, nil) + iter, err := retriever.Iter(prefix, prefix.PrefixNext()) if err != nil { return errors.Trace(err) } @@ -56,7 +56,7 @@ func ScanMetaWithPrefix(retriever kv.Retriever, prefix kv.Key, filter func(kv.Ke // DelKeyWithPrefix deletes keys with prefix. func DelKeyWithPrefix(rm kv.RetrieverMutator, prefix kv.Key) error { var keys []kv.Key - iter, err := rm.Iter(prefix, nil) + iter, err := rm.Iter(prefix, prefix.PrefixNext()) if err != nil { return errors.Trace(err) }