View Javadoc
1   /*
2    * Copyright 2021 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.key;
19  
20  import static org.tikv.common.codec.Codec.IntegerCodec.writeLong;
21  
22  import java.io.Serializable;
23  import org.tikv.common.codec.Codec.IntegerCodec;
24  import org.tikv.common.codec.CodecDataInput;
25  import org.tikv.common.codec.CodecDataOutput;
26  import org.tikv.common.exception.TiClientInternalException;
27  import org.tikv.common.exception.TiExpressionException;
28  
29  public class RowKey extends Key implements Serializable {
30    private static final byte[] REC_PREFIX_SEP = new byte[] {'_', 'r'};
31  
32    private final long tableId;
33    private final long handle;
34    private final boolean maxHandleFlag;
35  
36    private RowKey(long tableId, long handle) {
37      super(encode(tableId, handle));
38      this.tableId = tableId;
39      this.handle = handle;
40      this.maxHandleFlag = false;
41    }
42  
43    /**
44     * The RowKey indicating maximum handle (its value exceeds Long.Max_Value)
45     *
46     * <p>Initializes an imaginary globally MAXIMUM rowKey with tableId.
47     */
48    private RowKey(long tableId) {
49      super(encodeBeyondMaxHandle(tableId));
50      this.tableId = tableId;
51      this.handle = Long.MAX_VALUE;
52      this.maxHandleFlag = true;
53    }
54  
55    public static RowKey toRowKey(long tableId, long handle) {
56      return new RowKey(tableId, handle);
57    }
58  
59    public static RowKey toRowKey(long tableId, org.tikv.common.key.TypedKey handle) {
60      Object obj = handle.getValue();
61      if (obj instanceof Long) {
62        return new RowKey(tableId, (long) obj);
63      }
64      throw new TiExpressionException("Cannot encode row key with non-long type");
65    }
66  
67    public static RowKey createMin(long tableId) {
68      return toRowKey(tableId, Long.MIN_VALUE);
69    }
70  
71    public static RowKey createBeyondMax(long tableId) {
72      return new RowKey(tableId);
73    }
74  
75    public static RowKey decode(byte[] value) {
76      CodecDataInput cdi = new CodecDataInput(value);
77      cdi.readByte();
78      long tableId = IntegerCodec.readLong(cdi); // tableId
79      cdi.readByte();
80      cdi.readByte();
81      long handle = IntegerCodec.readLong(cdi); // handle
82      return toRowKey(tableId, handle);
83    }
84  
85    private static byte[] encode(long tableId, long handle) {
86      CodecDataOutput cdo = new CodecDataOutput();
87      encodePrefix(cdo, tableId);
88      writeLong(cdo, handle);
89      return cdo.toBytes();
90    }
91  
92    private static byte[] encodeBeyondMaxHandle(long tableId) {
93      return prefixNext(encode(tableId, Long.MAX_VALUE));
94    }
95  
96    private static void encodePrefix(CodecDataOutput cdo, long tableId) {
97      cdo.write(TBL_PREFIX);
98      writeLong(cdo, tableId);
99      cdo.write(REC_PREFIX_SEP);
100   }
101 
102   @Override
103   public RowKey next() {
104     long handle = getHandle();
105     boolean maxHandleFlag = getMaxHandleFlag();
106     if (maxHandleFlag) {
107       throw new TiClientInternalException("Handle overflow for Long MAX");
108     }
109     if (handle == Long.MAX_VALUE) {
110       return createBeyondMax(tableId);
111     }
112     return new RowKey(tableId, handle + 1);
113   }
114 
115   public long getTableId() {
116     return tableId;
117   }
118 
119   public long getHandle() {
120     return handle;
121   }
122 
123   private boolean getMaxHandleFlag() {
124     return maxHandleFlag;
125   }
126 
127   @Override
128   public String toString() {
129     return Long.toString(handle);
130   }
131 
132   public static class DecodeResult {
133     public long handle;
134     public Status status;
135 
136     public enum Status {
137       MIN,
138       MAX,
139       EQUAL,
140       LESS,
141       GREATER,
142       UNKNOWN_INF
143     }
144   }
145 }