package com.taobao.tddl.rule.virtualnode; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import com.google.common.collect.Maps; /** * 构造group的一致性hash的slot * * @author <a href="junyu@taobao.com">junyu</a> * @version 1.0 * @since 1.6 * @date 2011-6-2 03:12:39 */ public class DBTableMap extends WrappedLogic implements VirtualNodeMap { private Map<String/* slot number */, String/* group_0 */> dbContext = Maps.newConcurrentMap(); private Map<String, String> dbTableMap = Maps.newHashMap(); private String logicTable; private Map<String/* group */, PartitionFunction> parFuncMap; public void init() { this.initDbTableMap(this.dbTableMap); if (null != dbTableMap && dbTableMap.size() > 0) { dbContext = extraReverseMap(dbTableMap); addLogicTableAndSplitorToKey(); } else { throw new IllegalArgumentException("no dbTableMap config at all"); } } public String getValue(String tableSuffix) { return dbContext.get(tableSuffix); } private void addLogicTableAndSplitorToKey() { if (tableSlotKeyFormat != null) { ConcurrentHashMap<String, String> reKeyMap = new ConcurrentHashMap<String, String>(); for (Map.Entry<String, String> entry : dbContext.entrySet()) { String newKey = super.wrapValue(entry.getKey()); reKeyMap.put(newKey, entry.getValue()); } dbContext.clear(); dbContext = reKeyMap; } else if (this.logicTable != null) { ConcurrentHashMap<String, String> reKeyMap = new ConcurrentHashMap<String, String>(); for (Map.Entry<String, String> entry : dbContext.entrySet()) { StringBuilder sb = new StringBuilder(this.logicTable); sb.append(tableSplitor); sb.append(entry.getKey()); reKeyMap.put(sb.toString(), entry.getValue()); } dbContext.clear(); dbContext = reKeyMap; } else { // throw new // RuntimeException("TableRule no tableSlotKeyFormat property and logicTable is null"); } } private void initDbTableMap(Map<String, String> dbTableMap) { if (this.parFuncMap == null || this.parFuncMap.isEmpty()) { return; } for (String key : this.parFuncMap.keySet()) { PartitionFunction parFunc = this.parFuncMap.get(key); String value = this.buildDbTableMapValue(parFunc); dbTableMap.put(key, value); } } private String buildDbTableMapValue(PartitionFunction parFunc) { StringBuilder valueBuilder = new StringBuilder(); int[] partitionCount = parFunc.getCount(); int[] partitionLength = parFunc.getLength(); int firstValue = parFunc.getFirstValue(); for (int i = 0; i < partitionCount.length; i++) { for (int j = 0; j < partitionCount[i]; j++) { int key = firstValue + partitionLength[i]; firstValue = key; valueBuilder.append(key); valueBuilder.append(","); } } valueBuilder.deleteCharAt(valueBuilder.length() - 1); return valueBuilder.toString(); } // ===================== setter / getter ==================== public void setDbTableMap(Map<String, String> dbTableMap) { this.dbTableMap = dbTableMap; } public void setLogicTable(String logicTable) { this.logicTable = logicTable; } public void setParFuncMap(Map<String, PartitionFunction> parFuncMap) { this.parFuncMap = parFuncMap; } }