青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 200, comments - 8, trackbacks - 0, articles - 0

hadoop 序列化源碼淺析 (轉(zhuǎn))

Posted on 2013-01-15 21:48 鑫龍 閱讀(1137) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Hadoop
轉(zhuǎn)自:http://my.oschina.net/tuzibuluo/blog?catalog=127826


1.Writable接口
         Hadoop 并沒有使用 JAVA 的序列化,而是引入了自己實(shí)的序列化系統(tǒng), package org.apache.hadoop.io 這個(gè)包中定義了大量的可序列化對(duì)象,這些對(duì)象都實(shí)現(xiàn)了 Writable 接口, Writable 接口是序列化對(duì)象的一個(gè)通用接口.我們來看下Writable 接口的定義。
public interface Writable{
  void write(DataOutput out) throws IOException;
  void readFields(DataInput in) throws IOException;
}
     Writable接口抽象了兩個(gè)序列化的方法WriteReadFields,分別對(duì)應(yīng)了序列化和反序列化,參數(shù)DataOutPut java.io包內(nèi)的IO類,Writable接口只是對(duì)象序列化的一個(gè)簡(jiǎn)單聲明。

2.WriteCompareable接口
      WriteCompareable接口是Wirtable接口的二次封裝,提供了compareTo(T o)方法,用于序列化對(duì)象的比較的比較。因?yàn)閙apreduce中間有個(gè)基于key的排序階段。
public interface WritableComparable<T> extends    Writable, Comparable<T> {
}
下面是io包簡(jiǎn)單的類圖關(guān)系。



3.RawComparator接口
     hadoop為序列化提供了優(yōu)化,類型的比較對(duì)M/R而言至關(guān)重要,Key和Key的比較也是在排序階段完成的,hadoop提供了原生的比較器接口RawComparator<T>用于序列化字節(jié)間的比較,該接口允許其實(shí)現(xiàn)直接比較數(shù)據(jù)流中的記錄,無需反序列化為對(duì)象,RawComparator是一個(gè)原生的優(yōu)化接口類,它只是簡(jiǎn)單的提供了用于數(shù)據(jù)流中簡(jiǎn)單的數(shù)據(jù)對(duì)比方法,從而提供優(yōu)化:
public interface RawComparator<T> extends Comparator<T> {
    public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2);
}
    該接口并非被多數(shù)的衍生類所實(shí)現(xiàn),其直接的子類為WritableComparator,多數(shù)情況下是作為實(shí)現(xiàn)Writable接口的類的內(nèi)置類,提供序列化字節(jié)的比較。下面是RawComparator接口內(nèi)置類的實(shí)現(xiàn)類圖:

      首先,我們看 RawComparator的直接實(shí)現(xiàn)類WritableComparator:

    WritableComparator類似于一個(gè)注冊(cè)表,里面通過靜態(tài)map記錄了所有WritableComparator類的集合。Comparators成員用一張Hash表記錄Key=Classvalue=WritableComprator的注冊(cè)信息.

WritableComparator主要提供了兩個(gè)功能

1.   提供了對(duì)原始compare()方法的一個(gè)默認(rèn)實(shí)現(xiàn)

默認(rèn)實(shí)現(xiàn)是 先反序列化為對(duì)像 再通過 對(duì)像比較(有開銷的問題),所以一般都會(huì)被具體writeCompatable類的Comparator類覆蓋以加快效率。

public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
    
try {
      buffer.reset(b1, s1, l1);                   
// parse key1
      key1.readFields(buffer);
     

      buffer.reset(b2, s2, l2);                   
// parse key2
      key2.readFields(buffer);
 

    } 
catch (IOException e) {
        
throw new RuntimeException(e);
    }
    
return compare(key1, key2);                   // compare them
}

2.    充當(dāng)RawComparable實(shí)例的工廠,以注冊(cè)Writable的實(shí)現(xiàn)

例如,為了獲取IntWritableComparator,可以直接調(diào)用其get方法。

4.WritableComparator
接下來?yè)礻P(guān)鍵代碼來分析writableComparator類,該類是RawComparator接口的直接子類。

代碼1registry 注冊(cè)器

// registry 注冊(cè)器:記載了WritableComparator類的集合

private static HashMap<ClassWritableComparator>comparators = new HashMap<Class, WritableComparator>();

