共計 4439 個字符,預計需要花費 12 分鐘才能閱讀完成。
hadoop AbstractMapWritable 及其實現類是怎樣的,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面丸趣 TV 小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
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);
}
AbstractMapWritable 提供了一個受保護的構造函數
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());
}
}
}
AbstractMapWritable 作為 MapWritable 抽象類并沒有涉及到 Map Wirtable,Writable 的鍵值對操作,而是從抽象層抽象出索引表,其實現類 MapWritable 和 SortedMapWritable 則是新增了 Map Wirtable,Writable 變量,不同的之處在于 SortedMapWritable 是實現了排序了的 TreeMap,自身已具有排序功能。
//MapWritable 構造函數
public MapWritable() { super();
this.instance = new HashMap Writable, Writable
}
//SortedMapWritable 構造函數
public SortedMapWritable() { super();
this.instance = new TreeMap WritableComparable, Writable
}
對于新增的成員 Map Wirtable,Writable 自然需要具備一些方法,基本上跟 java 的 map(這里需要維護索引表)方法無異,但對于序列化和反序列化則是在其抽象類的基礎上擴展,具體如下
序列化:先調用 AbstractMapWritable 的序列化方法, 在對 Map Wirtable,Writable 的容量序列化,接著對 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 對象。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注丸趣 TV 行業資訊頻道,感謝您對丸趣 TV 的支持。