Skip to content

Commit

Permalink
1、Move function getShardingConditions from ParsingSQLRouter to Optimi…
Browse files Browse the repository at this point in the history
…zeEngine(将getShardingConditions相关逻辑从ParsingSQLRouter移到OptimizeEngine)

2、Add some object Instead of null to return in OptimizeEngine(添加一些包装类代替返回值null)
3、Optimizing UnicastRoutingEngine no longer call CartesianRoutingEngine(优化UnicastRoutingEngine逻辑不在调用CartesianRoutingEngine)
4、Recover code with sharding by generated key condition(找回根据主键路由的部分代码)
5、Modify some code style(修改一些编码风格)
  • Loading branch information
maxiaoguang64 committed Apr 14, 2018
1 parent 29b864b commit 831ed6a
Show file tree
Hide file tree
Showing 25 changed files with 420 additions and 277 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*
* Copyright 1999-2015 dangdang.com.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* </p>
*/

package io.shardingjdbc.core.optimizer;

import com.google.common.collect.BoundType;
import com.google.common.collect.Range;
import io.shardingjdbc.core.api.algorithm.sharding.ListShardingValue;
import io.shardingjdbc.core.api.algorithm.sharding.RangeShardingValue;
import io.shardingjdbc.core.constant.ShardingOperator;
import io.shardingjdbc.core.exception.ShardingJdbcException;
import io.shardingjdbc.core.parsing.parser.context.condition.AndCondition;
import io.shardingjdbc.core.parsing.parser.context.condition.Column;
import io.shardingjdbc.core.parsing.parser.context.condition.Condition;
import io.shardingjdbc.core.parsing.parser.context.condition.GeneratedKeyCondition;
import io.shardingjdbc.core.parsing.parser.context.condition.OrCondition;
import io.shardingjdbc.core.routing.sharding.AlwaysFalseShardingCondition;
import io.shardingjdbc.core.routing.sharding.GeneratedKey;
import io.shardingjdbc.core.routing.sharding.ShardingCondition;
import io.shardingjdbc.core.routing.sharding.ShardingConditions;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
* Optimize engine.
*
* @author maxiaoguang
*/
public class OptimizeEngine {

/**
* Get sharding conditions.
*
* @param orCondition or condition
* @param parameters parameters
* @param generatedKey generated key
* @return sharding value
*/
public ShardingConditions getOptimizeShardingConditions(final OrCondition orCondition, final List<Object> parameters, final GeneratedKey generatedKey) {
ShardingConditions result = new ShardingConditions();
if (orCondition.isEmpty()) {
return result;
}
for (AndCondition each : orCondition.getAndConditions()) {
result.add(getOptimizeShardingCondition(each, parameters, generatedKey));
}
return result;
}

private ShardingCondition getOptimizeShardingCondition(final AndCondition andCondition, final List<Object> parameters, final GeneratedKey generatedKey) {
ShardingCondition result = new ShardingCondition();
Map<Column, List<Condition>> conditionsMap = getConditionsMap(andCondition, generatedKey);
for (Entry<Column, List<Condition>> entry : conditionsMap.entrySet()) {
List<Comparable<?>> listValue = null;
Range<Comparable<?>> rangeValue = null;
for (Condition each : entry.getValue()) {
List<Comparable<?>> values = getValues(each, parameters);
if (ShardingOperator.EQUAL == each.getOperator() || ShardingOperator.IN == each.getOperator()) {
listValue = getOptimizeValue(values, listValue);
if (null == listValue) {
return new AlwaysFalseShardingCondition();
}
}
if (ShardingOperator.BETWEEN == each.getOperator()) {
try {
rangeValue = getOptimizeValue(Range.range(values.get(0), BoundType.CLOSED, values.get(1), BoundType.CLOSED), rangeValue);
} catch (IllegalArgumentException e) {
return new AlwaysFalseShardingCondition();
} catch (ClassCastException e) {
throw new ShardingJdbcException("Found different types for sharding value `%s`.", entry.getKey());
}
}
}
if (null == listValue) {
result.add(new RangeShardingValue<>(entry.getKey().getTableName(), entry.getKey().getName(), rangeValue));
} else {
if (null != rangeValue) {
try {
listValue = getOptimizeValue(listValue, rangeValue);
} catch (ClassCastException e) {
throw new ShardingJdbcException("Found different types for sharding value `%s`.", entry.getKey());
}
}
if (null == listValue) {
return new AlwaysFalseShardingCondition();
}
result.add(new ListShardingValue<>(entry.getKey().getTableName(), entry.getKey().getName(), listValue));
}
}
return result;
}

private Map<Column, List<Condition>> getConditionsMap(final AndCondition andCondition, final GeneratedKey generatedKey) {
Map<Column, List<Condition>> result = new LinkedHashMap<>(andCondition.getConditions().size() + 1, 1);
for (Condition each : andCondition.getConditions()) {
if (!result.containsKey(each.getColumn())) {
result.put(each.getColumn(), new LinkedList<Condition>());
}
result.get(each.getColumn()).add(each);
}
if (null != generatedKey) {
result.put(generatedKey.getColumn(), Arrays.<Condition>asList(new GeneratedKeyCondition(generatedKey)));
}
return result;
}

private List<Comparable<?>> getValues(final Condition condition, final List<?> parameters) {
List<Comparable<?>> result = new LinkedList<>(condition.getPositionValueMap().values());
for (Entry<Integer, Integer> entry : condition.getPositionIndexMap().entrySet()) {
Object parameter = parameters.get(entry.getValue());
if (!(parameter instanceof Comparable<?>)) {
throw new ShardingJdbcException("Parameter `%s` should extends Comparable for sharding value.", parameter);
}
if (entry.getKey() < result.size()) {
result.add(entry.getKey(), (Comparable<?>) parameter);
} else {
result.add((Comparable<?>) parameter);
}
}
return result;
}

private List<Comparable<?>> getOptimizeValue(final List<Comparable<?>> listValue1, final List<Comparable<?>> listValue2) {
if (null == listValue1) {
return listValue2;
}
if (null == listValue2) {
return listValue1;
}
listValue1.retainAll(listValue2);
if (listValue1.isEmpty()) {
return null;
}
return listValue1;
}

private Range<Comparable<?>> getOptimizeValue(final Range<Comparable<?>> rangeValue1, final Range<Comparable<?>> rangeValue2) {
if (null == rangeValue1) {
return rangeValue2;
}
if (null == rangeValue2) {
return rangeValue1;
}
return rangeValue1.intersection(rangeValue2);
}

private List<Comparable<?>> getOptimizeValue(final List<Comparable<?>> listValue, final Range<Comparable<?>> rangeValue) {
List<Comparable<?>> result = new LinkedList<>();
for (Comparable<?> each : listValue) {
if (rangeValue.contains(each)) {
result.add(each);
}
}
if (result.isEmpty()) {
return null;
}
return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ public void parse(final InsertStatement insertStatement) {
Collection<Column> result = new LinkedList<>();
if (lexerEngine.equalAny(Symbol.LEFT_PAREN)) {
String tableName = insertStatement.getTables().getSingleTableName();
Optional<String> generateKeyColumn = shardingRule.getGenerateKeyColumn(tableName);
Optional<Column> generateKeyColumn = shardingRule.getGenerateKeyColumn(tableName);
int count = 0;
do {
lexerEngine.nextToken();
String columnName = SQLUtil.getExactlyValue(lexerEngine.getCurrentToken().getLiterals());
result.add(new Column(columnName, tableName));
lexerEngine.nextToken();
if (generateKeyColumn.isPresent() && generateKeyColumn.get().equalsIgnoreCase(columnName)) {
if (generateKeyColumn.isPresent() && generateKeyColumn.get().getName().equalsIgnoreCase(columnName)) {
insertStatement.setGenerateKeyColumnIndex(count);
}
count++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
* Insert values clause parser.
*
* @author zhangliang
* @author maxiaoguang
*/
public class InsertValuesClauseParser implements SQLClauseParser {

Expand Down Expand Up @@ -104,9 +105,9 @@ private void parseValues(final InsertStatement insertStatement) {
private GeneratedKeyCondition createGeneratedKeyCondition(final Column column, final SQLExpression sqlExpression) {
GeneratedKeyCondition result;
if (sqlExpression instanceof SQLPlaceholderExpression) {
result = new GeneratedKeyCondition(column.getName(), ((SQLPlaceholderExpression) sqlExpression).getIndex(), null);
result = new GeneratedKeyCondition(column, ((SQLPlaceholderExpression) sqlExpression).getIndex(), null);
} else if (sqlExpression instanceof SQLNumberExpression) {
result = new GeneratedKeyCondition(column.getName(), -1, ((SQLNumberExpression) sqlExpression).getNumber());
result = new GeneratedKeyCondition(column, -1, ((SQLNumberExpression) sqlExpression).getNumber());
} else {
throw new ShardingJdbcException("Generated key only support number.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ public void add(final Condition condition) {
*
* @param column column
* @return found condition
* @deprecated only test call
*/
@Deprecated
public Optional<Condition> find(final Column column) {
Condition result = null;
for (Condition each : conditions) {
Expand All @@ -67,14 +69,11 @@ public Optional<Condition> find(final Column column) {
* Get condition via index.
*
* @param index index of conditions
* @return found condition
* @return index of condition
* @throws IndexOutOfBoundsException if the index is out of range
*/
public Optional<Condition> get(final int index) {
Condition result = null;
if (size() > index) {
result = conditions.get(index);
}
return Optional.fromNullable(result);
public Condition get(final int index) {
return conditions.get(index);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@
* Condition.
*
* @author zhangliang
* @author maxiaoguang
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
@EqualsAndHashCode
@ToString
public final class Condition {
public class Condition {

private final Column column;

Expand Down Expand Up @@ -78,7 +79,7 @@ public Condition(final Column column, final List<SQLExpression> sqlExpressions)
count++;
}
}

private void init(final SQLExpression sqlExpression, final int position) {
if (sqlExpression instanceof SQLPlaceholderExpression) {
positionIndexMap.put(position, ((SQLPlaceholderExpression) sqlExpression).getIndex());
Expand All @@ -94,7 +95,9 @@ private void init(final SQLExpression sqlExpression, final int position) {
*
* @param parameters parameters
* @return sharding value
* @deprecated only test call
*/
@Deprecated
public ShardingValue getShardingValue(final List<?> parameters) {
List<Comparable<?>> conditionValues = getValues(parameters);
switch (operator) {
Expand All @@ -108,7 +111,7 @@ public ShardingValue getShardingValue(final List<?> parameters) {
}
}

public List<Comparable<?>> getValues(final List<?> parameters) {
private List<Comparable<?>> getValues(final List<?> parameters) {
List<Comparable<?>> result = new LinkedList<>(positionValueMap.values());
for (Entry<Integer, Integer> entry : positionIndexMap.entrySet()) {
Object parameter = parameters.get(entry.getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* Conditions collection.
*
* @author zhangliang
* @author maxiaoguang
*/
@NoArgsConstructor
@Getter
Expand Down Expand Up @@ -57,7 +58,9 @@ public void add(final Condition condition, final ShardingRule shardingRule) {
*
* @param column column
* @return found condition
* @deprecated only test call
*/
@Deprecated
public Optional<Condition> find(final Column column) {
return find(column, 0);
}
Expand All @@ -68,7 +71,9 @@ public Optional<Condition> find(final Column column) {
* @param column column
* @param index index of and conditions
* @return found condition
* @deprecated only test call
*/
@Deprecated
public Optional<Condition> find(final Column column, final int index) {
return orCondition.find(column, index);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,35 @@

package io.shardingjdbc.core.parsing.parser.context.condition;

import io.shardingjdbc.core.parsing.parser.expression.SQLNumberExpression;
import io.shardingjdbc.core.routing.sharding.GeneratedKey;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

/**
* Generated key condition.
*
* @author zhangliang
* @author maxiaoguang
*/
@RequiredArgsConstructor
@Getter
@ToString
public final class GeneratedKeyCondition {
public final class GeneratedKeyCondition extends Condition {

private final String column;
private final Column column;

private final int index;

private final Number value;

public GeneratedKeyCondition(final GeneratedKey generatedKey) {
this(generatedKey.getColumn(), generatedKey.getIndex(), generatedKey.getValue());
}

public GeneratedKeyCondition(final Column column, final int index, final Number value) {
super(column, new SQLNumberExpression(value));
this.column = column;
this.index = index;
this.value = value;
}
}
Loading

0 comments on commit 831ed6a

Please sign in to comment.