/** * Returns a list of pseudo-random 32-bit values derived from the specified end point ID. */ private List<Integer> computeHashCodes(String endPointId) { // Use the libketama approach of using MD5 hashes to generate 32-bit random values. This assigns a set of // randomly generated ranges to each end point. The individual ranges may vary widely in size, but, with // sufficient # of entries per end point, the overall amount of data assigned to each server tends to even out // with minimal variation (256 entries per server yields roughly 5% variation in server load). List<Integer> list = Lists.newArrayListWithCapacity(_entriesPerEndPoint); for (int i = 0; list.size() < _entriesPerEndPoint; i++) { Hasher hasher = Hashing.md5().newHasher(); hasher.putInt(i); putUnencodedChars(hasher, endPointId); ByteBuffer buf = ByteBuffer.wrap(hasher.hash().asBytes()); while (buf.hasRemaining() && list.size() < _entriesPerEndPoint) { list.add(buf.getInt()); } } return list; }
private HashCode getPartitionHash(PartitionContext partitionContext) { // The precise implementation of this method isn't particularly important. There are lots of ways we can hash // the data in the PartitionContext. It just needs to be deterministic and to take into account the values in // the PartitionContext for the configured partition keys. Hasher hasher = Hashing.md5().newHasher(); boolean empty = true; if (_partitionKeys.isEmpty()) { // Use the default context. Object value = partitionContext.get(); if (value != null) { putUnencodedChars(hasher, value.toString()); empty = false; } } for (String partitionKey : _partitionKeys) { Object value = partitionContext.get(partitionKey); if (value != null) { // Include both the key and value in the hash so "reviewId" of 1 and "reviewerId" of 1 hash differently. putUnencodedChars(hasher, partitionKey); putUnencodedChars(hasher, value.toString()); empty = false; } } if (empty) { // When the partition context has no relevant values that means we should ignore the partition context and // don't filter the end points based on partition. Return null to indicate this. return null; } return hasher.hash(); }
private HashCode getPartitionHash(PartitionContext partitionContext) { // The precise implementation of this method isn't particularly important. There are lots of ways we can hash // the data in the PartitionContext. It just needs to be deterministic and to take into account the values in // the PartitionContext for the configured partition keys. Hasher hasher = Hashing.md5().newHasher(); boolean empty = true; if (_partitionKeys.isEmpty()) { // Use the default context. Object value = partitionContext.get(); if (value != null) { putUnencodedChars(hasher, value.toString()); empty = false; } } for (String partitionKey : _partitionKeys) { Object value = partitionContext.get(partitionKey); if (value != null) { // Include both the key and value in the hash so "reviewId" of 1 and "reviewerId" of 1 hash differently. putUnencodedChars(hasher, partitionKey); putUnencodedChars(hasher, value.toString()); empty = false; } } if (empty) { // When the partition context has no relevant values that means we should ignore the partition context and // don't filter the end points based on partition. Return null to indicate this. return null; } return hasher.hash(); }
/** * Returns a list of pseudo-random 32-bit values derived from the specified end point ID. */ private List<Integer> computeHashCodes(String endPointId) { // Use the libketama approach of using MD5 hashes to generate 32-bit random values. This assigns a set of // randomly generated ranges to each end point. The individual ranges may vary widely in size, but, with // sufficient # of entries per end point, the overall amount of data assigned to each server tends to even out // with minimal variation (256 entries per server yields roughly 5% variation in server load). List<Integer> list = Lists.newArrayListWithCapacity(_entriesPerEndPoint); for (int i = 0; list.size() < _entriesPerEndPoint; i++) { Hasher hasher = Hashing.md5().newHasher(); hasher.putInt(i); putUnencodedChars(hasher, endPointId); ByteBuffer buf = ByteBuffer.wrap(hasher.hash().asBytes()); while (buf.hasRemaining() && list.size() < _entriesPerEndPoint) { list.add(buf.getInt()); } } return list; }