Hadoop中Comparator原理


在前面的博文《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        }

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM