Avoid thread contention in FBUtilities.hash

Patch by brandonwilliams and jbellis, reviewed by brandonwilliams for
CASSANDRA-1369

git-svn-id: https://svn.apache.org/repos/asf/cassandra/branches/cassandra-0.7@1053457 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brandon Williams 2010-12-28 21:55:37 +00:00
parent 25258f968e
commit 671de68026
2 changed files with 24 additions and 6 deletions

View File

@ -80,7 +80,7 @@ public class RandomPartitioner implements IPartitioner<BigIntegerToken>
public BigIntegerToken getRandomToken()
{
BigInteger token = FBUtilities.md5hash(GuidGenerator.guidAsBytes());
BigInteger token = FBUtilities.hashToBigInteger(GuidGenerator.guidAsBytes());
if ( token.signum() == -1 )
token = token.multiply(BigInteger.valueOf(-1L));
return new BigIntegerToken(token);
@ -126,7 +126,7 @@ public class RandomPartitioner implements IPartitioner<BigIntegerToken>
{
if (key.remaining() == 0)
return MINIMUM;
return new BigIntegerToken(FBUtilities.md5hash(key));
return new BigIntegerToken(FBUtilities.hashToBigInteger(key));
}
public Map<Token, Float> describeOwnership(List<Token> sortedTokens)

View File

@ -28,6 +28,7 @@ import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@ -64,6 +65,22 @@ public class FBUtilities
private static volatile InetAddress localInetAddress_;
private static final ThreadLocal<MessageDigest> localMessageDigest = new ThreadLocal<MessageDigest>()
{
@Override
protected MessageDigest initialValue()
{
try
{
return MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException e)
{
throw new AssertionError(e);
}
}
};
public static final int MAX_UNSIGNED_SHORT = 0xFFFF;
/**
@ -218,19 +235,20 @@ public class FBUtilities
return out;
}
public static BigInteger md5hash(ByteBuffer data)
public static BigInteger hashToBigInteger(ByteBuffer data)
{
byte[] result = hash("MD5", data);
byte[] result = hash(data);
BigInteger hash = new BigInteger(result);
return hash.abs();
}
public static byte[] hash(String type, ByteBuffer... data)
public static byte[] hash(ByteBuffer... data)
{
byte[] result;
try
{
MessageDigest messageDigest = MessageDigest.getInstance(type);
MessageDigest messageDigest = localMessageDigest.get();
messageDigest.reset();
for(ByteBuffer block : data)
messageDigest.update(block.array(),block.position()+block.arrayOffset(),block.remaining());
result = messageDigest.digest();