您好,登錄后才能下訂單哦!
hadoop AbstractMapWritable及其實(shí)現(xiàn)類(lèi)是怎樣的,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
AbstractMapWritable作為抽象的Map容器Writable類(lèi)型,主要是為其實(shí)現(xiàn)類(lèi)MapWritable和SortedMapWritable提供出一套索引表的結(jié)構(gòu),如下:
Map<Class, Byte> classToIdMap = new ConcurrentHashMap<Class, Byte>() //id到Class的映射表 Map<Byte, Class> idToClassMap = new ConcurrentHashMap<Byte, Class>(), //class到Id的映射表
索引表需要添加新的class對(duì)象和Id映射關(guān)系,勢(shì)必需要一個(gè)新的Id變量,class對(duì)象則作為方法形參,如下
private volatile byte newClasses = 0;
有了上面的數(shù)據(jù)結(jié)構(gòu),則需要增加一些數(shù)據(jù)的操作方法,既然AbstractMapWritable基本的數(shù)據(jù)結(jié)構(gòu)是關(guān)于索引表的,自然的會(huì)有索引的添加
private synchronized void addToMap(Class clazz, byte id) { //主要實(shí)現(xiàn)功能為對(duì)索引id通過(guò)兩個(gè)索引表操作是否存在已存在,索引Id存在但不為形參id則拋異常,否則加入索引信息 } protected synchronized void addToMap(Class clazz) { //不存在索引id,且當(dāng)前索引變量newClasses<127則自動(dòng)加入索引信息 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提供了一個(gè)受保護(hù)的構(gòu)造函數(shù)
protected AbstractMapWritable() { this.conf = new AtomicReference<Configuration>(); //添加基礎(chǔ)序列化類(lèi)型的索引信息,索引表能表示的范圍只有-127~128種類(lèi)型 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())); }
緊接著的是序列化和反序列化方法
序列化:將索引信息寫(xiě)流中
//序列化方法首先寫(xiě)入的是當(dāng)前索引變量newClasses,然后依次從索引Id范圍[1,newClasss]依次寫(xiě)入索引Id+類(lèi)名的組合 public void write(DataOutput out) throws IOException { // First write out the size of the class table and any classes that are // "unknown" classes //寫(xiě)入索引ID out.writeByte(newClasses); /* **不明白為什么只是寫(xiě)入部分[1~newClasses]的索引信息,而非[-127~newClasses的索引信息], **猜想可能與子類(lèi)覆蓋其受保護(hù)的構(gòu)造函數(shù)有關(guān),因?yàn)閚ewClasses默認(rèn)初始為0 **/ for (byte i = 1; i <= newClasses; i++) { out.writeByte(i); out.writeUTF(getClass(i).getName()); } }
反序列化:從流中構(gòu)造出索引信息
//主要是根據(jù)序列化的結(jié)構(gòu)從流中構(gòu)造索引信息 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 { //索引信息構(gòu)造 addToMap(Class.forName(className), id); } catch (ClassNotFoundException e) { throw new IOException("can't find class: " + className + " because "+ e.getMessage()); } } }
AbstractMapWritable作為MapWritable抽象類(lèi)并沒(méi)有涉及到Map<Wirtable,Writable>的鍵值對(duì)操作,而是從抽象層抽象出索引表,其實(shí)現(xiàn)類(lèi)MapWritable和SortedMapWritable則是新增了Map<Wirtable,Writable>變量,不同的之處在于SortedMapWritable是實(shí)現(xiàn)了排序了的TreeMap,自身已具有排序功能。
//MapWritable構(gòu)造函數(shù) public MapWritable() { super(); this.instance = new HashMap<Writable, Writable>(); } //SortedMapWritable構(gòu)造函數(shù) public SortedMapWritable() { super(); this.instance = new TreeMap<WritableComparable, Writable>(); }
對(duì)于新增的成員Map<Wirtable,Writable>自然需要具備一些方法,基本上跟java的map(這里需要維護(hù)索引表)方法無(wú)異,但對(duì)于序列化和反序列化則是在其抽象類(lèi)的基礎(chǔ)上擴(kuò)展,具體如下
序列化:先調(diào)用AbstractMapWritable的序列化方法,在對(duì)Map<Wirtable,Writable>的容量序列化,接著對(duì)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); } }
反序列化:則按照上訴的結(jié)構(gòu)從流中構(gòu)造出索引表和Writable對(duì)象。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。