com.netflix.astyanax.partitioner.BOP20Partitioner Maven / Gradle / Ivy
package com.netflix.astyanax.partitioner;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.binary.Hex;
import com.google.common.collect.Lists;
import com.netflix.astyanax.connectionpool.TokenRange;
import com.netflix.astyanax.connectionpool.impl.TokenRangeImpl;
public class BOP20Partitioner implements Partitioner {
public static final String MINIMUM = "0000000000000000000000000000000000000000";
public static final String MAXIMUM = "ffffffffffffffffffffffffffffffffffffffff";
public static final BigInteger ONE = new BigInteger("1", 16);
public static final int KEY_LENGTH = 20;
@Override
public String getMinToken() {
return MINIMUM;
}
@Override
public String getMaxToken() {
return MAXIMUM;
}
@Override
public List splitTokenRange(String first, String last, int count) {
List tokens = Lists.newArrayList();
for (int i = 0; i < count; i++) {
String startToken = getTokenMinusOne(getSegmentToken(count, i, new BigInteger(first, 16), new BigInteger(last, 16)));
String endToken;
if (i == count-1 && last.equals(getMaxToken()))
endToken = getMinToken();
else
endToken = getSegmentToken(count, i+1, new BigInteger(first, 16), new BigInteger(last, 16));
tokens.add(new TokenRangeImpl(startToken, endToken, new ArrayList()));
}
return tokens;
}
@Override
public List splitTokenRange(int count) {
return splitTokenRange(getMinToken(), getMaxToken(), count);
}
@Override
public String getTokenForKey(ByteBuffer key) {
if (key.remaining() != KEY_LENGTH) {
throw new IllegalArgumentException("Key must be a 20 byte array");
}
return new String(Hex.encodeHexString(key.duplicate().array()));
}
@Override
public String getTokenMinusOne(String token) {
if (token.equals("0") || token.equals(MINIMUM))
return MAXIMUM;
return new BigInteger(token, 16).subtract(ONE).toString(16);
}
public static String getSegmentToken(int size, int position, BigInteger minInitialToken, BigInteger maxInitialToken ) {
BigInteger decValue = minInitialToken;
if (position != 0)
decValue = maxInitialToken.multiply(new BigInteger("" + position)).divide(new BigInteger("" + size));
return decValue.toString(16);
}
}