Lucene数据储存结构中的VInt(可变长度整型)

Lucene数据存储结构中的VInt(可变长度整型)

转载自:

http://www.blogjava.net/persister/archive/2010/02/02/311642.html

 

A variable-length format for positive integers is defined where the high-order bit of each byte indicates whether more bytes remain to be read. The low-order seven bits are appended as increasingly more significant bits in the resulting integer value. Thus values from zero to 127 may be stored in a single byte, values from 128 to 16,383 may be stored in two bytes, and so on.

可变格式的整型定义:最高位表示是否还有字节要读取,低七位就是就是具体的有效位,添加到

结果数据中。比如00000001 最高位表示0,那么说明这个数就是一个字节表示,有效位是后面的七位0000001,值为1。10000010 00000001 第一个字节最高位为1,表示后面还有字节,第二位最高位0表示到此为止了,即就是两个字节,那么具体的值注意,是从最后一个字节的七位有效数放在最前面,依次放置,最后是第一个自己的七位有效位,所以这个数表示 0000001 0000010,换算成整数就是130

VInt Encoding Example

Value

First byte

Second byte

Third byte

0

00000000

 

 

1

00000001

 

 

2

00000010

 

 

...

 

 

 

127

01111111

 

 

128

10000000

00000001

 

129

10000001

00000001

 

130

10000010

00000001

 

...

 

 

 

16,383

11111111

01111111

 

16,384

10000000

10000000

00000001

16,385

10000001

10000000

00000001

...

 

 

 

 

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   }

InputStream负责读:
 1   /** Reads an int stored in variable-length format.  Reads between one and
 2    * five bytes.  Smaller values take fewer bytes.  Negative numbers are not
 3    * supported.
 4    * @see OutputStream#writeVInt(int)
 5    */
 6   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   }

>>>表示无符号右移