You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/10/21 02:04:27 UTC

[shardingsphere] branch master updated: fix AbstractRangeShardingAlgorithm class cast exception (#13186)

This is an automated email from the ASF dual-hosted git repository.

panjuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 63bdfe0  fix AbstractRangeShardingAlgorithm class cast exception (#13186)
63bdfe0 is described below

commit 63bdfe0f41612276f6702aba63efcd43cdc54d43
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Thu Oct 21 10:03:51 2021 +0800

    fix AbstractRangeShardingAlgorithm class cast exception (#13186)
    
    * adjust AbstractRangeShardingAlgorithm doSharding logic
    
    * add unit test case
---
 .../range/AbstractRangeShardingAlgorithm.java      | 24 +++++++-----
 .../range/BoundaryBasedRangeShardingAlgorithm.java |  4 +-
 .../range/VolumeBasedRangeShardingAlgorithm.java   |  4 +-
 .../BoundaryBasedRangeShardingAlgorithmTest.java   | 22 ++++++++++-
 .../VolumeBasedRangeShardingAlgorithmTest.java     | 44 ++++++++++++++++++++--
 5 files changed, 78 insertions(+), 20 deletions(-)

diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/AbstractRangeShardingAlgorithm.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/AbstractRangeShardingAlgorithm.java
index d58c976..6992762 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/AbstractRangeShardingAlgorithm.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/AbstractRangeShardingAlgorithm.java
@@ -34,9 +34,9 @@ import java.util.Properties;
 /**
  * Abstract range sharding algorithm.
  */
-public abstract class AbstractRangeShardingAlgorithm implements StandardShardingAlgorithm<Long>, ShardingAutoTableAlgorithm {
+public abstract class AbstractRangeShardingAlgorithm implements StandardShardingAlgorithm<Comparable<?>>, ShardingAutoTableAlgorithm {
     
-    private volatile Map<Integer, Range<Long>> partitionRange;
+    private volatile Map<Integer, Range<Comparable<?>>> partitionRange;
     
     @Getter
     @Setter
@@ -47,15 +47,15 @@ public abstract class AbstractRangeShardingAlgorithm implements StandardSharding
         partitionRange = calculatePartitionRange(props);
     }
     
-    protected abstract Map<Integer, Range<Long>> calculatePartitionRange(Properties props);
+    protected abstract Map<Integer, Range<Comparable<?>>> calculatePartitionRange(Properties props);
     
     @Override
-    public final String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<Long> shardingValue) {
+    public final String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<Comparable<?>> shardingValue) {
         return availableTargetNames.stream().filter(each -> each.endsWith(String.valueOf(getPartition(shardingValue.getValue())))).findFirst().orElse(null);
     }
     
     @Override
-    public final Collection<String> doSharding(final Collection<String> availableTargetNames, final RangeShardingValue<Long> shardingValue) {
+    public final Collection<String> doSharding(final Collection<String> availableTargetNames, final RangeShardingValue<Comparable<?>> shardingValue) {
         Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
         int firstPartition = getFirstPartition(shardingValue.getValueRange());
         int lastPartition = getLastPartition(shardingValue.getValueRange());
@@ -69,23 +69,27 @@ public abstract class AbstractRangeShardingAlgorithm implements StandardSharding
         return result;
     }
     
-    private int getFirstPartition(final Range<Long> valueRange) {
+    private int getFirstPartition(final Range<Comparable<?>> valueRange) {
         return valueRange.hasLowerBound() ? getPartition(valueRange.lowerEndpoint()) : 0;
     }
     
-    private int getLastPartition(final Range<Long> valueRange) {
+    private int getLastPartition(final Range<Comparable<?>> valueRange) {
         return valueRange.hasUpperBound() ? getPartition(valueRange.upperEndpoint()) : partitionRange.size() - 1;
     }
     
-    private Integer getPartition(final Long value) {
-        for (Entry<Integer, Range<Long>> entry : partitionRange.entrySet()) {
-            if (entry.getValue().contains(value)) {
+    private Integer getPartition(final Comparable<?> value) {
+        for (Entry<Integer, Range<Comparable<?>>> entry : partitionRange.entrySet()) {
+            if (entry.getValue().contains(getLongValue(value))) {
                 return entry.getKey();
             }
         }
         throw new UnsupportedOperationException("");
     }
     
+    private Long getLongValue(final Comparable<?> value) {
+        return Long.parseLong(value.toString());
+    }
+    
     @Override
     public final int getAutoTablesAmount() {
         return partitionRange.size();
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/BoundaryBasedRangeShardingAlgorithm.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/BoundaryBasedRangeShardingAlgorithm.java
index 8bf799f..adaf4bd 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/BoundaryBasedRangeShardingAlgorithm.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/BoundaryBasedRangeShardingAlgorithm.java
@@ -40,12 +40,12 @@ public final class BoundaryBasedRangeShardingAlgorithm extends AbstractRangeShar
     private static final String SHARDING_RANGES_KEY = "sharding-ranges";
     
     @Override
-    public Map<Integer, Range<Long>> calculatePartitionRange(final Properties props) {
+    public Map<Integer, Range<Comparable<?>>> calculatePartitionRange(final Properties props) {
         Preconditions.checkState(props.containsKey(SHARDING_RANGES_KEY), "Sharding ranges cannot be null.");
         List<Long> partitionRanges = Splitter.on(",").trimResults().splitToList(props.getProperty(SHARDING_RANGES_KEY))
                 .stream().map(Longs::tryParse).filter(Objects::nonNull).sorted().collect(Collectors.toList());
         Preconditions.checkArgument(CollectionUtils.isNotEmpty(partitionRanges), "Sharding ranges is not valid.");
-        Map<Integer, Range<Long>> result = new HashMap<>(partitionRanges.size() + 1, 1);
+        Map<Integer, Range<Comparable<?>>> result = new HashMap<>(partitionRanges.size() + 1, 1);
         for (int i = 0; i < partitionRanges.size(); i++) {
             Long rangeValue = partitionRanges.get(i);
             if (0 == i) {
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/VolumeBasedRangeShardingAlgorithm.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/VolumeBasedRangeShardingAlgorithm.java
index ccad987..1f70666 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/VolumeBasedRangeShardingAlgorithm.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/VolumeBasedRangeShardingAlgorithm.java
@@ -40,7 +40,7 @@ public final class VolumeBasedRangeShardingAlgorithm extends AbstractRangeShardi
     private static final String SHARDING_VOLUME_KEY = "sharding-volume";
     
     @Override
-    public Map<Integer, Range<Long>> calculatePartitionRange(final Properties props) {
+    public Map<Integer, Range<Comparable<?>>> calculatePartitionRange(final Properties props) {
         Preconditions.checkState(props.containsKey(RANGE_LOWER_KEY), "Lower range cannot be null.");
         Preconditions.checkState(props.containsKey(RANGE_UPPER_KEY), "Upper range cannot be null.");
         Preconditions.checkState(props.containsKey(SHARDING_VOLUME_KEY), "Sharding volume cannot be null.");
@@ -49,7 +49,7 @@ public final class VolumeBasedRangeShardingAlgorithm extends AbstractRangeShardi
         long volume = Long.parseLong(props.getProperty(SHARDING_VOLUME_KEY));
         Preconditions.checkArgument(upper - lower >= volume, "Range can not be smaller than volume.");
         int partitionSize = Math.toIntExact(LongMath.divide(upper - lower, volume, RoundingMode.CEILING));
-        Map<Integer, Range<Long>> result = new HashMap<>(partitionSize + 2, 1);
+        Map<Integer, Range<Comparable<?>>> result = new HashMap<>(partitionSize + 2, 1);
         result.put(0, Range.lessThan(lower));
         for (int i = 0; i < partitionSize; i++) {
             result.put(i + 1, Range.closedOpen(lower + i * volume, Math.min(lower + (i + 1) * volume, upper)));
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/BoundaryBasedRangeShardingAlgorithmTest.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/BoundaryBasedRangeShardingAlgorithmTest.java
index 21cbb2754..c009a8c 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/BoundaryBasedRangeShardingAlgorithmTest.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/BoundaryBasedRangeShardingAlgorithmTest.java
@@ -44,14 +44,27 @@ public final class BoundaryBasedRangeShardingAlgorithmTest {
     
     @Test
     public void assertPreciseDoSharding() {
+        assertPreciseDoSharding(new PreciseShardingValue<>("t_order", "order_id", 0L));
+    }
+    
+    private void assertPreciseDoSharding(final PreciseShardingValue<Comparable<?>> shardingValue) {
         List<String> availableTargetNames = Arrays.asList("t_order_0", "t_order_1", "t_order_2", "t_order_3");
-        assertThat(shardingAlgorithm.doSharding(availableTargetNames, new PreciseShardingValue<>("t_order", "order_id", 0L)), is("t_order_0"));
+        assertThat(shardingAlgorithm.doSharding(availableTargetNames, shardingValue), is("t_order_0"));
+    }
+    
+    @Test
+    public void assertPreciseDoShardingWithIntShardingValue() {
+        assertPreciseDoSharding(new PreciseShardingValue<>("t_order", "order_id", 0));
     }
     
     @Test
     public void assertRangeDoSharding() {
+        assertRangeDoSharding(new RangeShardingValue<>("t_order", "order_id", Range.closed(2L, 15L)));
+    }
+    
+    private void assertRangeDoSharding(final RangeShardingValue<Comparable<?>> shardingValue) {
         List<String> availableTargetNames = Arrays.asList("t_order_0", "t_order_1", "t_order_2", "t_order_3");
-        Collection<String> actual = shardingAlgorithm.doSharding(availableTargetNames, new RangeShardingValue<>("t_order", "order_id", Range.closed(2L, 15L)));
+        Collection<String> actual = shardingAlgorithm.doSharding(availableTargetNames, shardingValue);
         assertThat(actual.size(), is(3));
         assertTrue(actual.contains("t_order_1"));
         assertTrue(actual.contains("t_order_2"));
@@ -59,6 +72,11 @@ public final class BoundaryBasedRangeShardingAlgorithmTest {
     }
     
     @Test
+    public void assertRangeDoShardingWithIntShardingValue() {
+        assertRangeDoSharding(new RangeShardingValue<>("t_order", "order_id", Range.closed(2, 15)));
+    }
+    
+    @Test
     public void assertGetAutoTablesAmount() {
         BoundaryBasedRangeShardingAlgorithm shardingAlgorithm = new BoundaryBasedRangeShardingAlgorithm();
         shardingAlgorithm.getProps().setProperty("sharding-ranges", "1,5,10");
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/VolumeBasedRangeShardingAlgorithmTest.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/VolumeBasedRangeShardingAlgorithmTest.java
index c441a0a..4be9eb2 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/VolumeBasedRangeShardingAlgorithmTest.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/range/VolumeBasedRangeShardingAlgorithmTest.java
@@ -46,32 +46,63 @@ public final class VolumeBasedRangeShardingAlgorithmTest {
     
     @Test
     public void assertPreciseDoSharding() {
+        assertPreciseDoSharding(new PreciseShardingValue<>("t_order", "order_id", 0L));
+    }
+    
+    private void assertPreciseDoSharding(final PreciseShardingValue<Comparable<?>> shardingValue) {
         List<String> availableTargetNames = Arrays.asList("t_order_0", "t_order_1", "t_order_2", "t_order_3", "t_order_4", "t_order_5");
-        assertThat(shardingAlgorithm.doSharding(availableTargetNames, new PreciseShardingValue<>("t_order", "order_id", 0L)), is("t_order_0"));
+        assertThat(shardingAlgorithm.doSharding(availableTargetNames, shardingValue), is("t_order_0"));
+    }
+    
+    @Test
+    public void assertPreciseDoShardingWithIntShardingValue() {
+        assertPreciseDoSharding(new PreciseShardingValue<>("t_order", "order_id", 0));
     }
     
     @Test
     public void assertRangeDoShardingWithoutLowerBound() {
+        assertRangeDoShardingWithoutLowerBound(new RangeShardingValue<>("t_order", "order_id", Range.lessThan(12L)));
+    }
+    
+    private void assertRangeDoShardingWithoutLowerBound(final RangeShardingValue<Comparable<?>> shardingValue) {
         List<String> availableTargetNames = Arrays.asList("t_order_0", "t_order_1", "t_order_2", "t_order_3", "t_order_4", "t_order_5");
-        Collection<String> actual = shardingAlgorithm.doSharding(availableTargetNames, new RangeShardingValue<>("t_order", "order_id", Range.lessThan(12L)));
+        Collection<String> actual = shardingAlgorithm.doSharding(availableTargetNames, shardingValue);
         assertThat(actual.size(), is(2));
         assertTrue(actual.contains("t_order_0"));
         assertTrue(actual.contains("t_order_1"));
     }
     
     @Test
+    public void assertRangeDoShardingWithoutLowerBoundWithIntShardingValue() {
+        assertRangeDoShardingWithoutLowerBound(new RangeShardingValue<>("t_order", "order_id", Range.lessThan(12)));
+    }
+    
+    @Test
     public void assertRangeDoShardingWithoutUpperBound() {
+        assertRangeDoShardingWithoutUpperBound(new RangeShardingValue<>("t_order", "order_id", Range.greaterThan(40L)));
+    }
+    
+    private void assertRangeDoShardingWithoutUpperBound(final RangeShardingValue<Comparable<?>> shardingValue) {
         List<String> availableTargetNames = Arrays.asList("t_order_0", "t_order_1", "t_order_2", "t_order_3", "t_order_4", "t_order_5");
-        Collection<String> actual = shardingAlgorithm.doSharding(availableTargetNames, new RangeShardingValue<>("t_order", "order_id", Range.greaterThan(40L)));
+        Collection<String> actual = shardingAlgorithm.doSharding(availableTargetNames, shardingValue);
         assertThat(actual.size(), is(2));
         assertTrue(actual.contains("t_order_4"));
         assertTrue(actual.contains("t_order_5"));
     }
     
     @Test
+    public void assertRangeDoShardingWithoutUpperBoundWithIntShardingValue() {
+        assertRangeDoShardingWithoutUpperBound(new RangeShardingValue<>("t_order", "order_id", Range.greaterThan(40)));
+    }
+    
+    @Test
     public void assertRangeDoSharding() {
+        assertRangeDoSharding(new RangeShardingValue<>("t_order", "order_id", Range.closed(12L, 55L)));
+    }
+    
+    private void assertRangeDoSharding(final RangeShardingValue<Comparable<?>> shardingValue) {
         List<String> availableTargetNames = Arrays.asList("t_order_0", "t_order_1", "t_order_2", "t_order_3", "t_order_4", "t_order_5");
-        Collection<String> actual = shardingAlgorithm.doSharding(availableTargetNames, new RangeShardingValue<>("t_order", "order_id", Range.closed(12L, 55L)));
+        Collection<String> actual = shardingAlgorithm.doSharding(availableTargetNames, shardingValue);
         assertThat(actual.size(), is(5));
         assertTrue(actual.contains("t_order_1"));
         assertTrue(actual.contains("t_order_2"));
@@ -81,6 +112,11 @@ public final class VolumeBasedRangeShardingAlgorithmTest {
     }
     
     @Test
+    public void assertRangeDoShardingWithIntegerShardingValue() {
+        assertRangeDoSharding(new RangeShardingValue<>("t_order", "order_id", Range.closed(12, 55)));
+    }
+    
+    @Test
     public void assertGetAutoTablesAmount() {
         VolumeBasedRangeShardingAlgorithm shardingAlgorithm = new VolumeBasedRangeShardingAlgorithm();
         shardingAlgorithm.getProps().setProperty("range-lower", "10");