vlong编码规则

来源:互联网 发布:淘宝网买东西注意什么 编辑:程序博客网 时间:2024/05/16 01:29

byte[] bytes;字节数组,存储数据长度,符号和值
start;读取和写入的起始位置
int len = bytes[start];这是起始位置的值,包含数据长度,符号,或者是值(当数据只有一个字节时)
len>=-112 代表vlong的值只有一个字节,即value = len;(-112-127);
len<-120 代表vlong的值是一个负数,长度为-(len+120) ;(1-8位)
len在[-120,-112)范围代表vlong的值是一个正数,长度为-(len+112);(1-8位)
此部分代码位于package org.apache.hadoop.io.WritableUtils类中;
readVlong源代码:

 int len = bytes[start];    if (len >= -112) {      return len;    }    boolean isNegative = (len < -120);//判断正负    len = isNegative ? -(len + 120) : -(len + 112);//获取长度    if (start+1+len>bytes.length)//字节数组长度错误      throw new IOException("");    long i = 0;    for (int idx = 0; idx < len; idx++) {      i = i << 8;//从高位向低位读取,每读取一次左移8位      i = i | (bytes[start+1+idx] & 0xFF);    }    /**根据写入long值限制,除去第一位符号位,因此i的最大有效位数是63位,    *最高位必然是0,因此i^-1L可以将i转变为相对应的负数,此时表达式i^-1L相当于(i* -1)-1 ,    *至于-1的原因,我认为是因为负数比正数多一个的原因,比如一个字节表示的数值范围是-128~127,去除最高位,    *剩余七位表示的最大数是127,127^ -1 正好可以表示-128 (个人理解,欢迎指正)    **/    return (isNegative ? (i ^ -1L) : i);

writeVlong源代码

 //stream是输出流,i是要写出的long值(8个字节64位) //第一位是符号位,剩余63位代表其值 if (i >= -112 && i <= 127) {      stream.writeByte((byte)i);      return;    }    int len = -112;    if (i < 0) {    //此处与readVlong相对应      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);     //(1-8)    for (int idx = len; idx != 0; idx--) {      int shiftbits = (idx - 1) * 8;      long mask = 0xFFL << shiftbits;      //从最高位开始读取      /**假设len为8,第一次mask为0xff左移56位,即mask为0xff00 0000 0000 0000,i & mask保留i的最高8位,      *其余位数置0,然后再右移56位,即只保留最高8位,以此类推,从高到低以此写入输出流      */      stream.writeByte((byte)((i & mask) >> shiftbits));    }
0 0
原创粉丝点击