首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 互联网 >

MapReduce源码诠释-MapTask.MapOutputBuffer.Buffer

2013-11-06 
MapReduce源码注释-MapTask.MapOutputBuffer.Buffer?BlockBuffer.resetprotected synchronized void reset

MapReduce源码注释-MapTask.MapOutputBuffer.Buffer

?

BlockBuffer.reset

      protected synchronized void reset() throws IOException {        // spillLock unnecessary; If spill wraps, then        // bufindex < bufstart < bufend so contention is impossible        // a stale value for bufstart does not affect correctness, since        // we can only get false negatives that force the more conservative path    // 写入key时,发生跨界现象. 即写入某个key时,缓冲区尾部剩余空间不足以容纳整个key值,因此需要将key值分开存储,其中一部分存到缓冲区末尾,->key上半部分①    // 另一部分存到缓冲区头部->key下半部分②. 由于key是排序的关键字,需要保证连续性. 因此需要将跨界的key值重新存储到缓冲区的头部位置.    // 发生跨界的key在缓冲区末尾的长度=bufvoid-bufmark. 其中bufmark为最后(上一次)写入的一个完整的key/value的结束位置         int headbytelen = bufvoid - bufmark;          // 将尾部key插入到头部之后, bufvoid要设置为bufmark. 那么bufvoid开始,长度为headbytelen的就是key的尾部部分了        bufvoid = bufmark;        // 缓冲区前半段有足够的空间容纳整个key值. 即将尾部的key插入到头部后, 不会使得这一个key超过bufstart        if (bufindex + headbytelen < bufstart) {          // bufindex为当前缓冲区的位置. 不管写入key或者value, bufindex都表示下一个可写的初始位置          // [0, bufindex]在调整之前的头部① -> [headbytelen, headbytelen+bufindex] 即将原先头部后移headbytelen用来准备第二次拷贝          System.arraycopy(kvbuffer, 0, kvbuffer, headbytelen, bufindex);          // [bufvoid, bufvoid+headbytelen]调整之前的尾部② -> [0, headbytelen] 将尾部②插入到原先的头部①          System.arraycopy(kvbuffer, bufvoid, kvbuffer, 0, headbytelen);          bufindex += headbytelen;  // bufindex也要跟随移动到原先头部的下一个位置        } else {   // 缓冲区前半段没有足够的空间容纳整个key值. 在将key值移动到缓冲区开始位置时触发一次spill操作          byte[] keytmp = new byte[bufindex];// bufindex为在未调整之前的缓冲区头部          System.arraycopy(kvbuffer, 0, keytmp, 0, bufindex);  // 将原先的头部②复制到临时缓冲区中          bufindex = 0;  // 重置缓冲区          out.write(kvbuffer, bufmark, headbytelen);// 首先将[bufmark, bufmark+headbytelen]即尾部①写入输出流          out.write(keytmp);// 然后将缓冲区头部,即key的下半部分也写入输出流        }      }

?

热点排行