1. VInt:将一个整形去掉高位无效的0,使用更小的字节数来表示这个整形。
writeVInt代码
/** Writes an int in a variable-length format. Writes between one and
* five bytes. Smaller values take fewer bytes. Negative numbers are not
* supported.
*/
public void writeVInt(int i) throws IOException {
while ((i & ~0x7F) != 0) {
writeByte((byte)((i & 0x7f) | 0x80));
i >>>= 7;
}
writeByte((byte)i);
}
-
~127->00 0111 1111(原)->00 0111 1111(反)-> 00 0111 1111(补)->~之后为11 1000 0000(补)-> 11 0111 1111(反)->10 1000 0000(原) = -128
- (i & ~0x7F) :判断当前整数i的最低字节的第8位,如果返回为真,说明int整数的第二个字节仍旧保存着有效的字节。这些字节应该在后续遍历中执行相同的判断逻辑,以确定int整数中有效字节个数。
- writeByte((byte)((i & 0x7f) | 0x80)):将当前整数i的最低7个bit比特位和一个标志位(设置为1)组成一个字节,并写入字节缓存。
- i >>>= 7: 对整数i向右移7位。继续分析接下来的字节内容。
readVInt代码
/** Reads an int stored in variable-length format. Reads between one and
* five bytes. Smaller values take fewer bytes. Negative numbers are not
* supported.
*/
public int readVInt() throws IOException {
// byte高位为符号位
byte b = readByte(); // 读取第一个字节
if (b >= 0) return b;
// 第一个字节高位为1,b < 0 存在下一个字节
int i = b & 0x7F; // 第一个字节的高位过滤掉,i此时为有效的7个bit位
b = readByte(); // 读取第二个字节
i |= (b & 0x7F) << 7; // 第二个字节高位过滤掉取7个有效bit,再左移7位,再与上一个字节的有效bit位合并
if (b >= 0) return i;
// 存在第三个字节
b = readByte(); // 读取第三个字节
i |= (b & 0x7F) << 14; // 第三个字节高位过滤掉取7个有效bit,再左移14位,再与上两个字节的有效bit位合并
if (b >= 0) return i;
b = readByte(); // 读取第四个字节
i |= (b & 0x7F) << 21;// 第四个字节高位过滤掉取7个有效bit,再左移21位,再与上三个字节的有效bit位合并
if (b >= 0) return i;
// 因整形数字太大占用4个字节内存大小,又因每个字节的高位为标记位,所以放大到5个字节
b = readByte();
// Warning: the next ands use 0x0F / 0xF0 - beware copy/paste errors:
i |= (b & 0x0F) << 28; // 第5个字节高位过滤掉取7个有效bit,再左移28位,再与上四个字节的有效bit位合并
if ((b & 0xF0) == 0) return i;
throw new IOException("Invalid vInt detected (too many bits)");
}
- readByte:首先读取最低位的字节。
- b & 0x7F: 取当前字节的低7个比特位,并初始化整数变量i。
2. zigzag: 针对VInt无法处理好负数的情况
3.LZ4: 其字典ht为PackedInts。
4.packedInts: 是针对一个以long为成员的数组,将这些long打包拼接起来。
首先去除所有long的高位0,找出最大的bits,所有的long都将以这个bits来表示。
最终一个long 64位表示多个long(64 / bits)。
/** * A {@link AbstractPagedMutable}. * Base implementation for {@link PagedMutable} and {@link PagedGrowableWriter}. * @lucene.internal */
/** * A {@link PagedGrowableWriter}. This class slices data into fixed-size blocks * which have independent numbers of bits per value and grow on-demand. * <p>You should use this class instead of the {@link PackedLongValues} related ones only when * you need random write-access. Otherwise this class will likely be slower and * less memory-efficient. * @lucene.internal *//** * A {@link PagedMutable}. This class slices data into fixed-size blocks * which have the same number of bits per value. It can be a useful replacement * for {@link PackedInts.Mutable} to store more than 2B values. * @lucene.internal */
5. FST