All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.javaclub.cdl.client.matrix.rule.DefaultRouterStrategy Maven / Gradle / Ivy

The newest version!
package com.github.javaclub.cdl.client.matrix.rule;

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 
 *         默认路由逻辑:
 * 
 *         假设32个分表,2个group, 则:
 * 
 *         group1: 0-15
 * 
 *         group2: 16-31
 * 
 *         路由时先找到分表的逻辑编号如15,则再找到group1, 这种方式可以方便地进行表粒度的数据迁移,便于水平扩缩容
 *
 */
public class DefaultRouterStrategy implements RouterStrategy {
	protected String defaultDbGroup;  // 非sharding表走默认库
	protected Map tableShardMap;
	protected HashFunction hashFunction;
	protected AtomicBoolean inited = new AtomicBoolean(false);

	public void init() {
		if(inited.compareAndSet(false,true)){
			for (TableShardInfo tableShardInfo : tableShardMap.values()) {
				Collections.sort(tableShardInfo.getGroupList());
			}
		}
	}

	@Override
	public Map getActualTable(String table, Object shardColumnValue) {
		if(!inited.get()){
			throw new RuntimeException("init method not be invoked at first, check your spring bean");
		}
		TableShardInfo tableShardInfo = tableShardMap.get(table);
		if (tableShardInfo == null) {
			throw new RuntimeException("not found Sharding Column for table:" + table);
		}
		
		int tableIndex = -1;
		
		if(hashFunction != null){
			tableIndex = hashFunction.doHash(table, shardColumnValue);
		}
		
		if(tableIndex == -1){
			if (shardColumnValue instanceof Number) {
				Number number = (Number)shardColumnValue;
				long value = number.longValue();
				long mod = value % tableShardInfo.getTableShardNum();
				tableIndex = (int) mod;
			} else {
				tableIndex = shardColumnValue.hashCode() % tableShardInfo.getTableShardNum();
			}
		}
		
		return getDataSourceFromIndex(tableIndex, tableShardInfo);
	}

	@Override
	public Map getShardingColumn() {
		if(!inited.get()){
			throw new RuntimeException("init method not be invoked at first, check your spring bean");
		}
		Map map = new HashMap<>();
		for (TableShardInfo tableShardInfo : tableShardMap.values()) {
			map.put(tableShardInfo.getTable(), tableShardInfo.getShardColumn());
		}
		return map;
	}

	@Override
	public Map> getAllActualTable(String table) {
		if(!inited.get()){
			throw new RuntimeException("init method not be invoked at first, check your spring bean");
		}
		Map> map = new HashMap<>();
		TableShardInfo tableShardInfo = tableShardMap.get(table);
		if (tableShardInfo == null) {
			map.put(defaultDbGroup, Arrays.asList(new String[] { table}));
			return map;
		}
		
		for (int i = 0; i < tableShardInfo.getTableShardNum(); i++) {
			Map oneShard = getDataSourceFromIndex(i, tableShardInfo);
			for (String group : oneShard.keySet()) {
				if (map.get(group) == null) {
					map.put(group, new ArrayList());
				}
				map.get(group).add(oneShard.get(group));
			}
		}
		return map;
	}
	
	@Override
	public void setHashFunction(HashFunction hashFunction) {
		this.hashFunction = hashFunction;
	}
	
	private Map getDataSourceFromIndex(int tableIndex, TableShardInfo tableShardInfo) {
		String actualTable = tableShardInfo.getTablePrefix()
				+ SuffixParse.getTableSuffix(tableShardInfo.getTableBeginIndex() + tableIndex, tableShardInfo.getIndexBits());

		int groupIndex = tableIndex == 0 ? 0 : tableIndex / (tableShardInfo.getTableShardNum() / tableShardInfo.getGroupList().size());
		String group = tableShardInfo.getGroupList().get(groupIndex);
		Map routeMap = new HashMap();
		routeMap.put(group, actualTable);
		return routeMap;
	}

	public void setTableShardMap(Map tableShardMap) {
		this.tableShardMap = tableShardMap;
	}

	public void setDefaultDbGroup(String defaultDbGroup) {
		this.defaultDbGroup = defaultDbGroup;
	}

	@Override
	public String getDefaultGroup() {
		return defaultDbGroup;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy