提交 26179fac 编写于 作者: T terrymanu

refactor ShardingStrategy: auto merge in, split range strategy 23th version

上级 cb0d4929
......@@ -20,12 +20,10 @@ package com.dangdang.ddframe.rdb.sharding.routing.strategy;
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.routing.strategy.complex.ComplexKeysShardingAlgorithm;
import com.dangdang.ddframe.rdb.sharding.routing.strategy.hint.HintShardingAlgorithm;
import com.google.common.base.Preconditions;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.Collection;
import java.util.Collections;
import java.util.TreeSet;
/**
......@@ -54,38 +52,17 @@ public class ShardingStrategy {
* @param shardingValues sharding values
* @return sharding results for data sources or tables's names
*/
public Collection<String> doStaticSharding(final Collection<String> availableTargetNames, final Collection<ShardingValue> shardingValues) {
Collection<String> result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
if (shardingValues.isEmpty()) {
result.addAll(availableTargetNames);
public Collection<String> doSharding(final Collection<String> availableTargetNames, final Collection<ShardingValue> shardingValues) {
Collection<String> shardingResult;
if (shardingAlgorithm instanceof HintShardingAlgorithm) {
shardingResult = ((HintShardingAlgorithm) shardingAlgorithm).doSharding(availableTargetNames, shardingValues.iterator().next());
} else if (shardingAlgorithm instanceof ComplexKeysShardingAlgorithm) {
shardingResult = ((ComplexKeysShardingAlgorithm) shardingAlgorithm).doSharding(availableTargetNames, shardingValues);
} else {
result.addAll(doSharding(shardingValues, availableTargetNames));
throw new UnsupportedOperationException(shardingAlgorithm.getClass().getName());
}
return result;
}
/**
* Calculate dynamic sharding info.
*
* @param shardingValues sharding values
* @return sharding results for data sources or tables's names
*/
public Collection<String> doDynamicSharding(final Collection<ShardingValue> shardingValues) {
Preconditions.checkState(!shardingValues.isEmpty(), "Dynamic table should contain sharding value.");
Collection<String> availableTargetNames = Collections.emptyList();
Collection<String> result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
result.addAll(doSharding(shardingValues, availableTargetNames));
result.addAll(shardingResult);
return result;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private Collection<String> doSharding(final Collection<ShardingValue> shardingValues, final Collection<String> availableTargetNames) {
if (shardingAlgorithm instanceof HintShardingAlgorithm) {
return ((HintShardingAlgorithm) shardingAlgorithm).doSharding(availableTargetNames, shardingValues.iterator().next());
}
if (shardingAlgorithm instanceof ComplexKeysShardingAlgorithm) {
return ((ComplexKeysShardingAlgorithm) shardingAlgorithm).doSharding(availableTargetNames, shardingValues);
}
throw new UnsupportedOperationException(shardingAlgorithm.getClass().getName());
}
}
......@@ -17,13 +17,18 @@
package com.dangdang.ddframe.rdb.sharding.routing.strategy.standard;
import com.dangdang.ddframe.rdb.sharding.api.ListShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.PreciseShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.RangeShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.routing.strategy.ShardingStrategy;
import com.google.common.base.Optional;
import lombok.Getter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;
/**
......@@ -50,33 +55,40 @@ public final class StandardShardingStrategy extends ShardingStrategy {
this.rangeShardingAlgorithm = Optional.fromNullable(rangeShardingAlgorithm);
}
/**
* Calculate precise sharding info.
*
* @param availableTargetNames available data sources or tables's names
* @param shardingValue sharding value
* @return sharding results for data sources or tables's names
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public String doPreciseSharding(final Collection<String> availableTargetNames, final PreciseShardingValue shardingValue) {
return preciseShardingAlgorithm.doSharding(availableTargetNames, shardingValue);
public Collection<String> doSharding(final Collection<String> availableTargetNames, final ShardingValue shardingValue) {
Collection<String> shardingResult = shardingValue instanceof ListShardingValue
? doSharding(availableTargetNames, (ListShardingValue) shardingValue) : doSharding(availableTargetNames, (RangeShardingValue) shardingValue);
Collection<String> result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
result.addAll(shardingResult);
return result;
}
/**
* Calculate range sharding info.
*
* @param availableTargetNames available data sources or tables's names
* @param shardingValue sharding value
* @return sharding results for data sources or tables's names
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public Collection<String> doRangeSharding(final Collection<String> availableTargetNames, final RangeShardingValue shardingValue) {
@SuppressWarnings("unchecked")
private Collection<String> doSharding(final Collection<String> availableTargetNames, final RangeShardingValue shardingValue) {
if (!rangeShardingAlgorithm.isPresent()) {
throw new UnsupportedOperationException("Cannot find range sharding strategy in sharding rule.");
}
return rangeShardingAlgorithm.get().doSharding(availableTargetNames, shardingValue);
}
@SuppressWarnings("unchecked")
private Collection<String> doSharding(final Collection<String> availableTargetNames, final ListShardingValue shardingValue) {
Collection<String> result = new LinkedList<>();
for (PreciseShardingValue<?> eachTableShardingValue : transferToPreciseShardingValues(shardingValue)) {
result.add(preciseShardingAlgorithm.doSharding(availableTargetNames, eachTableShardingValue));
}
return result;
}
@SuppressWarnings("unchecked")
private List<PreciseShardingValue> transferToPreciseShardingValues(final ListShardingValue<?> shardingValue) {
List<PreciseShardingValue> result = new ArrayList<>(shardingValue.getValues().size());
for (Comparable<?> each : shardingValue.getValues()) {
result.add(new PreciseShardingValue(shardingValue.getLogicTableName(), shardingValue.getColumnName(), each));
}
return result;
}
@Override
public Collection<String> getShardingColumns() {
Collection<String> result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
......
......@@ -53,7 +53,7 @@ public final class DatabaseHintRoutingEngine implements RoutingEngine {
Preconditions.checkState(shardingValue.isPresent());
log.debug("Before database sharding only db:{} sharding values: {}", dataSourceRule.getDataSourceNames(), shardingValue.get());
Collection<String> routingDataSources;
routingDataSources = databaseShardingStrategy.doStaticSharding(dataSourceRule.getDataSourceNames(), Collections.singleton(shardingValue.get()));
routingDataSources = databaseShardingStrategy.doSharding(dataSourceRule.getDataSourceNames(), Collections.singleton(shardingValue.get()));
Preconditions.checkState(!routingDataSources.isEmpty(), "no database route info");
log.debug("After database sharding only result: {}", routingDataSources);
RoutingResult result = new RoutingResult();
......
......@@ -17,9 +17,6 @@
package com.dangdang.ddframe.rdb.sharding.routing.type.simple;
import com.dangdang.ddframe.rdb.sharding.api.ListShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.PreciseShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.RangeShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataNode;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
......@@ -42,7 +39,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
......@@ -120,53 +116,33 @@ public final class SimpleRoutingEngine implements RoutingEngine {
}
private Collection<String> routeDataSources(final TableRule tableRule, final List<ShardingValue> databaseShardingValues) {
Collection<String> availableTargetDatabases = tableRule.getActualDatasourceNames();
if (databaseShardingValues.isEmpty()) {
return availableTargetDatabases;
}
ShardingStrategy strategy = shardingRule.getDatabaseShardingStrategy(tableRule);
if (strategy instanceof StandardShardingStrategy && !databaseShardingValues.isEmpty()) {
if (isPreciseSharding(databaseShardingValues)) {
Collection<String> result = new LinkedList<>();
Collection<PreciseShardingValue> preciseDatabaseShardingValues = transferToShardingValues((ListShardingValue<?>) databaseShardingValues.get(0));
for (PreciseShardingValue<?> eachDatabaseShardingValue : preciseDatabaseShardingValues) {
result.add(((StandardShardingStrategy) strategy).doPreciseSharding(tableRule.getActualDatasourceNames(), eachDatabaseShardingValue));
}
return result;
}
return ((StandardShardingStrategy) strategy).doRangeSharding(tableRule.getActualDatasourceNames(), (RangeShardingValue) databaseShardingValues.get(0));
if (strategy instanceof StandardShardingStrategy) {
return ((StandardShardingStrategy) strategy).doSharding(availableTargetDatabases, databaseShardingValues.get(0));
}
Collection<String> result = shardingRule.getDatabaseShardingStrategy(tableRule).doStaticSharding(tableRule.getActualDatasourceNames(), databaseShardingValues);
Collection<String> result = strategy.doSharding(tableRule.getActualDatasourceNames(), databaseShardingValues);
Preconditions.checkState(!result.isEmpty(), "no database route info");
return result;
}
private Collection<String> routeTables(final TableRule tableRule, final String routedDataSource, final List<ShardingValue> tableShardingValues) {
ShardingStrategy strategy = shardingRule.getTableShardingStrategy(tableRule);
if (tableShardingValues.isEmpty() && tableRule.isDynamic()) {
throw new UnsupportedOperationException("Dynamic table should contain sharding value.");
}
Collection<String> availableTargetTables = tableRule.isDynamic() ? Collections.<String>emptyList() : tableRule.getActualTableNames(routedDataSource);
if (strategy instanceof StandardShardingStrategy && !tableShardingValues.isEmpty()) {
if (isPreciseSharding(tableShardingValues)) {
Collection<String> result = new LinkedList<>();
Collection<PreciseShardingValue> preciseTableShardingValues = transferToShardingValues((ListShardingValue<?>) tableShardingValues.get(0));
for (PreciseShardingValue<?> eachTableShardingValue : preciseTableShardingValues) {
result.add(((StandardShardingStrategy) strategy).doPreciseSharding(availableTargetTables, eachTableShardingValue));
}
return result;
}
return ((StandardShardingStrategy) strategy).doRangeSharding(availableTargetTables, (RangeShardingValue) tableShardingValues.get(0));
if (tableShardingValues.isEmpty()) {
return availableTargetTables;
}
Collection<String> result =
tableRule.isDynamic() ? strategy.doDynamicSharding(tableShardingValues) : strategy.doStaticSharding(tableRule.getActualTableNames(routedDataSource), tableShardingValues);
Preconditions.checkState(!result.isEmpty(), "no table route info");
return result;
}
private boolean isPreciseSharding(final List<ShardingValue> shardingValues) {
return 1 == shardingValues.size() && !(shardingValues.get(0) instanceof RangeShardingValue);
}
@SuppressWarnings("unchecked")
private List<PreciseShardingValue> transferToShardingValues(final ListShardingValue<?> shardingValue) {
List<PreciseShardingValue> result = new ArrayList<>(shardingValue.getValues().size());
for (Comparable<?> each : shardingValue.getValues()) {
result.add(new PreciseShardingValue(shardingValue.getLogicTableName(), shardingValue.getColumnName(), each));
ShardingStrategy strategy = shardingRule.getTableShardingStrategy(tableRule);
if (strategy instanceof StandardShardingStrategy) {
return ((StandardShardingStrategy) strategy).doSharding(availableTargetTables, tableShardingValues.get(0));
}
Collection<String> result = strategy.doSharding(availableTargetTables, tableShardingValues);
Preconditions.checkState(!result.isEmpty(), "no table route info");
return result;
}
......
......@@ -26,7 +26,6 @@ import com.dangdang.ddframe.rdb.sharding.api.strategy.fixture.TestRangeShardingA
import com.dangdang.ddframe.rdb.sharding.api.strategy.sharding.NoneShardingAlgorithm;
import com.dangdang.ddframe.rdb.sharding.routing.strategy.ShardingStrategy;
import com.dangdang.ddframe.rdb.sharding.routing.strategy.standard.StandardShardingStrategy;
import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
import org.junit.Test;
......@@ -44,40 +43,27 @@ public final class ShardingStrategyTest {
@Test
public void assertDoStaticShardingWithoutShardingColumns() {
ShardingStrategy strategy = new ShardingStrategy(Sets.newHashSet("column"), new NoneShardingAlgorithm());
assertThat(strategy.doStaticSharding(targets, Collections.<ShardingValue>emptySet()), is(targets));
assertThat(strategy.doSharding(targets, Collections.<ShardingValue>emptySet()), is(targets));
}
@Test
public void assertDoStaticShardingForBetweenSingleKey() {
StandardShardingStrategy strategy = new StandardShardingStrategy("column", new TestPreciseShardingAlgorithm(), new TestRangeShardingAlgorithm());
assertThat(strategy.doRangeSharding(targets, new RangeShardingValue<>("logicTable", "column", Range.open("1", "3"))),
is((Collection<String>) Lists.newArrayList("1", "2", "3")));
assertThat(strategy.doSharding(targets, new RangeShardingValue<>("logicTable", "column", Range.open("1", "3"))),
is((Collection<String>) Sets.newHashSet("1", "2", "3")));
}
@Test
public void assertDoStaticShardingForMultipleKeys() {
ShardingStrategy strategy = new ShardingStrategy(Collections.singletonList("column"), new TestComplexKeysShardingAlgorithm());
assertThat(strategy.doStaticSharding(targets, Collections.<ShardingValue>singletonList(new PreciseShardingValue<>("logicTable", "column", "1"))),
assertThat(strategy.doSharding(targets, Collections.<ShardingValue>singletonList(new PreciseShardingValue<>("logicTable", "column", "1"))),
is((Collection<String>) Sets.newHashSet("1", "2", "3")));
}
@Test(expected = IllegalStateException.class)
public void assertDoDynamicShardingWithoutShardingColumns() {
ShardingStrategy strategy = new ShardingStrategy(Sets.newHashSet("column"), null);
strategy.doDynamicSharding(Collections.<ShardingValue>emptySet());
}
@Test
public void assertDoDynamicShardingForBetweenSingleKey() {
StandardShardingStrategy strategy = new StandardShardingStrategy("column", new TestPreciseShardingAlgorithm(), new TestRangeShardingAlgorithm());
assertThat(strategy.doRangeSharding(Collections.<String>emptyList(), new RangeShardingValue<>("logicTable", "column", Range.open("1", "3"))),
is((Collection<String>) Lists.newArrayList("1", "2", "3")));
}
@Test
public void assertDoDynamicShardingForMultipleKeys() {
ShardingStrategy strategy = new ShardingStrategy(Collections.singletonList("column"), new TestComplexKeysShardingAlgorithm());
assertThat(strategy.doDynamicSharding(Collections.<ShardingValue>singletonList(new PreciseShardingValue<>("logicTable", "column", "1"))),
is((Collection<String>) Collections.<String>emptySet()));
assertThat(strategy.doSharding(Collections.<String>emptyList(), new RangeShardingValue<>("logicTable", "column", Range.open("1", "3"))),
is((Collection<String>) Sets.newHashSet("1", "2", "3")));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册