1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.tikv.common.apiversion;
19
20 import com.google.protobuf.ByteString;
21 import org.tikv.common.util.Pair;
22 import org.tikv.kvproto.Metapb;
23 import org.tikv.kvproto.Metapb.Region;
24
25 public class RequestKeyV2Codec implements RequestKeyCodec {
26 protected static final ByteString RAW_DEFAULT_PREFIX =
27 ByteString.copyFrom(new byte[] {'r', 0, 0, 0});
28 protected static final ByteString RAW_DEFAULT_END =
29 ByteString.copyFrom(new byte[] {'r', 0, 0, 1});
30 protected static final ByteString TXN_DEFAULT_PREFIX =
31 ByteString.copyFrom(new byte[] {'x', 0, 0, 0});
32 protected static final ByteString TXN_DEFAULT_END =
33 ByteString.copyFrom(new byte[] {'x', 0, 0, 1});
34 protected ByteString keyPrefix;
35 protected ByteString infiniteEndKey;
36
37 @Override
38 public ByteString encodeKey(ByteString key) {
39 return keyPrefix.concat(key);
40 }
41
42 @Override
43 public ByteString decodeKey(ByteString key) {
44 if (key.isEmpty()) {
45 return key;
46 }
47
48 if (!key.startsWith(keyPrefix)) {
49 throw new IllegalArgumentException("key corrupted, wrong prefix");
50 }
51
52 return key.substring(keyPrefix.size());
53 }
54
55 @Override
56 public Pair<ByteString, ByteString> encodeRange(ByteString start, ByteString end) {
57 start = encodeKey(start);
58
59 end = end.isEmpty() ? infiniteEndKey : encodeKey(end);
60
61 return Pair.create(start, end);
62 }
63
64 @Override
65 public ByteString encodePdQuery(ByteString key) {
66 return CodecUtils.encode(encodeKey(key));
67 }
68
69 @Override
70 public Pair<ByteString, ByteString> encodePdQueryRange(ByteString start, ByteString end) {
71 Pair<ByteString, ByteString> range = encodeRange(start, end);
72 return Pair.create(CodecUtils.encode(range.first), CodecUtils.encode(range.second));
73 }
74
75 @Override
76 public Region decodeRegion(Region region) {
77 Metapb.Region.Builder builder = Metapb.Region.newBuilder().mergeFrom(region);
78
79 ByteString start = region.getStartKey();
80 ByteString end = region.getEndKey();
81
82 if (!start.isEmpty()) {
83 start = CodecUtils.decode(start);
84 }
85
86 if (!end.isEmpty()) {
87 end = CodecUtils.decode(end);
88 }
89
90 if (ByteString.unsignedLexicographicalComparator().compare(start, infiniteEndKey) >= 0
91 || (!end.isEmpty()
92 && ByteString.unsignedLexicographicalComparator().compare(end, keyPrefix) <= 0)) {
93 throw new IllegalArgumentException("region out of keyspace" + region.toString());
94 }
95
96 start = start.startsWith(keyPrefix) ? start.substring(keyPrefix.size()) : ByteString.EMPTY;
97 end = end.startsWith(keyPrefix) ? end.substring(keyPrefix.size()) : ByteString.EMPTY;
98
99 return builder.setStartKey(start).setEndKey(end).build();
100 }
101 }