FixedBitSet在lucene中的一个主要用途是存储文档号,该类使用一个bit来存储一个文档号,在最好的情况下,该类可以使用一个long(64位)来存储64个docId, 该类特别适合存储没有重复的Int类型的数据,下面通过讲解该类中的几个方法的源码,以此来了解该类的存储原理,理解该类对于理解lucene的docId遍历有一定的帮助。
代码语言:javascript复制1. 该类的构造函数
public FixedBitSet(int numBits)
public FixedBitSet(long[] storedBits, int numBits)
代码语言:javascript复制 /**
* Creates a new LongBitSet.
* The internally allocated long array will be exactly the size needed to accommodate the numBits specified.
* @param numBits the number of bits needed
*/
// 通过参数提供的bit的个数,计算long数组的长度,long数组的长度计算公式((numBits - 1) >> 6) 1
public FixedBitSet(int numBits) {
this.numBits = numBits;
bits = new long[bits2words(numBits)];
numWords = bits.length;
}
2. 该类主要方法
代码语言:javascript复制2.1 public void set(int index)
public void set(int index) {
assert index >= 0 && index < numBits: "index=" index ", numBits=" numBits;
// 计算参数index应该落在long数组中的那个位置上,index >> 6, 右移6位相当于除以64,即long的bit位数
int wordNum = index >> 6; // div 64
// 计算index是上面计算出来的long数组指定位置的元素的哪一位,对该位进行置位
long bitmask = 1L << index;
// 对该位进行 或 操作, 即对该位进行置位
bits[wordNum] |= bitmask;
}
代码语言:javascript复制public int nextSetBit(int index)
// 计算大于等于参数index的位置被置位的Index
public int nextSetBit(int index) {
// Depends on the ghost bits being clear!
assert index >= 0 && index < numBits : "index=" index ", numBits=" numBits;
// 计算该index落在long数组的哪个元素上
int i = index >> 6;
// 丢弃该index右侧的位
long word = bits[i] >> index; // skip all the bits to the right of index
// 如果word的值不为0,说明大于等于index的位中存在被置位(1)的位
if (word!=0) {
// 返回大于等于该index,第一个被置位的Index(从低位到高位)
return index Long.numberOfTrailingZeros(word);
}
// 运行到此处,说明上面计算出的元素所有的位全部为0,需要向后遍历数组的元素,找出第一个被置位的Index
while( i < numWords) {
word = bits[i];
if (word != 0) {
return (i<<6) Long.numberOfTrailingZeros(word);
}
}
// 没有比index指定的位更高的位被置位
return DocIdSetIterator.NO_MORE_DOCS;
}
到此为止,已经介绍了FixedBitSet中两个重要的方法,该类的源码比较容易理解,因此不再此处讲解更多的此类中的方法,了解该类的源码对lucene搜索过程中遍历docId有一定的帮助。后面的源码分析文章中会详细介绍lucene的索引和搜索过程中的源码。敬请期待