package jef.database.routing.function; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import jef.common.PairSO; import jef.common.log.LogUtil; import jef.database.ORMConfig; import jef.database.annotation.PartitionFunction; import jef.database.query.RangeDimension; import jef.database.query.RegexpDimension; import jef.tools.StringUtils; /** * 对文本进行截断,并获取hash值,然后取模,最后按Range进行分区 * * @author jiyi * */ public class HashMod1024MappingFunction implements PartitionFunction<String> { private int maxLength = 0; private int[] ranges; private String[] results; private Collection<String> allResult; private BigInteger mod = BigInteger.valueOf(1024); public static void main(String[] args) { // HashMod1024MappingFunction ss = new HashMod1024MappingFunction("0:DB1,256:DB2,512:DB3,768:DB4", 0); HashMod1024MappingFunction ss = new HashMod1024MappingFunction("0-255:DB1,256-511:DB2,512-767:DB3,768-1023:DB4", 0); System.out.println(ss.allModulus()); System.out.println("-------------------------"); System.out.println(ss.getResult(1)); System.out.println(ss.getResult(2)); System.out.println("-------------------------"); System.out.println(ss.getResult(999)); System.out.println(ss.getResult(1023)); System.out.println(ss.getResult(1024)); System.out.println("-------------------------"); System.out.println(ss.eval("A")); System.out.println(ss.eval("ABC123")); System.out.println(ss.eval("毛泽东")); System.out.println(ss.eval("周恩来")); System.out.println(ss.eval("蒋介石")); System.out.println(ss.eval("马克思")); System.out.println(ss.eval("孙悟空")); System.out.println(ss.eval("猪八戒")); } /** * 空构造 */ public HashMod1024MappingFunction() { this(ORMConfig.getInstance().getPartitionBucketRange(), 0); } /** * 构造 * * @param expression * @param digit */ public HashMod1024MappingFunction(String expression, int digit) { if(StringUtils.isEmpty(expression)) { expression=ORMConfig.getInstance().getPartitionBucketRange(); } this.maxLength = digit; List<PairSO<RangeDimension<Integer>>> ranges = new ArrayList<PairSO<RangeDimension<Integer>>>(); for (String s : StringUtils.split(expression, ",")) { int index = s.lastIndexOf(':'); if (index < 1) { throw new IllegalArgumentException("Invalid config of map:" + s); } String value = s.substring(index + 1); s = s.substring(0, index); index = s.lastIndexOf('-'); if (index > 0) { // 如果第一位就是-,认为是负号,不算分隔符 int start = StringUtils.toInt(s.substring(0, index), null); int end = StringUtils.toInt(s.substring(index + 1), null); addRange(start, end+1, value, ranges); } else { int start = StringUtils.toInt(s, null); addRange(start, null, value, ranges); } } checkLast(ranges); for(PairSO<RangeDimension<Integer>> entry:ranges) { LogUtil.info(entry.first+":"+entry.second); } this.ranges = new int[ranges.size()]; this.results = new String[ranges.size()]; for (int i = 0; i < ranges.size(); i++) { PairSO<RangeDimension<Integer>> p = ranges.get(i); this.results[i] = p.first; this.ranges[i] = p.second.getMin(); } this.allResult = Arrays.asList(results); } private void checkLast(List<PairSO<RangeDimension<Integer>>> ranges) { RangeDimension<Integer> last=ranges.isEmpty()?null:ranges.get(ranges.size()-1).second; if(last.getMax()==null) { last.setMax(1024); } if(last.getMax()!=1024) { throw new IllegalArgumentException(); } } @SuppressWarnings("unchecked") private void addRange(int start, Integer end, String value, List<PairSO<RangeDimension<Integer>>> ranges) { if (end!=null && end < start) { throw new IllegalArgumentException(); } RangeDimension<Integer> last=ranges.isEmpty()?null:ranges.get(ranges.size()-1).second; if (last==null) { ranges.add(new PairSO<RangeDimension<Integer>>(value,RangeDimension.createLC(start, end))); } else { if(last.getMax()==null) { last.setMax(start); } if(last.getMax()!=start) { throw new IllegalArgumentException("The range ["+last.getMax()+"-"+start+"] was skipped."); } ranges.add(new PairSO<RangeDimension<Integer>>(value,RangeDimension.createLC(start, end))); } } @Override public String eval(String value) { int buck = value == null ? 0 : (BigInteger.valueOf(trim(value).hashCode()).mod(mod).intValue()); return getResult(buck); } private String trim(String value) { return value.length() > maxLength ? value.substring(0, maxLength) : value; } private Collection<String> allModulus() { return allResult; } private String getResult(int buck) { for (int id = 0; id < ranges.length - 1; id++) { if (buck >= ranges[id] && buck < ranges[id + 1]) { return results[id]; } } return results[ranges.length - 1]; } @Override public Collection<String> iterator(String min, String max, boolean left, boolean right) { // 由于 if (min == null || max == null) { return allModulus(); } if (StringUtils.equals(min, max)) { if (!left && left == right) { return Collections.emptyList(); } else { return Collections.singletonList(eval(min)); } } return allModulus(); } @Override public boolean acceptRegexp() { return false; } @Override public Collection<String> iterator(RegexpDimension regexp) { throw new UnsupportedOperationException(); } }