package com.taobao.tddl.optimizer.config.table; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.taobao.tddl.common.utils.GeneralUtil; /** * 每一个索引(或者叫KV更直白点)的描述 * * @author jianxing <jianxing.qx@taobao.com> */ public class IndexMeta implements Serializable, Cloneable { private static final long serialVersionUID = 1L; /** * 表名+列名 */ private final String name; /** * 列名字 */ private final List<ColumnMeta> keyColumns; /** * 值名字 */ private final List<ColumnMeta> valueColumns; /** * 当前index的类型 @IndexType */ private final IndexType indexType; /** * 关系,用来处理多对多关系,暂时没有用到。 see IndexType */ private final Relationship relationship; /** * 是否强同步,目前只支持主key */ private final boolean isStronglyConsistent; private final boolean isPrimaryKeyIndex; /** * 该索引的拆分键 */ private final List<ColumnMeta> partitionColumns; // ================== 冗余字段 ============== /** * 表名+index名的方式进行命名的。 在查询时,会先根据.之前的,拿到表名,然后找到对应的schema。 * 然后再根据.之后的,找到对应的schema */ private final String tableName; /** * 保存了所有列,方便查找 */ private Map<String, ColumnMeta> columnsMap = new HashMap(); public IndexMeta(String tableName, List<ColumnMeta> keys, List<ColumnMeta> values, IndexType indexType, Relationship relationship, boolean isStronglyConsistent, boolean isPrimaryKeyIndex, List<ColumnMeta> partitionColumns){ this.tableName = tableName; this.keyColumns = uniq(keys); this.valueColumns = uniq(values); this.indexType = indexType; this.relationship = relationship; this.isPrimaryKeyIndex = isPrimaryKeyIndex; this.isStronglyConsistent = isStronglyConsistent; this.partitionColumns = partitionColumns; this.name = buildName(tableName, keys); this.columnsMap = buildColumnsMap(); } private Map<String, ColumnMeta> buildColumnsMap() { Map<String, ColumnMeta> columnsMap = new HashMap(); if (valueColumns != null) { for (ColumnMeta cm : valueColumns) { columnsMap.put(cm.getName(), cm); } } if (keyColumns != null) { for (ColumnMeta cm : keyColumns) { columnsMap.put(cm.getName(), cm); } } return columnsMap; } private String buildName(String tableName, List<ColumnMeta> columns) { StringBuilder sb = new StringBuilder(); sb.append(tableName).append("."); for (ColumnMeta column : columns) { sb.append("_" + column.getName()); } return sb.toString(); } public ColumnMeta getColumnMeta(String name) { return this.columnsMap.get(name); } public String getName() { if (isPrimaryKeyIndex) { return tableName; // 如果是主键索引,直接返回逻辑表名 } else { return name; // 否则返回索引名,逻辑表名+字段 } } public List<ColumnMeta> getKeyColumns() { return keyColumns; } public List<ColumnMeta> getValueColumns() { return valueColumns; } public IndexType getIndexType() { return indexType; } public Relationship getRelationship() { return relationship; } public boolean isStronglyConsistent() { return isStronglyConsistent; } public boolean isPrimaryKeyIndex() { return isPrimaryKeyIndex; } public List<ColumnMeta> getPartitionColumns() { return partitionColumns; } public String getTableName() { return tableName; } public String getNameWithOutDot() { return name.replace(".", "$"); } public String toString() { return toStringWithInden(0); } /** * 根据列名获取对应的index key column * * @param name * @return */ public ColumnMeta getKeyColumn(String name) { for (ColumnMeta column : keyColumns) { if (column.getName().equals(name)) { return column; } } return null; } /** * 根据列名获取对应的index value column * * @param name * @return */ public ColumnMeta getValueColumn(String name) { for (ColumnMeta column : valueColumns) { if (column.getName().equals(name)) { return column; } } return null; } private List<ColumnMeta> uniq(List<ColumnMeta> s) { if (s == null) { return null; } List<ColumnMeta> uniqList = new ArrayList<ColumnMeta>(s.size()); for (ColumnMeta cm : s) { if (!uniqList.contains(cm)) { uniqList.add(cm); } } return uniqList; } public String toStringWithInden(int inden) { StringBuilder sb = new StringBuilder(); String tabTittle = GeneralUtil.getTab(inden); sb.append(tabTittle).append("["); sb.append("indexMeta name : ").append(name).append("\n"); buildMetas(inden, sb, keyColumns, "keyColumn :"); buildMetas(inden, sb, valueColumns, "valueColumn :"); sb.append(tabTittle).append("]"); return sb.toString(); } private void buildMetas(int inden, StringBuilder sb, List<ColumnMeta> metas, String keyName) { if (metas != null) { String tabContent = GeneralUtil.getTab(inden + 1); sb.append(tabContent).append(keyName).append("\n"); String content = GeneralUtil.getTab(inden + 2); sb.append(content); for (ColumnMeta meta : metas) { sb.append(meta.toStringWithInden(0)); sb.append(" "); } sb.append("\n"); } } }