// Path: src/main/java/com/hyd/ssdb/util/MD5.java
// public class MD5 {
// 
//     /**
//      * 利用 md5 生成字符串的 hashCode
//      *
//      * @param str 要签名的字符串
//      *
//      * @return 签名的 hash
//      */
//     public static int md5Hash(String str) {
//         try {
//             MessageDigest digest = MessageDigest.getInstance("MD5");
//             byte[] bytes = digest.digest(str.getBytes("UTF-8"));
//             return b2i(bytes);
//         } catch (NoSuchAlgorithmException e) {
//             throw new RuntimeException(e);
//         } catch (UnsupportedEncodingException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     public static int b2i(byte[] b) {
//         int value = 0;
//         for (int i = 0; i < 4; i++) {
//             int shift = (4 - 1 - i) * 8;
//             value += (b[i] & 0x000000FF) << shift;
//         }
//         return value;
//     }
// }
// 
// Path: src/main/java/com/hyd/ssdb/util/Range.java
// public class Range<T extends Number> {
// 
//     private T min;
// 
//     private T max;
// 
//     public Range(T min, T max) {
//         this.min = min;
//         this.max = max;
//     }
// 
//     public T getMin() {
//         return min;
//     }
// 
//     public void setMin(T min) {
//         this.min = min;
//     }
// 
//     public T getMax() {
//         return max;
//     }
// 
//     public void setMax(T max) {
//         this.max = max;
//     }
// 
//     public boolean contains(T value) {
//         if (value instanceof Integer) {
//             return (Integer) this.min <= (Integer) value && (Integer) value <= (Integer) this.max;
//         } else if (value instanceof Long) {
//             return (Long) this.min <= (Long) value && (Long) value <= (Long) this.max;
//         } else if (value instanceof Double) {
//             return (Double) this.min <= (Double) value && (Double) value <= (Double) this.max;
//         } else if (value instanceof Float) {
//             return (Float) this.min <= (Float) value && (Float) value <= (Float) this.max;
//         } else if (value instanceof Short) {
//             return (Short) this.min <= (Short) value && (Short) value <= (Short) this.max;
//         } else if (value instanceof Byte) {
//             return (Byte) this.min <= (Byte) value && (Byte) value <= (Byte) this.max;
//         } else {
//             throw new UnsupportedOperationException("Type '" + value.getClass() + "' not supported.");
//         }
//     }
// 
//     public Range<T> duplicate() {
//         return new Range<T>(min, max);
//     }
// 
//     @Override
//     public String toString() {
//         return "Range{" +
//             "min=" + min +
//             ", max=" + max +
//             '}';
//     }
// }


import com.hyd.ssdb.*;
import com.hyd.ssdb.conf.*;
import com.hyd.ssdb.util.MD5;
import com.hyd.ssdb.util.Range;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
package com.hyd.ssdb.sharding;


/**
 * 基于一致性哈希的分片策略。这是 hydrogen-ssdb 实现的缺省分片策略。
 * <p></p>
 * ConsistentHashSharding 有一个属性叫做 {@link #spofStrategy}，用于决定当出现单点故障时如何处理。
 * <p></p>
 * created at 15-12-8
 *
 * @author Yiding
 */
public class ConsistentHashSharding extends Sharding {

    private static final Logger LOG = LoggerFactory.getLogger(ConsistentHashSharding.class);

    /**
     * 单点故障处理策略，参考 {@link SPOFStrategy}
     */
    private SPOFStrategy spofStrategy = SPOFStrategy.AutoExpandStrategy;

    public ConsistentHashSharding(Cluster cluster) {
        super(cluster);
    }

    //////////////////////////////////////////////////////////////

    public ConsistentHashSharding(List<Cluster> clusters) {
        super(clusters);
    }

    public ConsistentHashSharding(Cluster... clusters) {
        super(Arrays.asList(clusters));
    }

    public SPOFStrategy getSpofStrategy() {
        return spofStrategy;
    }

