大家好,欢迎来到IT知识分享网。
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)); }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/157363.html