Lucene Vint压缩策略是,用每个字节的最高位做标志位,后7位为有效算术位,如果标志位为1,则说明后一个字节和当前字节是同一个数字,为0说明后一个字节是一个新的数字

Lucene源代码中进行存储和读取是这样的。OutputStream是负责写:

 1   /** Writes an int in a variable-length format.  Writes between one and
 2    * five bytes.  Smaller values take fewer bytes.  Negative numbers are not
 3    * supported.
 4    * @see InputStream#readVInt()
 5    */
 6   public final void writeVInt(int i) throws IOException {
 7     while ((i & ~0x7F) != 0) {
 8       writeByte((byte)((i & 0x7f) | 0x80));
 9       i >>>= 7;
10     }
11     writeByte((byte)i);
12   }

writeVint(压缩)步骤

1. i & ~0x7F

用int i的最低位byte和~0x7F(1000 0000)做与操作,如果为真则说明这个int在等于或者大于第8位的bit上依然还有有效bit,这些bit应该在后面的writeByte操作在写入(每次循环一个字节包括int的低位7个bit位和一个标志位)

2 writeByte((byte)((i & 0x7f) | 0x80));

写入一个byte,友i的最低7个bit位和一个标志位(置1)组成

3  i >>>= 7;

由于写入了7个bit位,所以i右移7位,使得后面的bit参与下一次写入

4   writeByte((byte)i);

如果循环结束,则说明i剩下的有效bit等于或者小于7位,则当前这次是最后一次writeByte,这时候第8位也不需要置1,直接写入这个byte皆可。

==============================================================================================================================================

InputStream负责读

public final int readVInt() throws IOException {
 7     byte b = readByte();
 8     int i = b & 0x7F;
 9     for (int shift = 7; (b & 0x80) != 0; shift += 7) {
10       b = readByte();
11       i |= (b & 0x7F) << shift;
12     }
13     return i;
14   }

1   byte b = readByte();

先读取低位的一个byte

2    int i = b & 0x7F;

取这个字节的低7位(有效数字位)赋值给i

3    for (int shift = 7; (b & 0x80) != 0; shift += 7)

循环先判定当前byte(b)的第8位是不是为1,如果是1,则说明后面还有byte也是属于这个int, shift是表示当前b里的有效7位在i里面对于的bit位置,因为在循环开始就已经赋值过7bit,所以shift循环开始就从7开始算

Lucene的Vint类型详解的更多相关文章

  1. C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解

    前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解  ...

  2. C++11 并发指南六(atomic 类型详解四 C 风格原子操作介绍)

    前面三篇文章<C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)>.<C++11 并发指南六( <atomic> 类型详解二 std::at ...

  3. C++11 并发指南六(atomic 类型详解三 std::atomic (续))

    C++11 并发指南六( <atomic> 类型详解二 std::atomic ) 介绍了基本的原子类型 std::atomic 的用法,本节我会给大家介绍C++11 标准库中的 std: ...

  4. C++11 并发指南六( <atomic> 类型详解二 std::atomic )

    C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)  一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...

  5. 服务启动项 Start类型详解

    注册表的服务启动项 Start类型详解 HKLM\SYSTEM\CurrentControlSet\services\ 下的服务项.不论有没有在services.msc服务管理控制台中显示,在注册表中 ...

  6. c# WebApi之接口返回类型详解

    c# WebApi之接口返回类型详解 https://blog.csdn.net/lwpoor123/article/details/78644998

  7. C++之string类型详解

    C++之string类型详解 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够.字符串长度等等,而且作为一个泛型类出现,他集成的操作函 ...

  8. (转)C# WebApi 接口返回值不困惑:返回值类型详解

    原文地址:http://www.cnblogs.com/landeanfen/p/5501487.html 正文 前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi ...

  9. Swift - 可选类型详解

    可选类型详解 直接上代码解释 // 类中所有的属性在对象初始化时,必须有初始化值 class Person : NSObject { var name : String? var view : UIV ...

随机推荐

  1. (转载)OC学习篇之---类的延展

    前一篇文章我们介绍了类的类目概念和使用,那么这篇文章我们继续来介绍一下OC中的一个特性:延展. 其实说白了,延展就是弥补C语言中的前向申明,我们知道,在C语言中,如果你想调用一个函数的话,那么在此之前 ...

  2. ninject学习笔记一:IOC的实现

    这篇文章主要介绍ninject在IOC方面的实现,至于IOC的含义,网络资源很丰富,我这儿就不再赘述了.官方的文档其实挺好的,只是本人英语很烂,看起来比较费劲,下面这些东西是看官方的代码推敲的,我觉得 ...

  3. Python学习第二天数组

    1:Python定义数组:a=[0,1,2,3,4] ;   打印数组list(a); 这时:a[0]=0, a[1]=1, a[[2]=2...... 1.1:如果想定义一个很长的数组可以用到pyt ...

  4. Hbase学习记录(1)|伪分布式安装

    概述 Hbase –Haddop Database 是一个高性能,高可靠性.面向列.可伸缩的分布式存储系统. Hbase利用HDFS作为文件存储系统,利用MapReduce来处理Hbase的海量数据, ...

  5. 初学VSTO一问,如何添加SheetChange事件

    很多初学者在学习VSTO时,觉得很迷茫,举一个简单的例子,在VBA中,添加SheetChange的事件,非常容易. 如下图所示,只需要在VBE界面,先把SheetChange事件就好了. 而认为在VS ...

  6. iOS获取文件和文件夹大小

    //通常用于删除缓存的时,计算缓存大小 //单个文件的大小 - (long long) fileSizeAtPath:(NSString*) filePath{ NSFileManager* mana ...

  7. (剑指Offer)面试题20:顺时针打印矩阵

    题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字, 例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2, ...

  8. Hibernate 与 Spring 的整合

    刚刚学习了hibernate和Spring的整合,现在来总结一下. 以实现一个功能为例,与大家分享一下整个过程. 需要实现的功能:建立一个Person类,该类包括name,sex,age,birtha ...

  9. Android 通过xml 自定义图片

    <?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http:/ ...

  10. java中string与byte[]的转换

    1.string 转 byte[] byte[] midbytes=isoString.getBytes("UTF8"); //为UTF8编码 byte[] isoret = sr ...