tiandihai commented on issue #29225:
URL: 
https://github.com/apache/shardingsphere/issues/29225#issuecomment-1828943671

   import com.google.common.base.Preconditions;
   import lombok.extern.slf4j.Slf4j;
   import 
org.apache.shardingsphere.sharding.api.sharding.hint.HintShardingAlgorithm;
   import 
org.apache.shardingsphere.sharding.api.sharding.hint.HintShardingValue;
   import 
org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
   import 
org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
   import 
org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
   
   import java.nio.charset.StandardCharsets;
   import java.util.Collection;
   import java.util.HashMap;
   import java.util.Map;
   import java.util.Properties;
   import java.util.stream.Collectors;
   
   /**
    * @Description:
    * @author wanglei10
    * @date 2023-08-02 11:35
    */
   @Slf4j
   public class DatabaseShardingAlgorithm implements 
StandardShardingAlgorithm<Comparable<?>>, HintShardingAlgorithm<Comparable<?>> {
   
       private final Map<Integer, String> partitionDatabaseMap = new 
HashMap<>();
   
       private volatile int partitionSize;
   
       @Override
       public void init(Properties properties) {
           calculatePartitionRange(properties);
       }
   
       private static final String DATABASE_SHARDING_RANGES = 
"database-sharding-ranges";
   
       public void calculatePartitionRange(final Properties props) {
           
Preconditions.checkState(props.containsKey(DATABASE_SHARDING_RANGES), "props: 
database-sharding-ranges cannot be null.");
           log.info("database-sharding-ranges配置:{}", 
props.getProperty(DATABASE_SHARDING_RANGES));
           String[] dsConfigs = 
props.getProperty(DATABASE_SHARDING_RANGES).split(",");
           Preconditions.checkState(dsConfigs.length > 0, "props: 
database-sharding-ranges配置错误,配置实例:db-0:0-15,db-1:16-31,db-2:32-47,db-3:48-63");
           for (String s : dsConfigs) {
               if (s != null && !s.trim().equals("")) {
                   String[] s1 = s.trim().split(":");
                   if (s1.length == 2) {
                       String dsName = s1[0].trim();
   
                       String[] s2 = s1[1].trim().split("-");
                       int start = Integer.parseInt(s2[0].trim());
                       int end = Integer.parseInt(s2[1].trim());
                       for (int i = start; i <= end; i++) {
                           partitionDatabaseMap.put(i, dsName);
                       }
                   } else {
                       log.warn("props: database-sharding-ranges配置可能出现错误:{}", 
s);
                   }
               }
           }
   
           partitionSize = partitionDatabaseMap.size();
   
           //解析后配置
           log.info("database-sharding-ranges解析后配置");
           partitionDatabaseMap.entrySet().stream()
                   .collect(Collectors.groupingBy(Map.Entry::getValue, 
Collectors.mapping(Map.Entry::getKey, Collectors.toList())))
                   .forEach((key, value) -> log.info("数据库:{},哈希值:{}-{}", key, 
value.get(0), value.get(value.size() - 1)));
       }
   
       @Override
       public Collection<String> doSharding(Collection<String> 
availableTargetNames, HintShardingValue<Comparable<?>> shardingValue) {
           return shardingValue.getValues().stream().map(it -> 
routeDatabase(availableTargetNames, it)).collect(Collectors.toList());
       }
   
       @Override
       public final String doSharding(final Collection<String> 
availableTargetNames, final PreciseShardingValue<Comparable<?>> shardingValue) {
           return routeDatabase(availableTargetNames, shardingValue.getValue());
       }
   
       private String routeDatabase(Collection<String> availableTargetNames, 
Comparable<?> value) {
           if (value == null) {
               throw new RuntimeException("shardingValue不能为空");
           }
   
           int slot = (int) 
(MurmurHash2.hash32(value.toString().getBytes(StandardCharsets.UTF_8), 2773) & 
0xFFFFFFFFL % partitionSize);
           String dbName = partitionDatabaseMap.get(slot);
           if (dbName == null) {
               throw new RuntimeException("database-sharding-ranges配置错误:" + 
value + "对应的配置不存在");
           }
           if (!availableTargetNames.contains(dbName)) {
               throw new RuntimeException("database-sharding-ranges配置错误:" + 
dbName + "数据库不存在");
           }
           return dbName;
       }
   
       @Override
       public final Collection<String> doSharding(final Collection<String> 
availableTargetNames, final RangeShardingValue<Comparable<?>> shardingValue) {
           return availableTargetNames;
       }
   
       @Override
       public String getType() {
           return "DATABASE-MOD-SHARDING";
       }
   }


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to