1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
45
46
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);
79 cdi.readByte();
80 cdi.readByte();
81 long handle = IntegerCodec.readLong(cdi);
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 }