You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2020/12/11 13:20:21 UTC

[shardingsphere] branch master updated: Add Complex And Hint Inline Sharding Algorithm. (#8576)

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

zhangliang 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 49480c7  Add Complex And Hint Inline Sharding Algorithm. (#8576)
49480c7 is described below

commit 49480c746ef5465d5aee7c6cc39328ad444f9ed9
Author: likly <56...@qq.com>
AuthorDate: Fri Dec 11 21:20:07 2020 +0800

    Add Complex And Hint Inline Sharding Algorithm. (#8576)
    
    * Add Complex and Hint Inline sharding algorithm.
    
    * Update Complex and Hint Inline sharding algorithm docs
    
    * Add Complex and Hint Inline sharding algorithm license
    
    * Fix not config sharding-columns checkout sharing values keys size bug
    
    * fix checkstyle
    
    * remove file header info
    
    Co-authored-by: likly <li...@ilikly.com>
---
 .../built-in-algorithm/sharding.cn.md              |  23 ++-
 .../built-in-algorithm/sharding.en.md              |  23 ++-
 .../complex/ComplexInlineShardingAlgorithm.java    | 154 +++++++++++++++++++++
 .../sharding/hint/HintInlineShardingAlgorithm.java |  94 +++++++++++++
 ...e.shardingsphere.sharding.spi.ShardingAlgorithm |   2 +
 .../ComplexInlineShardingAlgorithmTest.java        | 100 +++++++++++++
 .../hint/HintInlineShardingAlgorithmTest.java      |  82 +++++++++++
 7 files changed, 474 insertions(+), 4 deletions(-)

diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/configuration/built-in-algorithm/sharding.cn.md b/docs/document/content/user-manual/shardingsphere-jdbc/configuration/built-in-algorithm/sharding.cn.md
index 053a455..3c7d0cd 100644
--- a/docs/document/content/user-manual/shardingsphere-jdbc/configuration/built-in-algorithm/sharding.cn.md
+++ b/docs/document/content/user-manual/shardingsphere-jdbc/configuration/built-in-algorithm/sharding.cn.md
@@ -95,11 +95,30 @@ Apache ShardingSphere 内置的标准分片算法实现类包括:
 
 ## 复合分片算法
 
-Apache ShardingSphere 暂无内置复合分片算法。
+### 复合行表达式分片算法
+
+详情请参见[行表达式](/cn/features/sharding/concept/inline-expression/)。
+
+类型:COMPLEX_INLINE
+
+| *属性名称*                                 | *数据类型* | *说明*                                              | *默认值* |
+| ----------------------------------------- | --------- | --------------------------------------------------- | ------- |
+| sharding-columns (?)                      | String    | 分片列名称,多个列用逗号分隔。如不配置无法则不能校验       | -       |
+| algorithm-expression                      | String    | 分片算法的行表达式                                    | -       |
+| allow-range-query-with-inline-sharding (?)| boolean   | 是否允许范围查询。注意:范围查询会无视分片策略,进行全路由 | false   |
+
 
 ## Hint 分片算法
 
-Apache ShardingSphere 暂无内置 Hint 分片算法。
+### Hint 行表达式分片算法
+
+详情请参见[行表达式](/cn/features/sharding/concept/inline-expression/)。
+
+类型:HINT_INLINE
+
+| *属性名称*                                 | *数据类型* | *说明*                                              | *默认值* |
+| ----------------------------------------- | --------- | --------------------------------------------------- | ------- |
+| algorithm-expression (?)                  | String    | 分片算法的行表达式                                    | ${value}|
 
 ## 自定义类分片算法
 
diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/configuration/built-in-algorithm/sharding.en.md b/docs/document/content/user-manual/shardingsphere-jdbc/configuration/built-in-algorithm/sharding.en.md
index 9fb152f..45c8878 100644
--- a/docs/document/content/user-manual/shardingsphere-jdbc/configuration/built-in-algorithm/sharding.en.md
+++ b/docs/document/content/user-manual/shardingsphere-jdbc/configuration/built-in-algorithm/sharding.en.md
@@ -96,11 +96,30 @@ Attributes:
 
 ## Complex Sharding Algorithm
 
-There is no built-in complex sharding algorithm in Apache ShardingSphere.
+### Complex Inline Sharding Algorithm
+
+Please refer to [Inline Expression](/en/features/sharding/concept/inline-expression/) for more details.
+
+Type: COMPLEX_INLINE
+
+| *Name*                                    | *DataType* | *Description*                                                                                            | *Default Value* |
+| ----------------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------- | --------------- |
+| sharding-columns (?)                      | String     | sharing column names                                                                                     | -               |
+| algorithm-expression                      | String     | Inline expression sharding algorithm                                                                     | -               |
+| allow-range-query-with-inline-sharding (?)| boolean    | Whether range query is allowed. Note: range query will ignore sharding strategy and conduct full routing | false           |
 
 ## Hint Sharding Algorithm
 
-There is no built-in hint sharding algorithm in Apache ShardingSphere.
+### Hint Inline Sharding Algorithm
+
+Please refer to [Inline Expression](/en/features/sharding/concept/inline-expression/) for more details.
+
+Type: COMPLEX_INLINE
+
+| *Name*                                    | *DataType* | *Description*                                                                                            | *Default Value* |
+| ----------------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------- | --------------- |
+| algorithm-expression                      | String     | Inline expression sharding algorithm                                                                     | ${value}        |
+
 
 ## Class Based Sharding Algorithm
 
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/complex/ComplexInlineShardingAlgorithm.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/complex/ComplexInlineShardingAlgorithm.java
new file mode 100644
index 0000000..04b5a2a
--- /dev/null
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/complex/ComplexInlineShardingAlgorithm.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shardingsphere.sharding.algorithm.sharding.complex;
+
+import com.google.common.base.Preconditions;
+import groovy.lang.Closure;
+import groovy.util.Expando;
+import org.apache.shardingsphere.sharding.algorithm.sharding.inline.InlineExpressionParser;
+import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingValue;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+/**
+ * Complex Inline sharding algorithm.
+ */
+public class ComplexInlineShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+    private static final String ALGORITHM_EXPRESSION_KEY = "algorithm-expression";
+
+    private static final String SHARING_COLUMNS_KEY = "sharding-columns";
+
+    private static final String ALLOW_RANGE_QUERY_KEY = "allow-range-query-with-inline-sharding";
+
+    private boolean allowRangeQuery;
+
+    private String[] shardingColumns;
+
+    private String algorithmExpression;
+
+    private final Properties props = new Properties();
+
+    @Override
+    public Collection<String> doSharding(final Collection<String> availableTargetNames, final ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+
+        if (!shardingValue.getColumnNameAndRangeValuesMap().isEmpty()) {
+            if (isAllowRangeQuery()) {
+                return availableTargetNames;
+            }
+
+            throw new UnsupportedOperationException("Since the property of `" + ALLOW_RANGE_QUERY_KEY + "` is false, inline sharding algorithm can not tackle with range query.");
+        }
+
+        Map<String, Collection<Comparable<?>>> columnNameAndShardingValuesMap = shardingValue.getColumnNameAndShardingValuesMap();
+
+        if (shardingColumns.length > 0 && shardingColumns.length != columnNameAndShardingValuesMap.size()) {
+            throw new IllegalArgumentException("complex inline need " + shardingColumns.length + " sharing columns, but only found " + columnNameAndShardingValuesMap.size());
+        }
+
+        Collection<Map<String, Comparable<?>>> combine = combine(columnNameAndShardingValuesMap);
+
+        return combine.stream()
+                .map(this::doSharding)
+                .collect(Collectors.toList());
+
+    }
+
+    private String doSharding(final Map<String, Comparable<?>> shardingValues) {
+        Closure<?> closure = createClosure();
+        for (Map.Entry<String, Comparable<?>> entry : shardingValues.entrySet()) {
+            closure.setProperty(entry.getKey(), entry.getValue());
+        }
+        return closure.call().toString();
+    }
+
+    @Override
+    public void init() {
+        String expression = props.getProperty(ALGORITHM_EXPRESSION_KEY);
+        Preconditions.checkNotNull(expression, "Inline sharding algorithm expression cannot be null.");
+        algorithmExpression = InlineExpressionParser.handlePlaceHolder(expression.trim());
+        initShardingColumns(props.getProperty(SHARING_COLUMNS_KEY, ""));
+        allowRangeQuery = Boolean.parseBoolean(props.getOrDefault(ALLOW_RANGE_QUERY_KEY, Boolean.FALSE.toString()).toString());
+    }
+
+    private void initShardingColumns(final String shardingColumns) {
+        if (shardingColumns.length() == 0) {
+            this.shardingColumns = new String[0];
+            return;
+        }
+        this.shardingColumns = shardingColumns.split(",");
+    }
+
+    private boolean isAllowRangeQuery() {
+        return allowRangeQuery;
+    }
+
+    private Closure<?> createClosure() {
+        Closure<?> result = new InlineExpressionParser(algorithmExpression).evaluateClosure().rehydrate(new Expando(), null, null);
+        result.setResolveStrategy(Closure.DELEGATE_ONLY);
+        return result;
+    }
+
+    @Override
+    public String getType() {
+        return "COMPLEX_INLINE";
+    }
+
+    @Override
+    public Properties getProps() {
+        return props;
+    }
+
+    @Override
+    public void setProps(final Properties props) {
+        this.props.clear();
+        this.props.putAll(props);
+    }
+
+    private static <K, V> Collection<Map<K, V>> combine(final Map<K, Collection<V>> map) {
+        Collection<Map<K, V>> result = new ArrayList<>();
+        for (Map.Entry<K, Collection<V>> entry : map.entrySet()) {
+            if (result.isEmpty()) {
+                for (V value : entry.getValue()) {
+                    Map<K, V> item = new HashMap<>();
+                    item.put(entry.getKey(), value);
+                    result.add(item);
+                }
+            } else {
+                Collection<Map<K, V>> list = new ArrayList<>();
+                for (Map<K, V> loop : result) {
+                    for (V value : entry.getValue()) {
+                        Map<K, V> item = new HashMap<>();
+                        item.put(entry.getKey(), value);
+                        item.putAll(loop);
+                        list.add(item);
+                    }
+                }
+                result = list;
+            }
+        }
+        return result;
+    }
+
+}
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java
new file mode 100644
index 0000000..e28c81b
--- /dev/null
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shardingsphere.sharding.algorithm.sharding.hint;
+
+import com.google.common.base.Preconditions;
+import groovy.lang.Closure;
+import groovy.util.Expando;
+import org.apache.shardingsphere.sharding.algorithm.sharding.inline.InlineExpressionParser;
+import org.apache.shardingsphere.sharding.api.sharding.hint.HintShardingAlgorithm;
+import org.apache.shardingsphere.sharding.api.sharding.hint.HintShardingValue;
+
+import java.util.Collection;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+/**
+ * Hint Inline sharding algorithm.
+ */
+public class HintInlineShardingAlgorithm implements HintShardingAlgorithm<Comparable<?>> {
+
+    private static final String ALGORITHM_EXPRESSION_KEY = "algorithm-expression";
+
+    private static final String DEFAULT_ALGORITHM_EXPRESSION = "${value}";
+
+    private static final String HINT_INLINE_VALUE_PROPERTY_NAME = "value";
+
+    private String algorithmExpression;
+
+    private final Properties properties = new Properties();
+
+    @Override
+    public Collection<String> doSharding(final Collection<String> availableTargetNames, final HintShardingValue<Comparable<?>> shardingValue) {
+
+        if (shardingValue.getValues().isEmpty()) {
+            return availableTargetNames;
+        }
+
+        return shardingValue.getValues().stream()
+                .map(this::doSharding)
+                .collect(Collectors.toList());
+
+    }
+
+    private String doSharding(final Comparable<?> shardingValue) {
+        Closure<?> closure = createClosure();
+        closure.setProperty(HINT_INLINE_VALUE_PROPERTY_NAME, shardingValue);
+        return closure.call().toString();
+    }
+
+    @Override
+    public void init() {
+        String expression = properties.getProperty(ALGORITHM_EXPRESSION_KEY, DEFAULT_ALGORITHM_EXPRESSION);
+        Preconditions.checkNotNull(expression, "Inline sharding algorithm expression cannot be null.");
+        algorithmExpression = InlineExpressionParser.handlePlaceHolder(expression.trim());
+    }
+
+    private Closure<?> createClosure() {
+        Closure<?> result = new InlineExpressionParser(algorithmExpression).evaluateClosure().rehydrate(new Expando(), null, null);
+        result.setResolveStrategy(Closure.DELEGATE_ONLY);
+        return result;
+    }
+
+    @Override
+    public String getType() {
+        return "HINT_INLINE";
+    }
+
+    @Override
+    public Properties getProps() {
+        return properties;
+    }
+
+    @Override
+    public void setProps(final Properties props) {
+        properties.clear();
+        properties.putAll(props);
+    }
+
+}
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/main/resources/META-INF/services/org.apache.shardingsphere.sharding.spi.ShardingAlgorithm b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/main/resources/META-INF/services/org.apache.shardingsphere.sharding.spi.ShardingAlgorithm
index 7b71c68..2af81f3 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/main/resources/META-INF/services/org.apache.shardingsphere.sharding.spi.ShardingAlgorithm
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/main/resources/META-INF/services/org.apache.shardingsphere.sharding.spi.ShardingAlgorithm
@@ -23,3 +23,5 @@ org.apache.shardingsphere.sharding.algorithm.sharding.range.BoundaryBasedRangeSh
 org.apache.shardingsphere.sharding.algorithm.sharding.datetime.AutoIntervalShardingAlgorithm
 org.apache.shardingsphere.sharding.algorithm.sharding.datetime.IntervalShardingAlgorithm
 org.apache.shardingsphere.sharding.algorithm.sharding.classbased.ClassBasedShardingAlgorithm
+org.apache.shardingsphere.sharding.algorithm.sharding.complex.ComplexInlineShardingAlgorithm
+org.apache.shardingsphere.sharding.algorithm.sharding.hint.HintInlineShardingAlgorithm
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/complex/ComplexInlineShardingAlgorithmTest.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/complex/ComplexInlineShardingAlgorithmTest.java
new file mode 100644
index 0000000..bbff5f3
--- /dev/null
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/complex/ComplexInlineShardingAlgorithmTest.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shardingsphere.sharding.algorithm.sharding.complex;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Range;
+import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingValue;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Complex Inline sharding algorithm test.
+ */
+public class ComplexInlineShardingAlgorithmTest {
+
+    private ComplexInlineShardingAlgorithm complexInlineShardingAlgorithm;
+
+    private ComplexInlineShardingAlgorithm complexInlineShardingAlgorithmAllowRangeQuery;
+
+    @Before
+    public void setUp() throws Exception {
+        initComplexInlineShardingAlgorithm();
+        initComplexInlineShardingAlgorithmAllowRangeQuery();
+    }
+
+    private void initComplexInlineShardingAlgorithm() {
+        complexInlineShardingAlgorithm = new ComplexInlineShardingAlgorithm();
+        complexInlineShardingAlgorithm.getProps().setProperty("algorithm-expression", "t_order_${type % 2}_${order_id % 2}");
+        complexInlineShardingAlgorithm.getProps().setProperty("sharding-columns", "type,order_id");
+        complexInlineShardingAlgorithm.init();
+    }
+
+    private void initComplexInlineShardingAlgorithmAllowRangeQuery() {
+        complexInlineShardingAlgorithmAllowRangeQuery = new ComplexInlineShardingAlgorithm();
+        complexInlineShardingAlgorithmAllowRangeQuery.getProps().setProperty("algorithm-expression", "t_order_${type % 2}_${order_id % 2}");
+        complexInlineShardingAlgorithmAllowRangeQuery.getProps().setProperty("sharding-columns", "type,order_id");
+        complexInlineShardingAlgorithmAllowRangeQuery.getProps().setProperty("allow-range-query-with-inline-sharding", "true");
+        complexInlineShardingAlgorithmAllowRangeQuery.init();
+    }
+
+    @Test
+    public void assertDoSharding() {
+        List<String> availableTargetNames = Lists.newArrayList("t_order_0_0", "t_order_0_1", "t_order_1_0", "t_order_1_1");
+        Map<String, Collection<Comparable<?>>> sharingValueMap = new HashMap<>();
+        sharingValueMap.put("type", Collections.singletonList(2));
+        sharingValueMap.put("order_id", Collections.singletonList(2));
+        Map<String, Range<Comparable<?>>> rangeShardingValueMap = new HashMap<>();
+        ComplexKeysShardingValue<Comparable<?>> shardingValue = new ComplexKeysShardingValue<>("t_order", sharingValueMap, rangeShardingValueMap);
+        Collection<String> actual = complexInlineShardingAlgorithm.doSharding(availableTargetNames, shardingValue);
+        assertTrue(actual.size() == 1 && actual.contains("t_order_0_0"));
+    }
+
+    @Test
+    public void assertDoShardingWithMultiValue() {
+        List<String> availableTargetNames = Lists.newArrayList("t_order_0_0", "t_order_0_1", "t_order_1_0", "t_order_1_1");
+        Map<String, Collection<Comparable<?>>> sharingValueMap = new HashMap<>();
+        sharingValueMap.put("type", Arrays.asList(1, 2));
+        sharingValueMap.put("order_id", Arrays.asList(1, 2));
+        Map<String, Range<Comparable<?>>> rangeShardingValueMap = new HashMap<>();
+        ComplexKeysShardingValue<Comparable<?>> shardingValue = new ComplexKeysShardingValue<>("t_order", sharingValueMap, rangeShardingValueMap);
+        Collection<String> actual = complexInlineShardingAlgorithm.doSharding(availableTargetNames, shardingValue);
+        assertTrue(actual.containsAll(availableTargetNames));
+    }
+
+    @Test
+    public void assertDoShardingWithRangeValue() {
+        List<String> availableTargetNames = Lists.newArrayList("t_order_0_0", "t_order_0_1", "t_order_1_0", "t_order_1_1");
+        Map<String, Collection<Comparable<?>>> sharingValueMap = new HashMap<>();
+        Map<String, Range<Comparable<?>>> rangeShardingValueMap = new HashMap<>();
+        rangeShardingValueMap.put("type", Range.all());
+        ComplexKeysShardingValue<Comparable<?>> shardingValue = new ComplexKeysShardingValue<>("t_order", sharingValueMap, rangeShardingValueMap);
+        Collection<String> actual = complexInlineShardingAlgorithmAllowRangeQuery.doSharding(availableTargetNames, shardingValue);
+        assertTrue(actual.containsAll(availableTargetNames));
+    }
+
+}
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithmTest.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithmTest.java
new file mode 100644
index 0000000..341649f
--- /dev/null
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-common/src/test/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithmTest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shardingsphere.sharding.algorithm.sharding.hint;
+
+import com.google.common.collect.Lists;
+import org.apache.shardingsphere.sharding.api.sharding.hint.HintShardingValue;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Hint Inline sharding algorithm test.
+ */
+public final class HintInlineShardingAlgorithmTest {
+
+    private HintInlineShardingAlgorithm hintInlineShardingAlgorithm;
+
+    private HintInlineShardingAlgorithm hintInlineShardingAlgorithmDefault;
+
+    @Before
+    public void setUp() {
+        initHintInlineShardingAlgorithm();
+        initHintInlineShardingAlgorithmDefault();
+    }
+
+    private void initHintInlineShardingAlgorithm() {
+        hintInlineShardingAlgorithm = new HintInlineShardingAlgorithm();
+        hintInlineShardingAlgorithm.getProps().setProperty("algorithm-expression", "t_order_$->{value % 4}");
+        hintInlineShardingAlgorithm.init();
+    }
+
+    private void initHintInlineShardingAlgorithmDefault() {
+        hintInlineShardingAlgorithmDefault = new HintInlineShardingAlgorithm();
+        hintInlineShardingAlgorithmDefault.init();
+    }
+
+    @Test
+    public void assertDoShardingWithSingleValueOfDefault() {
+        List<String> availableTargetNames = Lists.newArrayList("t_order_0", "t_order_1", "t_order_2", "t_order_3");
+        HintShardingValue<Comparable<?>> shardingValue = new HintShardingValue<>("t_order", "order_id", Collections.singleton("t_order_0"));
+        Collection<String> actual = hintInlineShardingAlgorithmDefault.doSharding(availableTargetNames, shardingValue);
+        assertTrue(actual.contains("t_order_0"));
+    }
+
+    @Test
+    public void assertDoShardingWithSingleValue() {
+        List<String> availableTargetNames = Lists.newArrayList("t_order_0", "t_order_1", "t_order_2", "t_order_3");
+        HintShardingValue<Comparable<?>> shardingValue = new HintShardingValue<>("t_order", "order_id", Collections.singleton(4));
+        Collection<String> actual = hintInlineShardingAlgorithm.doSharding(availableTargetNames, shardingValue);
+        assertTrue(actual.contains("t_order_0"));
+    }
+
+    @Test
+    public void assertDoShardingWithMultiValues() {
+        List<String> availableTargetNames = Lists.newArrayList("t_order_0", "t_order_1", "t_order_2", "t_order_3");
+        HintShardingValue<Comparable<?>> shardingValue = new HintShardingValue<>("t_order", "order_id", Arrays.asList(1, 2, 3, 4));
+        Collection<String> actual = hintInlineShardingAlgorithm.doSharding(availableTargetNames, shardingValue);
+        assertTrue(actual.containsAll(availableTargetNames));
+    }
+
+}