package com.taobao.tddl.rule.enumerator.handler; import java.util.Set; import com.taobao.tddl.rule.model.sqljep.Comparative; public abstract class NumberPartDiscontinousRangeEnumerator extends PartDiscontinousRangeEnumerator { private static final int LIMIT_UNIT_OF_LONG = 1; private static final int DEFAULT_LONG_ATOMIC_VALUE = 1; private static final boolean isAllowNegative; static { /** * 大多数整形的ID/分库分表字段默认都是大于零的。如果有小于0的系统,那么将这个参数设为true, * 同时自己要保证要么不出现id<3这样的条件,要么算出负的dbIndex也没有问题 */ isAllowNegative = "true".equals(System.getProperty("com.taobao.tddl.rule.isAllowNegativeShardValue", "false")); } @Override protected Comparative changeGreater2GreaterOrEq(Comparative from) { if (from.getComparison() == Comparative.GreaterThan) { Number fromComparable = cast2Number(from.getValue()); return new Comparative(Comparative.GreaterThanOrEqual, (Comparable) plus(fromComparable, LIMIT_UNIT_OF_LONG)); } else { return from; } } @Override protected Comparative changeLess2LessOrEq(Comparative to) { if (to.getComparison() == Comparative.LessThan) { Number toComparable = cast2Number(to.getValue()); return new Comparative(Comparative.LessThanOrEqual, (Comparable) plus(toComparable, -1 * LIMIT_UNIT_OF_LONG)); } else { return to; } } @Override protected Comparable getOneStep(Comparable source, Comparable atomIncVal) { if (atomIncVal == null) { atomIncVal = DEFAULT_LONG_ATOMIC_VALUE; } Number sourceLong = cast2Number(source); int atomIncValInt = (Integer) atomIncVal; return (Comparable) plus(sourceLong, atomIncValInt); } @SuppressWarnings("rawtypes") protected boolean inputCloseRangeGreaterThanMaxFieldOfDifination(Comparable from, Comparable to, Integer cumulativeTimes, Comparable<?> atomIncrValue) { if (cumulativeTimes == null) { return false; } if (atomIncrValue == null) { atomIncrValue = DEFAULT_LONG_ATOMIC_VALUE; } long fromLong = ((Number) from).longValue(); long toLong = ((Number) to).longValue(); int atomIncValLong = ((Number) atomIncrValue).intValue(); int size = cumulativeTimes; if ((toLong - fromLong) > (atomIncValLong * size)) { return true; } else { return false; } } public void processAllPassableFields(Comparative begin, Set<Object> retValue, Integer cumulativeTimes, Comparable<?> atomicIncreationValue) { if (cumulativeTimes == null) { throw new IllegalStateException("在没有提供叠加次数的前提下,不能够根据当前范围条件选出对应的定义域的枚举值,sql中不要出现> < >= <="); } if (atomicIncreationValue == null) { atomicIncreationValue = DEFAULT_LONG_ATOMIC_VALUE; } // 把> < 替换为>= <= begin = changeGreater2GreaterOrEq(begin); begin = changeLess2LessOrEq(begin); // long beginInt = (Long) toPrimaryValue(begin.getValue()); Number beginInt = getNumber(begin.getValue()); int atomicIncreateValueInt = ((Number) atomicIncreationValue).intValue(); int comparasion = begin.getComparison(); if (comparasion == Comparative.GreaterThanOrEqual) { for (int i = 0; i < cumulativeTimes; i++) { retValue.add(plus(beginInt, atomicIncreateValueInt * i)); } } else if (comparasion == Comparative.LessThanOrEqual) { for (int i = 0; i < cumulativeTimes; i++) { // 这里可能出现不期望的负数 Number value = (Number) plus(beginInt, -1 * atomicIncreateValueInt * i); if (!isAllowNegative && value.longValue() < 0) { break; } retValue.add(value); } } } protected abstract Number cast2Number(Comparable begin); protected abstract Number getNumber(Comparable begin); protected abstract Number plus(Number begin, int plus); }