hadoop AbstractMapWritableおよびその実装クラス

5322 ワード

AbstractMapWritableは抽象的なMapコンテナWritableタイプとして、主に現存クラスMapWritableとSortedMapWritableにインデックステーブルの構造を提供しています.以下のようにします.
Map<Class, Byte> classToIdMap = new ConcurrentHashMap<Class, Byte>()     //id Class 
Map<Byte, Class> idToClassMap = new ConcurrentHashMap<Byte, Class>(),   //class Id 

インデックス・テーブルには、新しいclassオブジェクトとIdマッピング関係を追加する必要があります.新しいId変数が必要です.classオブジェクトはメソッド・パラメータとして次のように使用されます.
 private volatile byte newClasses = 0;

上記のデータ構造があれば、AbstractMapWritableの基本的なデータ構造がインデックステーブルに関するものである以上、自然にインデックスの追加が必要になります.
private synchronized void addToMap(Class clazz, byte id) {
  // id , Id id , 
}
protected synchronized void addToMap(Class clazz) {
   // id, newClasses<127  
  if (classToIdMap.containsKey(clazz)) {
      return;
    }
    if (newClasses + 1 > Byte.MAX_VALUE) {
      throw new IndexOutOfBoundsException("adding an additional class would" +
      " exceed the maximum number allowed");
    }
    byte id = ++newClasses;
    addToMap(clazz, id);
}

AbstraactMapWritableは、保護された構造関数を提供します.
  protected AbstractMapWritable() {
    this.conf = new AtomicReference<Configuration>();
    
    // , -127~128 
    addToMap(ArrayWritable.class,
        Byte.valueOf(Integer.valueOf(-127).byteValue())); 
    addToMap(BooleanWritable.class,
        Byte.valueOf(Integer.valueOf(-126).byteValue()));
    addToMap(BytesWritable.class,
        Byte.valueOf(Integer.valueOf(-125).byteValue()));
    addToMap(FloatWritable.class,
        Byte.valueOf(Integer.valueOf(-124).byteValue()));
    addToMap(IntWritable.class,
        Byte.valueOf(Integer.valueOf(-123).byteValue()));
    addToMap(LongWritable.class,
        Byte.valueOf(Integer.valueOf(-122).byteValue()));
    addToMap(MapWritable.class,
        Byte.valueOf(Integer.valueOf(-121).byteValue()));
    addToMap(MD5Hash.class,
        Byte.valueOf(Integer.valueOf(-120).byteValue()));
    addToMap(NullWritable.class,
        Byte.valueOf(Integer.valueOf(-119).byteValue()));
    addToMap(ObjectWritable.class,
        Byte.valueOf(Integer.valueOf(-118).byteValue()));
    addToMap(SortedMapWritable.class,
        Byte.valueOf(Integer.valueOf(-117).byteValue()));
    addToMap(Text.class,
        Byte.valueOf(Integer.valueOf(-116).byteValue()));
    addToMap(TwoDArrayWritable.class,
        Byte.valueOf(Integer.valueOf(-115).byteValue()));
    
    // UTF8 is deprecated so we don't support it

    addToMap(VIntWritable.class,
        Byte.valueOf(Integer.valueOf(-114).byteValue()));
    addToMap(VLongWritable.class,
        Byte.valueOf(Integer.valueOf(-113).byteValue()));
}

続いてシーケンス化と逆シーケンス化の方法
シーケンス化:インデックス情報をストリームに書き込む
// newClasses, Id [1,newClasss] Id+ 
public void write(DataOutput out) throws IOException {
    
    // First write out the size of the class table and any classes that are
    // "unknown" classes
    // ID
    out.writeByte(newClasses);
    /*
    ** [1~newClasses] , [-127~newClasses ],
    ** , newClasses 0
    **/
    for (byte i = 1; i <= newClasses; i++) {
      out.writeByte(i);
      out.writeUTF(getClass(i).getName());
    }
  }

逆シーケンス化:ストリームからインデックス情報を構築する
  // 
  public void readFields(DataInput in) throws IOException {
    
    // Get the number of "unknown" classes
    
    newClasses = in.readByte();
    
    // Then read in the class names and add them to our tables
    
    for (int i = 0; i < newClasses; i++) {
      byte id = in.readByte();
      String className = in.readUTF();
      try {
      // 
        addToMap(Class.forName(className), id);
        
      } catch (ClassNotFoundException e) {
        throw new IOException("can't find class: " + className + " because "+
            e.getMessage());
      }
    }
  }

AbstraactMapWritableはMapWritable抽象クラスとしてMapのキー値対操作には関与せず,抽象層からインデックステーブルを抽象化しているが,現クラスのMapWritableとSortedMapWritableはMap変数を追加したものであり,SortedMapWritableはソートを実現したTreeMapであり,自身がソート機能を有している点が異なる.
 //MapWritable 
 public MapWritable() {
    super();
    this.instance = new HashMap<Writable, Writable>();
  }
  //SortedMapWritable 
  public SortedMapWritable() {
    super();
    this.instance = new TreeMap<WritableComparable, Writable>();
  }

新しいメンバーのMapには、Javaのmap(ここではインデックステーブルを維持する必要がある)メソッドと基本的に異なる方法が必要ですが、シーケンス化と逆シーケンス化は抽象クラスに基づいて拡張されます.具体的には、次のようになります.
シーケンス化:AbstractMapWritableのシーケンス化メソッドを呼び出し、Mapの容量をシーケンス化し、keyとvalueをシーケンス化します.
//MapWritable 
public void write(DataOutput out) throws IOException {
    super.write(out);
    
    // Write out the number of entries in the map
    
    out.writeInt(instance.size());

    // Then write out each key/value pair
    
    for (Map.Entry<Writable, Writable> e: instance.entrySet()) {
      out.writeByte(getId(e.getKey().getClass()));
      e.getKey().write(out);
      out.writeByte(getId(e.getValue().getClass()));
      e.getValue().write(out);
    }
  }

逆シーケンス化:インデックステーブルとWritableオブジェクトを、控訴構造に従ってストリームから構築します.