在前面的博文《Hadoop中WritableComparable 和 comparator》中,对于WritableComparator说的不够细致,下面说说具体的实现原理!
1.WritableComparator主要提供了两个功能:
- 提供了对原始compara()方法的一个默认实现,默认实现是先反序列化成对象,在对对象进行比较
1 public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) { 2 3 try { 4 5 buffer.reset(b1, s1, l1); // parse key1 6 7 key1.readFields(buffer); 8 9 10 11 buffer.reset(b2, s2, l2); // parse key2 12 13 key2.readFields(buffer); 14 15 16 17 } catch (IOException e) { 18 19 throw new RuntimeException(e); 20 21 } 22 23 24 25 return compare(key1, key2); // compare them 26 27 }
而对应的基础数据类型的compare()的实现却巧妙的利用了特定类型的泛化:(利用了writableComparable的compareTo方法)
1 public int compare(WritableComparable a, WritableComparable b) { 2 3 return a.compareTo(b); 4 5 }
- 充当RawComparator的注册工厂,通过get()方法,得到实例。
在WritableComparator中,private static HashMap<Class, WritableComparator>comparators =new HashMap<Class, WritableComparator>();记载着RawComparator实例,例如,可以通过下面的代码,获得一个IntWritable类型的RawComparator。
RawComparator<IntWritable> writable = WritableComparator.get(IntWritable.class);
2.WritableComparator如何注册定制的Writable
在WritableComparator类中,有一个方法define,通过该方法,可以将Writable注册到WritableComparator,以便可以通过get方法,直接获得实例!
1 public static synchronized void define(Class c,WritableComparator comparator) { 2 comparators.put(c, comparator); 3 }
3.BooleanWritable中内置Comparator的实现
WritableComparable的各种实例,例如 IntWritable实例:内部类Comparator类需要根据自己的IntWritable类型重载WritableComparator里面的compare()方法,可以说WritableComparator里面的compare()方法只是提供了一个缺省的实现,而真正的compare()方法实现需要根据自己的类型如IntWritable进行重载,所以WritableComparator方法中的那些readInt..等方法只是底层的封装的一个实现,方便内部Comparator进行调用而已。
下面我们着重看下BooleanWritable类的内置RawCompartor<T>的实现过程:
1 ** 2 * A Comparator optimized for BooleanWritable. 3 */ 4 public static class Comparator extends WritableComparator { 5 public Comparator() {//调用父类的Constructor初始化keyClass=BooleanWrite.class 6 super(BooleanWritable.class); 7 } 8 //重写父类的序列化比较方法,用些类用到父类提供的缺省方法 9 public int compare(byte[] b1, int s1, int l1, 10 byte[] b2, int s2, int l2) { 11 boolean a = (readInt(b1, s1) == 1) ? true : false; 12 boolean b = (readInt(b2, s2) == 1) ? true : false; 13 return ((a == b) ? 0 : (a == false) ? -1 : 1); 14 } 15 } 16 //注册 17 static { 18 WritableComparator.define(BooleanWritable.class, new Comparator()); 19 }