----------------------------------------------------------------

代碼2獲取WritableComparator實(shí)例

說明:hashMap作為容器類線程不安全,故需要synchronized同步,get方法根據(jù)key=Class返回對(duì)應(yīng)的WritableComparator,若返回的是空值NUll,則調(diào)用protected Constructor進(jìn)行構(gòu)造,而其兩個(gè)protected的構(gòu)造函數(shù)實(shí)則是調(diào)用了newKey()方法進(jìn)行NewInstance

public static synchronized WritableComparator get(Class<? extends WritableComparable> c) {
   WritableComparator comparator 
= comparators.get(c);
   
if (comparator == null)
     comparator 
= new WritableComparator(c, true);
   
return comparator;
 }

----------------------------------------------------------------
代碼3:WritableComparator構(gòu)造方法

new WritableComparator(c, true)

WritableComparator的構(gòu)造函數(shù)源碼如下:

 

/* 
   * keyClass,key1,key2和buffer都是用于WritableComparator的構(gòu)造函數(shù)
   
*/
  
private final Class<? extends WritableComparable> keyClass;

  
private final WritableComparable key1;  //WritableComparable接口

  
private final WritableComparable key2;   

  
private final DataInputBuffer buffer;      //輸入緩沖流

protected WritableComparator(Class<? extends WritableComparable> keyClass,boolean createInstances) {

    
this.keyClass = keyClass;
    
if (createInstances) {
      key1 
= newKey();
      key2 
= newKey();
      buffer 
= new DataInputBuffer();
    } 
else {
      key1 
= key2 = null;
      buffer = null;
    }

}
上述的keyClasskey1,key2,buffer是記錄HashMap對(duì)應(yīng)的key值,用于WritableComparator的構(gòu)造函數(shù),但由其構(gòu)造函數(shù)中我們可以看出WritableComparator根據(jù)Boolean createInstance來判斷是否實(shí)例化key1,key2buffer,key1,key2是用于接收比較的兩個(gè)key。WritableComparator的構(gòu)造函數(shù)里面通過newKey()的方法去實(shí)例化實(shí)現(xiàn)WritableComparable接口的一個(gè)對(duì)象,下面是newKey()的源碼,通過hadoop自身的反射去實(shí)例化了一個(gè)WritableComparable接口對(duì)象。
public WritableComparable newKey() {
    
return ReflectionUtils.newInstance(keyClass, null);
  }

----------------------------------------------------------------
代碼4Compare()方法

(1).   public int compare(Object a, Object b)

(2).     public int compare(WritableComparable a, WritableComparable b)

(3).     public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)

    三個(gè)compare()重載方法中,compare(Object a, Object b)利用子類塑形為WritableComparable而調(diào)用了第2個(gè)compare方法,而第2個(gè)Compare()方法則調(diào)用了Writable.compaerTo();最后一個(gè)compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)方法源碼如下:
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
    
try {
      buffer.reset(b1, s1, l1);                   
// parse key1
      key1.readFields(buffer);

      buffer.reset(b2, s2, l2);                   
// parse key2
      key2.readFields(buffer);

    } 
catch (IOException e) {
      
throw new RuntimeException(e);
    }

    
return compare(key1, key2);                   // compare them
  }

Compare方法的一個(gè)缺省實(shí)現(xiàn)方式,根據(jù)接口key1,ke2反序列化為對(duì)象再進(jìn)行比較。

利用Buffer為橋接中介,把字節(jié)數(shù)組存儲(chǔ)為buffer后,調(diào)用key1WritableComparable)的反序列化方法,再來比較key1,ke2,由此處可以看出,該compare方法是將要比較的二進(jìn)制流反序列化為對(duì)象,再調(diào)用方法第2個(gè)重載方法進(jìn)行比較。

----------------------------------------------------------------

代碼5:方法define方法

    該方法用于注冊(cè)WritebaleComparaor對(duì)象到注冊(cè)表中,注意同時(shí)該方法也需要同步,代碼如下:

public static synchronized void define(Class c, WritableComparator comparator) {
    comparators.put(c, comparator);
}

