lucene压缩算法

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。

 转自:Lucene编码与压缩算法 - 知乎

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值