package io.mycat.route.function; /** * 跳增一致性哈希分片 * 思想源自Google公开论文,比传统一致性哈希更省资源速度更快数据迁移量更少 * * @author XiaoSK */ public final class PartitionByJumpConsistentHash extends AbstractPartitionAlgorithm implements RuleAlgorithm { private static final long UNSIGNED_MASK = 0x7fffffffffffffffL; private static final long JUMP = 1L << 31; // If JDK >= 1.8, just use Long.parseUnsignedLong("2862933555777941757") instead. private static final long CONSTANT = Long.parseLong("286293355577794175", 10) * 10 + 7; private int totalBuckets; @Override public Integer calculate(String columnValue) { return jumpConsistentHash(columnValue.hashCode(), totalBuckets); } public static int jumpConsistentHash(final long key, final int buckets) { checkBuckets(buckets); long k = key; long b = -1; long j = 0; while (j < buckets) { b = j; k = k * CONSTANT + 1L; j = (long) ((b + 1L) * (JUMP / toDouble((k >>> 33) + 1L))); } return (int) b; } private static void checkBuckets(final int buckets) { if (buckets < 0) { throw new IllegalArgumentException("Buckets cannot be less than 0"); } } private static double toDouble(final long n) { double d = n & UNSIGNED_MASK; if (n < 0) { d += 0x1.0p63; } return d; } public void setTotalBuckets(int totalBuckets) { this.totalBuckets = totalBuckets; } public int getTotalBuckets() { return totalBuckets; } }