1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.tikv.common.meta;
19
20 import static java.util.Objects.requireNonNull;
21
22 import com.fasterxml.jackson.annotation.JsonCreator;
23 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
24 import com.fasterxml.jackson.annotation.JsonProperty;
25 import com.google.common.annotations.VisibleForTesting;
26 import com.google.common.base.Joiner;
27 import com.google.common.collect.ImmutableList;
28 import com.pingcap.tidb.tipb.ColumnInfo;
29 import com.pingcap.tidb.tipb.IndexInfo;
30 import java.io.Serializable;
31 import java.util.List;
32 import java.util.stream.Collectors;
33 import org.tikv.common.exception.TiKVException;
34
35 @JsonIgnoreProperties(ignoreUnknown = true)
36 public class TiIndexInfo implements Serializable {
37 private final long id;
38 private final String name;
39 private final String tableName;
40 private final List<TiIndexColumn> indexColumns;
41 private final boolean isUnique;
42 private final boolean isPrimary;
43 private final org.tikv.common.meta.SchemaState schemaState;
44 private final String comment;
45 private final org.tikv.common.meta.IndexType indexType;
46 private final boolean isFakePrimaryKey;
47
48
49 private long indexColumnSize = 9;
50
51 @JsonCreator
52 @VisibleForTesting
53 public TiIndexInfo(
54 @JsonProperty("id") long id,
55 @JsonProperty("idx_name") org.tikv.common.meta.CIStr name,
56 @JsonProperty("tbl_name") org.tikv.common.meta.CIStr tableName,
57 @JsonProperty("idx_cols") List<TiIndexColumn> indexColumns,
58 @JsonProperty("is_unique") boolean isUnique,
59 @JsonProperty("is_primary") boolean isPrimary,
60 @JsonProperty("state") int schemaState,
61 @JsonProperty("comment") String comment,
62 @JsonProperty("index_type") int indexType,
63
64
65 @JsonProperty("___isFakePrimaryKey") boolean isFakePrimaryKey) {
66 this.id = id;
67 this.name = requireNonNull(name, "index name is null").getL();
68 this.tableName = requireNonNull(tableName, "table name is null").getL();
69 this.indexColumns = ImmutableList.copyOf(requireNonNull(indexColumns, "indexColumns is null"));
70 this.isUnique = isUnique;
71 this.isPrimary = isPrimary;
72 this.schemaState = org.tikv.common.meta.SchemaState.fromValue(schemaState);
73 this.comment = comment;
74 this.indexType = org.tikv.common.meta.IndexType.fromValue(indexType);
75 this.isFakePrimaryKey = isFakePrimaryKey;
76 }
77
78 public static TiIndexInfo generateFakePrimaryKeyIndex(TiTableInfo table) {
79 org.tikv.common.meta.TiColumnInfo pkColumn = table.getPKIsHandleColumn();
80 if (pkColumn != null) {
81 return new TiIndexInfo(
82 -1,
83 org.tikv.common.meta.CIStr.newCIStr("fake_pk_" + table.getId()),
84 org.tikv.common.meta.CIStr.newCIStr(table.getName()),
85 ImmutableList.of(pkColumn.toFakeIndexColumn()),
86 true,
87 true,
88 org.tikv.common.meta.SchemaState.StatePublic.getStateCode(),
89 "Fake Column",
90 org.tikv.common.meta.IndexType.IndexTypeHash.getTypeCode(),
91 true);
92 }
93 return null;
94 }
95
96 private long calculateIndexColumnSize(
97 TiIndexColumn indexColumn, List<org.tikv.common.meta.TiColumnInfo> columns) {
98 for (org.tikv.common.meta.TiColumnInfo column : columns) {
99 if (column.getName().equalsIgnoreCase(indexColumn.getName())) {
100 return column.getType().getSize();
101 }
102 }
103 throw new TiKVException(
104 String.format(
105 "Index column [%s] not found in table [%s] columns [%s]",
106 indexColumn.getName(), getTableName(), columns));
107 }
108
109 void calculateIndexSize(List<org.tikv.common.meta.TiColumnInfo> columns) {
110 long ret = 0;
111 for (TiIndexColumn indexColumn : indexColumns) {
112 if (indexColumn.isLengthUnspecified()) {
113 ret += calculateIndexColumnSize(indexColumn, columns);
114 } else {
115 ret += indexColumn.getLength();
116 }
117 }
118 indexColumnSize = ret;
119 }
120
121 public long getIndexColumnSize() {
122 return this.indexColumnSize;
123 }
124
125 public long getId() {
126 return id;
127 }
128
129 public String getName() {
130 return name;
131 }
132
133 public String getTableName() {
134 return tableName;
135 }
136
137 public List<TiIndexColumn> getIndexColumns() {
138 return indexColumns;
139 }
140
141 public boolean isUnique() {
142 return isUnique;
143 }
144
145 public boolean isPrimary() {
146 return isPrimary;
147 }
148
149 public org.tikv.common.meta.SchemaState getSchemaState() {
150 return schemaState;
151 }
152
153 public String getComment() {
154 return comment;
155 }
156
157 public org.tikv.common.meta.IndexType getIndexType() {
158 return indexType;
159 }
160
161 public IndexInfo toProto(TiTableInfo tableInfo) {
162 IndexInfo.Builder builder =
163 IndexInfo.newBuilder().setTableId(tableInfo.getId()).setIndexId(id).setUnique(isUnique);
164
165 List<org.tikv.common.meta.TiColumnInfo> columns = tableInfo.getColumns();
166
167 for (TiIndexColumn indexColumn : getIndexColumns()) {
168 int offset = indexColumn.getOffset();
169 org.tikv.common.meta.TiColumnInfo column = columns.get(offset);
170 builder.addColumns(column.toProto(tableInfo));
171 }
172
173 if (tableInfo.isPkHandle()) {
174 for (org.tikv.common.meta.TiColumnInfo column : columns) {
175 if (!column.isPrimaryKey()) {
176 continue;
177 }
178 ColumnInfo pbColumn = column.toProto(tableInfo);
179 builder.addColumns(pbColumn);
180 }
181 }
182 return builder.build();
183 }
184
185 public boolean isFakePrimaryKey() {
186 return isFakePrimaryKey;
187 }
188
189 @Override
190 public String toString() {
191 return String.format(
192 "%s[%s]",
193 name,
194 Joiner.on(",")
195 .skipNulls()
196 .join(indexColumns.stream().map(TiIndexColumn::getName).collect(Collectors.toList())));
197 }
198 }