----------------------------------------------------------------
代碼6余下諸如readInt的靜態(tài)方法

    這些方法用于實(shí)現(xiàn)WritableComparable的各種實(shí)例,例如 IntWritable實(shí)例:內(nèi)部類Comparator類需要根據(jù)自己的IntWritable類型重載WritableComparator里面的compare()方法,可以說WritableComparator里面的compare()方法只是提供了一個(gè)缺省的實(shí)現(xiàn),而真正的compare()方法實(shí)現(xiàn)需要根據(jù)自己的類型如IntWritable進(jìn)行重載,所以WritableComparator方法中的那些readInt..等方法只是底層的封裝的一個(gè)實(shí)現(xiàn),方便內(nèi)部Comparator進(jìn)行調(diào)用而已。

 下面我們著重看下BooleanWritable類的內(nèi)置RawCompartor<T>的實(shí)現(xiàn)過程:

public static class Comparator extends WritableComparator {
    public Comparator() {//調(diào)用父類的Constructor初始化keyClass=BooleanWrite.class
      super(BooleanWritable.class);
    }

    //重寫父類的序列化比較方法,用些類用到父類提供的缺省方法

    public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
      boolean a = (readInt(b1, s1) == 1) ? true : false;
      boolean b = (readInt(b2, s2) == 1) ? true : false;
      return ((a == b) ? 0 : (a == false) ? -1 : 1);
    }
  }

  //注冊(cè)
  static {
    WritableComparator.define(BooleanWritable.classnew Comparator());
  }

總結(jié):

        hadoop 類似于Java的類包,即提供了Comparable接口(對(duì)應(yīng)于writableComparable接口)和Comparator類(對(duì)應(yīng)于RawComparator類)用于實(shí)現(xiàn)序列化的比較,在hadoop 的IO包中已經(jīng)封裝了JAVA的基本數(shù)據(jù)類型用于序列化和反序列化,一般自己寫的類實(shí)現(xiàn)序列化和反序列化需要繼承WritableComparable接口并且內(nèi)置一個(gè)Comparator(繼承于WritableComparator)的格式來實(shí)現(xiàn)自己的對(duì)象。

5.WritableFactory接口
      作為工廠模式的WritableFactory,其抽象為一個(gè)接口,提供了具體的Writable對(duì)象創(chuàng)建實(shí)例的抽象方法newInstance(),代碼如下:

 public interface WritableFactory {

  /** Return a new instance. */
  Writable newInstance();
}
      WritableFactories類類似于WritableComparator類利用HashMap注冊(cè)記錄著所有實(shí)現(xiàn)上述接口的WritableFactory的集合,與之不同的是WritableFactories是一個(gè)單例模式,所有的方法都是靜態(tài)的。
關(guān)鍵代碼:
//提供了一個(gè)key=class,value=WritableFactory的注冊(cè)表
   private static final HashMap<Class, WritableFactory> CLASS_TO_FACTORY = new HashMap<Class, WritableFactory>();

  public static Writable newInstance(Class<? extends Writable> c, Configuration conf) {

    WritableFactory factory = WritableFactories.getFactory(c);
    if (factory != null) {
//該方法的newInstanceof是調(diào)用了factory.newInstance()即你了實(shí)現(xiàn)的WritableFactory的newInstance()方法
      Writable result = factory.newInstance();
      
      if (result instanceof Configurable) {
        ((Configurable) result).setConf(conf);
      }
      return result;
   
    } else {
      return ReflectionUtils.newInstance(c, conf);
    }
}


6.InputBuffer和DataInputBuffer
       類似于JAVA.IO 的裝飾器模式, InputBuffer輸入緩沖和DataInputBuffer數(shù)據(jù)緩沖的實(shí)現(xiàn)封裝于內(nèi)部類Buffer,該類的功能只是提供一個(gè)空的緩沖區(qū),用于存儲(chǔ)數(shù)據(jù)。Buffer代碼如下:
private static class Buffer extends ByteArrayInputStream {
   public Buffer() {
     super(new byte[] {});
   }
 
   public void reset(byte[] input, int start, int length) {
     this.buf = input;
     this.count = start+length;
     this.mark = start;
     this.pos = start;
   }
 
   public int getPosition() { return pos; }
   public int getLength() { return count; }
 }
     InputBuffer和DataInputBuffer的方法委托于內(nèi)部類private Buffer buffer,例如InputBuffer部分代碼:
