package com.taobao.tddl.rule.enumerator.handler; import java.util.Set; import com.taobao.tddl.rule.model.sqljep.Comparative; public abstract class PartDiscontinousRangeEnumerator implements CloseIntervalFieldsEnumeratorHandler { /** * 一次自增 * * @param source * @param atomIncVal * @return */ protected abstract Comparable getOneStep(Comparable source, Comparable atomIncVal); /** * 根据不同数据的最小单位将>变为>= * * @param to * @return */ protected abstract Comparative changeGreater2GreaterOrEq(Comparative from); /** * 根据不同数据的最小单位将<变为<= * * @param to * @return */ protected abstract Comparative changeLess2LessOrEq(Comparative to); /** * 如果输入的范围大于range.size() * atomIncrementvalue的值,那么就可以做短路优化 * * @param from 只有<=情况下的form值 * @param to 只有>=情况下的to 值 * @param range * @param atomIncrementValue * @return */ protected abstract boolean inputCloseRangeGreaterThanMaxFieldOfDifination(Comparable from, Comparable to, Integer cumulativeTimes, Comparable<?> atomIncrValue); public void mergeFeildOfDefinitionInCloseInterval(Comparative from, Comparative to, Set<Object> retValue, Integer cumulativeTimes, Comparable<?> atomIncrValue) { if (cumulativeTimes == null || atomIncrValue == null) { throw new IllegalArgumentException("当原子增参数或叠加参数为空时,不支持在sql中使用范围选择,如id>? and id<?"); } from = changeGreater2GreaterOrEq(from); to = changeLess2LessOrEq(to); Comparable fromComparable = from.getValue(); Comparable toComparable = to.getValue(); if (inputCloseRangeGreaterThanMaxFieldOfDifination(fromComparable, toComparable, cumulativeTimes, atomIncrValue)) { // 如果所取得范围大于非连续函数的一个变动周期。直接断路掉,并且全取 if (retValue != null) { processAllPassableFields(from, retValue, cumulativeTimes, atomIncrValue); return; } else { throw new IllegalArgumentException("待写入的参数set为null"); } } if (fromComparable.compareTo(toComparable) == 0) { // 如果转变为>=和<=得情况下,俩值相等了,那么直接返回。 retValue.add(fromComparable); return; } int rangeSize = cumulativeTimes; retValue.add(fromComparable); Comparable enumedFoD = fromComparable; for (int i = 0; i < rangeSize; i++) { enumedFoD = getOneStep(enumedFoD, atomIncrValue); int compareResult = enumedFoD.compareTo(toComparable); if (compareResult == 0) { // 枚举值等于to的值,简单的把to的值放到枚举数列里。返回 retValue.add(toComparable); return; } else if (compareResult > 0) { // 枚举值大于to得值,按月分库的情况下也需要把最后一个月加上,其他情况会多算一个库 // 这样做,在最后一天的时候会有可能出现两个值,第一个值是由from自增出现的值,第二个是由to产生的值。规则引擎多算一次,但为了保证正确暂时先这样写 // trace: http://jira.taobao.ali.com/browse/TDDL-38 retValue.add(toComparable); return; } else { // 枚举小于to的值,添加枚举到定义域 retValue.add(enumedFoD); } } } }