最近,我正在阅读hadoop的权威指南。 我有两个问题:
1.我看到了一个自定义分区程序的代码:
public class KeyPartitioner extends Partitioner<TextPair, Text>{
@Override
public int getPartition(TextPair key, Text value, int numPartitions){
return (key.getFirst().hashCode()&Interger.MAX_VALUE)%numPartitions;
}
}
对于&amp; Integer.MAX_VALUE来说意味着什么?为什么要使用&amp;操作
2.我还想为IntWritable编写自定义分区程序。那么直接使用key.value%numPartitions是否合适?
答案 0 :(得分:11)
就像我在评论中写的那样,它用于保持结果整数为正。
让我们使用一个使用字符串的简单示例:
String h = "Hello I'm negative!";
int hashCode = h.hashCode();
hashCode
对-1937832979
的值为负。
如果您mod
使用表示分区的正数(> 0),则结果数字始终为负数。
System.out.println(hashCode % 5); // yields -4
由于分区永远不会是负数,因此您需要确保数字是正数。这里有一个简单的比特旋转技巧,因为Integer.MAX_VALUE
有一个全部执行符号位(Java中的MSB,因为它是大端),在负数上只有1。
因此,如果你设置了符号位的负数,你将永远AND
它与Integer.MAX_VALUE
的零点总是为零。
你可以使它更具可读性:
return Math.abs(key.getFirst().hashCode() % numPartitions);
例如I have done that in Apache Hama's partitioner用于任意对象:
@Override
public int getPartition(K key, V value, int numTasks) {
return Math.abs(key.hashCode() % numTasks);
}