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 com.google.common.base.Joiner;
21 import java.util.List;
22 import org.tikv.common.codec.Codec.IntegerCodec;
23 import org.tikv.common.codec.CodecDataOutput;
24 import org.tikv.common.exception.TypeException;
25 import org.tikv.common.meta.TiIndexColumn;
26 import org.tikv.common.meta.TiTableInfo;
27 import org.tikv.common.row.Row;
28 import org.tikv.common.types.DataType;
29 import org.tikv.common.types.IntegerType;
30
31 public class IndexKey extends Key {
32 private static final byte[] IDX_PREFIX_SEP = new byte[] {'_', 'i'};
33
34 private final long tableId;
35 private final long indexId;
36 private final Key[] dataKeys;
37
38 private IndexKey(long tableId, long indexId, Key[] dataKeys) {
39 super(encode(tableId, indexId, dataKeys));
40 this.tableId = tableId;
41 this.indexId = indexId;
42 this.dataKeys = dataKeys;
43 }
44
45 public static class EncodeIndexDataResult {
46 public EncodeIndexDataResult(Key[] keys, boolean appendHandle) {
47 this.keys = keys;
48 this.appendHandle = appendHandle;
49 }
50
51 public Key[] keys;
52 public boolean appendHandle;
53 }
54
55 public static IndexKey toIndexKey(long tableId, long indexId, Key... dataKeys) {
56 return new IndexKey(tableId, indexId, dataKeys);
57 }
58
59 public static EncodeIndexDataResult encodeIndexDataValues(
60 Row row,
61 List<TiIndexColumn> indexColumns,
62 long handle,
63 boolean appendHandleIfContainsNull,
64 TiTableInfo tableInfo) {
65
66
67 boolean appendHandle = false;
68 if (appendHandleIfContainsNull) {
69 for (TiIndexColumn col : indexColumns) {
70 DataType colTp = tableInfo.getColumn(col.getOffset()).getType();
71 if (row.get(col.getOffset(), colTp) == null) {
72 appendHandle = true;
73 break;
74 }
75 }
76 }
77 Key[] keys = new Key[indexColumns.size() + (appendHandle ? 1 : 0)];
78 for (int i = 0; i < indexColumns.size(); i++) {
79 TiIndexColumn col = indexColumns.get(i);
80 DataType colTp = tableInfo.getColumn(col.getOffset()).getType();
81
82 Key key =
83 org.tikv.common.key.TypedKey.toTypedKey(
84 row.get(col.getOffset(), colTp), colTp, (int) col.getLength());
85 keys[i] = key;
86 }
87 if (appendHandle) {
88 Key key = org.tikv.common.key.TypedKey.toTypedKey(handle, IntegerType.BIGINT);
89 keys[keys.length - 1] = key;
90 }
91
92 return new EncodeIndexDataResult(keys, appendHandle);
93 }
94
95 private static byte[] encode(long tableId, long indexId, Key[] dataKeys) {
96 CodecDataOutput cdo = new CodecDataOutput();
97 cdo.write(TBL_PREFIX);
98 IntegerCodec.writeLong(cdo, tableId);
99 cdo.write(IDX_PREFIX_SEP);
100 IntegerCodec.writeLong(cdo, indexId);
101 for (Key key : dataKeys) {
102 if (key == null) {
103 throw new TypeException("key cannot be null");
104 }
105 cdo.write(key.getBytes());
106 }
107 return cdo.toBytes();
108 }
109
110 public long getTableId() {
111 return tableId;
112 }
113
114 public long getIndexId() {
115 return indexId;
116 }
117
118 public Key[] getDataKeys() {
119 return dataKeys;
120 }
121
122 @Override
123 public String toString() {
124 return String.format("[%s]", Joiner.on(",").useForNull("null").join(dataKeys));
125 }
126 }