/** Returns the current position in the input. */
 public int getPosition() { return buffer.getPosition(); }

 /** Returns the length of the input. */

 public int getLength() { return buffer.getLength(); }
    DataInputBuffer 內(nèi)置的Buffer代碼如下
    private static class Buffer extends ByteArrayInputStream {
   public Buffer() {
     super(new byte[] {});
   }

   public void reset(byte[] input, int start, int length) {
     this.buf = input;
     this.count = start+length;
     this.mark = start;
     this.pos = start;
   }

   public byte[] getData() { return buf; }
   public int getPosition() { return pos; }
   public int getLength() { return count; }
}
    兩個(gè)類封裝的Buffer一樣,而其方法也都委托依賴于buffer,只是InputBuffer和DataInputBuffer繼承于不同的類,如下:

DataInputBuffer:
public class DataInputBuffer extends DataInputStream {
}

InputBuffer:
public class InputBuffer extends FilterInputStream {
}

7.OutputBuffer和DataOutputBuffe
       類似于上文的InputBuffer和DataInputBuffer,hadoop 的OutputBuffer和DataOutputBuffer的實(shí)現(xiàn)與之相似,同樣是利用內(nèi)部類的引用,而關(guān)鍵的代碼在于內(nèi)部類Buffer:

private static class Buffer extends ByteArrayOutputStream {
    public byte[] getData() { return buf; }
    public int getLength() { return count; }
    public void reset() { count = 0; }

