hadoop-common源码分析之-WritableUtils
来源:互联网 发布:手机淘宝评论在哪里看 编辑:程序博客网 时间:2024/05/17 01:33
hadoop将java的基本类型进行封装,对整型进行编码时,分为固定长度格式、可变长度格式。可变长度格式使用一种比较灵活的编码方式,对与较小的数(尤其是负数)可以节省空间存储。
VIntWritable
public class VIntWritable implements WritableComparable<VIntWritable> { private int value;//getter //setter @Override public void readFields(DataInput in) throws IOException { value = WritableUtils.readVInt(in); } @Override public void write(DataOutput out) throws IOException { WritableUtils.writeVInt(out, value); }}
WritableUtils.writeVLong
public static void writeVInt(DataOutput stream, int i) throws IOException { writeVLong(stream, i); } public static void writeVLong(DataOutput stream, long i) throws IOException { if (i >= -112 && i <= 127) { stream.writeByte((byte)i); return; } int len = -112; if (i < 0) { i ^= -1L; // take one's complement' len = -120; } long tmp = i; while (tmp != 0) { tmp = tmp >> 8; len--; } stream.writeByte((byte)len); len = (len < -120) ? -(len + 120) : -(len + 112); for (int idx = len; idx != 0; idx--) { int shiftbits = (idx - 1) * 8; long mask = 0xFFL << shiftbits; System.out.println(((i & mask) >> shiftbits)); stream.writeByte((byte)((i & mask) >> shiftbits)); } }
- 如果i在 [-112 ~ 127] 之间,直接转换为byte类型存储。
- 如果i小于-112时,将其转换成正数(异或-1L),将标识量len 设置-120;否则len为-112
- 移位要存储的数据,同时len进行自减(len即做了标示量,又统计了移位次数)。
- 将标识量写到输出流。
- 重置len,将len设置为移位个数。
- 进行循环,将数据每8位写到输出流(大端模式),具体分析for循环。
WritableUtils.readVLong
public static long readVLong(DataInput stream) throws IOException { byte firstByte = stream.readByte(); int len = decodeVIntSize(firstByte); if (len == 1) { return firstByte; } long i = 0; for (int idx = 0; idx < len-1; idx++) { byte b = stream.readByte(); i = i << 8; i = i | (b & 0xFF); } return (isNegativeVInt(firstByte) ? (i ^ -1L) : i); } public static int decodeVIntSize(byte value) { if (value >= -112) { return 1; } else if (value < -120) { return -119 - value; } return -111 - value; } public static boolean isNegativeVInt(byte value) { return value < -120 || (value >= -112 && value < 0); }
- 读取一个byte类型
- 判断读出数据如果大于-112,说明不是标志量,可以直接返回原始数据,如果小于-120或者在[-112 ~ -120]之间,说明为标识量,需要判断返回移动位数。
- 通过得到移动的位数,每次移动8位,异或移位。还原数据。
- 判断表示量,如果在小于-120 或者在[0 ~ -112]之间,证明是负数,将得到的数据进行异或-1L得到最终值。
总结:
- 在存储正数时,为了防止类型过大,而存储值小的,hadoop将数据每8位转换成byte进行存储。
- 在存储负数时,由于负数存储需要以补码形式(反码+1),浪费太多的空间,所以hadoop先将负数与-1L异或,得到正数进行存储,所以在存储过程中,需要一个标识来标记数字正负,即len,它同时标识了需要移动位数和正负。
0 0
- hadoop-common源码分析之-WritableUtils
- hadoop-common源码分析之-Configuration
- Hadoop Common源码分析之SerializationFactory、Serialization
- Hadoop Common源码分析之服务Service
- CodeIgniter源码分析之Common.php
- google probuf源码分析之common.h
- CodeIgniter源码分析之Common.php
- Hadoop源码分析18:common包中的fs.FileSystem
- Hadoop源码分析之开篇
- Hadoop源码分析之Configuration
- Hadoop源码分析之FileSystem
- Hadoop源码分析之DistributedFileSystem
- Hadoop源码分析之Configuration
- Hadoop之JobTracker源码分析
- hadoop之WordCount源码分析
- hadoop之BlockPoolManager源码分析
- Hadoop RPC源码分析之Client
- Hadoop RPC源码分析之Server
- Struts2.3.24项目配置所需最少依赖jar包
- 表单开发(一):获取文本框和密码框数据 用户登录网页
- 监听ContentProvider中数据的变化
- oracle启动顺序
- Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version 错误解决
- hadoop-common源码分析之-WritableUtils
- UVA136-Ugly Numbers
- Java多态中的注意事项
- 南阳oj 士兵杀敌(二) 题目116 NYOJ 数据结构
- 优先队列用法
- ZOJ - 3124 Celebrity jeopardy
- HDU 3033 I love sneakers!(分组背包变形)
- 文章标题
- velocity例子