    public void setSpofStrategy(SPOFStrategy spofStrategy) {
        this.spofStrategy = spofStrategy;
    }

// Path: src/main/java/com/hyd/ssdb/util/MD5.java
// public class MD5 {
// 
//     /**
//      * 利用 md5 生成字符串的 hashCode
//      *
//      * @param str 要签名的字符串
//      *
//      * @return 签名的 hash
//      */
//     public static int md5Hash(String str) {
//         try {
//             MessageDigest digest = MessageDigest.getInstance("MD5");
//             byte[] bytes = digest.digest(str.getBytes("UTF-8"));
//             return b2i(bytes);
//         } catch (NoSuchAlgorithmException e) {
//             throw new RuntimeException(e);
//         } catch (UnsupportedEncodingException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     public static int b2i(byte[] b) {
//         int value = 0;
//         for (int i = 0; i < 4; i++) {
//             int shift = (4 - 1 - i) * 8;
//             value += (b[i] & 0x000000FF) << shift;
//         }
//         return value;
//     }
// }
// 
// Path: src/main/java/com/hyd/ssdb/util/Range.java
// public class Range<T extends Number> {
// 
//     private T min;
// 
//     private T max;
// 
//     public Range(T min, T max) {
//         this.min = min;
//         this.max = max;
//     }
// 
//     public T getMin() {
//         return min;
//     }
// 
//     public void setMin(T min) {
//         this.min = min;
//     }
// 
//     public T getMax() {
//         return max;
//     }
// 
//     public void setMax(T max) {
//         this.max = max;
//     }
// 
//     public boolean contains(T value) {
//         if (value instanceof Integer) {
//             return (Integer) this.min <= (Integer) value && (Integer) value <= (Integer) this.max;
//         } else if (value instanceof Long) {
//             return (Long) this.min <= (Long) value && (Long) value <= (Long) this.max;
//         } else if (value instanceof Double) {
//             return (Double) this.min <= (Double) value && (Double) value <= (Double) this.max;
//         } else if (value instanceof Float) {
//             return (Float) this.min <= (Float) value && (Float) value <= (Float) this.max;
//         } else if (value instanceof Short) {
//             return (Short) this.min <= (Short) value && (Short) value <= (Short) this.max;
//         } else if (value instanceof Byte) {
//             return (Byte) this.min <= (Byte) value && (Byte) value <= (Byte) this.max;
//         } else {
//             throw new UnsupportedOperationException("Type '" + value.getClass() + "' not supported.");
//         }
//     }
// 
//     public Range<T> duplicate() {
//         return new Range<T>(min, max);
//     }
// 
//     @Override
//     public String toString() {
//         return "Range{" +
//             "min=" + min +
//             ", max=" + max +
//             '}';
//     }
// }


// Path: src/main/java/com/hyd/ssdb/sharding/ConsistentHashSharding.java
import com.hyd.ssdb.*;
import com.hyd.ssdb.conf.*;
import com.hyd.ssdb.util.MD5;
import com.hyd.ssdb.util.Range;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

package com.hyd.ssdb.sharding;


/**
 * 基于一致性哈希的分片策略。这是 hydrogen-ssdb 实现的缺省分片策略。
 * <p></p>
 * ConsistentHashSharding 有一个属性叫做 {@link #spofStrategy}，用于决定当出现单点故障时如何处理。
 * <p></p>
 * created at 15-12-8
 *
 * @author Yiding
 */
public class ConsistentHashSharding extends Sharding {

    private static final Logger LOG = LoggerFactory.getLogger(ConsistentHashSharding.class);

    /**
     * 单点故障处理策略，参考 {@link SPOFStrategy}
     */
    private SPOFStrategy spofStrategy = SPOFStrategy.AutoExpandStrategy;

    public ConsistentHashSharding(Cluster cluster) {
        super(cluster);
    }

    //////////////////////////////////////////////////////////////

    public ConsistentHashSharding(List<Cluster> clusters) {
        super(clusters);
    }

    public ConsistentHashSharding(Cluster... clusters) {
        super(Arrays.asList(clusters));
    }

    public SPOFStrategy getSpofStrategy() {
        return spofStrategy;
    }

    public void setSpofStrategy(SPOFStrategy spofStrategy) {
        this.spofStrategy = spofStrategy;
    }

    public Map<String, Range<Integer>> getRangeMap() {