    public void write(InputStream in, int len) throws IOException {
      int newcount = count + len;
      if (newcount > buf.length) {
        byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)];
        System.arraycopy(buf, 0, newbuf, 0, count);
        buf = newbuf;
      }
      IOUtils.readFully(in, buf, count, len);
      count = newcount;
    }
}
先是判斷buf數(shù)組的length,倘若空間不足,則new newbuf[] 利用Sysytem的數(shù)組拷貝實(shí)現(xiàn)內(nèi)容的復(fù)制。

 

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美一级理论性理论a| 雨宫琴音一区二区在线| 99在线热播精品免费99热| 亚洲国产精品一区二区www在线| 99视频精品全部免费在线| 伊人春色精品| 最新成人在线| 99国内精品| 亚洲一区二区伦理| 性欧美xxxx大乳国产app| 久久丁香综合五月国产三级网站| 久久久一本精品99久久精品66| 麻豆国产va免费精品高清在线| 蜜臀久久99精品久久久画质超高清| 欧美不卡高清| 欧美韩日高清| 亚洲精品色图| 亚洲线精品一区二区三区八戒| 亚洲男女毛片无遮挡| 久久精品99国产精品| 裸体歌舞表演一区二区| 欧美视频一区在线观看| 国产日韩精品电影| 亚洲国产精品成人| 午夜精品久久久久久久| 欧美成人免费视频| 亚洲网在线观看| 久久综合久久综合久久| 欧美日韩一区二区在线观看| 国产麻豆日韩| 亚洲三级免费| 久久国产精品久久国产精品| 亚洲国产日韩欧美在线99 | 亚洲自拍偷拍麻豆| 久久久久久亚洲精品杨幂换脸 | 亚洲欧美日韩精品一区二区| 久久婷婷蜜乳一本欲蜜臀| 欧美色精品在线视频| 1000部精品久久久久久久久| 欧美一区二区三区四区夜夜大片| 亚洲国产日韩欧美在线图片| 久久精品国产99精品国产亚洲性色| 欧美欧美全黄| 最近中文字幕mv在线一区二区三区四区| 午夜精品久久久久久久久久久久| 欧美a级一区| 久久成人这里只有精品| 国产精品免费aⅴ片在线观看| 亚洲精品午夜精品| 美女网站在线免费欧美精品| 欧美一级黄色录像| 国产精品裸体一区二区三区| 一本久道久久综合婷婷鲸鱼| 免费观看欧美在线视频的网站| 亚洲一区二区三区四区中文| 欧美日韩妖精视频| 一区二区三区www| 亚洲国产女人aaa毛片在线| 久久久精品动漫| 韩国一区二区在线观看| 久久精品1区| 欧美在线欧美在线| 国产一区二区三区在线观看网站| 国产精品99久久99久久久二8 | 蜜乳av另类精品一区二区| 国产精品视频久久一区| 亚洲一区精彩视频| 亚洲免费观看在线观看| 欧美日韩国产一区二区三区| 亚洲美女视频在线免费观看| 欧美激情导航| 欧美国产在线观看| 在线午夜精品自拍| 一区二区三区**美女毛片| 国产精品www网站| 午夜精品久久久久久| 久久精品91| 日韩一级精品| 亚洲神马久久| 国产一区二区三区在线观看免费| 美国成人毛片| 欧美成人性生活| 亚洲午夜小视频| 欧美一区不卡| 亚洲欧洲一区二区三区久久| 亚洲精品乱码久久久久久蜜桃91 | 国产精品久久久久久亚洲调教| 亚洲欧美一区二区三区极速播放| 亚洲男人影院| 在线成人小视频| 亚洲日本欧美| 国产精品一区二区久久| 美女黄色成人网| 欧美日韩在线观看视频| 久久九九热re6这里有精品| 久久亚洲欧洲| 亚洲午夜激情| 久久久久国产免费免费| 亚洲乱码国产乱码精品精天堂 | 亚洲精品国产精品乱码不99 | 欧美专区在线播放| 亚洲每日更新| 性欧美xxxx视频在线观看| 亚洲二区免费| 在线视频亚洲一区| 亚洲欧美日韩精品久久久久| 亚洲国产日韩一级| 亚洲欧美在线观看| 99国产麻豆精品| 久久婷婷色综合| 久久精品国产精品亚洲精品| 欧美女激情福利| 欧美肥婆bbw| 国产欧美精品一区aⅴ影院| 国产精品卡一卡二| 亚洲男女自偷自拍图片另类| 亚洲欧美激情一区二区| 最新亚洲视频| 久久都是精品| 午夜一区二区三区在线观看| 欧美高清视频在线| 久久一区欧美| 国产网站欧美日韩免费精品在线观看| 最新亚洲激情| 亚洲欧洲日夜超级视频| 久久久久久久一区二区| 久久精品99国产精品| 国产精品毛片大码女人| 亚洲卡通欧美制服中文| 亚洲日本欧美日韩高观看| 久久精品av麻豆的观看方式| 欧美一区在线直播| 国产精品一区二区a| 亚洲尤物精选| 午夜精品网站| 国产精品夜夜夜| 一区二区三区国产| 中文精品99久久国产香蕉| 欧美一区二区三区啪啪| 亚欧美中日韩视频| 国产日韩欧美综合| 欧美一区二区在线播放| 久久久久成人精品免费播放动漫| 国产精品美女999| 99re亚洲国产精品| 亚洲综合精品自拍| 国产精品护士白丝一区av| 日韩视频精品在线| 亚洲视频观看| 国产精品高潮视频| 亚洲综合视频一区| 欧美一区二区三区婷婷月色 | 国产精品亚洲产品| 亚洲在线电影| 久久精品天堂| 国产亚洲毛片| 久久精品国产一区二区三区免费看 | 亚洲午夜激情网页| 国产美女精品人人做人人爽| 亚洲综合日韩在线| 久久久精品欧美丰满| 在线成人av| 欧美激情一二三区| 亚洲精品一区二区三区四区高清| 亚洲一区二区三区精品在线| 欧美日韩一区二区在线播放| 亚洲视频www| 久久久夜夜夜| 亚洲精品无人区| 国产日本欧美视频| 美女在线一区二区| 日韩小视频在线观看| 午夜精品久久久99热福利| 在线观看亚洲a| 免费亚洲网站| 亚洲国产经典视频| 91久久午夜| 亚洲破处大片| 亚洲欧美国产不卡| 亚洲一二三级电影| 亚洲线精品一区二区三区八戒| 久久精品国产欧美亚洲人人爽| 性欧美videos另类喷潮| 亚洲制服丝袜在线| 欧美va天堂在线| 亚洲国产高清高潮精品美女| 亚洲欧美日韩中文播放| 免费毛片一区二区三区久久久| 男女激情视频一区| 一区二区三区精品久久久| 欧美成人精品三级在线观看 | 国产有码一区二区| 国产欧美一区二区精品婷婷| 亚洲日本va午夜在线电影| 在线一区二区三区做爰视频网站 | 欧美调教vk| 国产精品国产自产拍高清av| 国产欧美大片| 一区二区三区 在线观看视频| 免费久久精品视频|