View Javadoc
1   /*
2    * Copyright 2022 TiKV Project Authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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 }