注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Koala++'s blog

计算广告学 RTB

 
 
 

日志

 
 

Lucene源代码分析[14]  

2009-07-06 09:43:04|  分类: Lucene |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

         现在看skipInterval,把测试代码改了,只改一个地方,现在换成分词:

public static void main( String[] args ) throws Exception

{

    IndexWriter writer = new IndexWriter( "E:\\a\\", new SimpleAnalyzer(), true);

    writer.setUseCompoundFile( false );   

    int n = 1000;

    for( int i = 0; i < n; i++ )

    {

       Document doc1 = new Document();

       Field name1 = new Field( "TheField", "hello" + i,

           Field.Store.YES, Field.Index.TOKENIZED );

       doc1.add( name1 );

       writer.addDocument( doc1 );

    }

   

    writer.close();

}

    我看再看一次SegmentMerger中的:

if ((df % skipInterval) == 0) {

    bufferSkip(lastDoc);

}

    也就是达到skipIntervalDocument就写一次,那么第一次的时候lastDoc的序号就是14(16-1-1),我们再次进去看一下:

private void bufferSkip(int doc) throws IOException {

    long freqPointer = freqOutput.getFilePointer();

    long proxPointer = proxOutput.getFilePointer();

 

    skipBuffer.writeVInt(doc - lastSkipDoc);

    skipBuffer.writeVInt((int) (freqPointer - lastSkipFreqPointer));

    skipBuffer.writeVInt((int) (proxPointer - lastSkipProxPointer));

 

    lastSkipDoc = doc;

    lastSkipFreqPointer = freqPointer;

    lastSkipProxPointer = proxPointer;

}

    因为第一次之前没有skip过,那么lastSkipDoc就是0,当然lastSkipFrqPointerlastSkipProxPointer也是0。那么doc-lastSkipDoc=14,而freqPointer – lastSkipFreqPointer = 15proxPointer-lastSkipProxPointer=15,所以第一组应该是0E0F0F

    先看.frq的前半部分,第一个是01,也就是(0<<1)|1的值,而后面的是(1<<1)|1=3

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

 

00000000   01 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

00000010   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

00000020   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

00000030   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

00000040   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

00000050   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

00000060   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

00000070   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

00000080   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

00000090   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

000000A0   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

000000B0   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

000000C0   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

000000D0   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

000000E0   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

000000F0   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

00000100   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

 

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

 

000003D0   03 03 03 03 03 03 03 03  03 03 03 03 03 03 03 03   ................

000003E0   03 03 03 03 03 03 03 03  0E 0F 0F 10 10 10 10 10   ................

000003F0   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

00000400   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

00000410   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

00000420   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

00000430   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

00000440   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

00000450   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

00000460   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

00000470   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

00000480   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

00000490   10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10   ................

000004A0   10 10                                              ..

    3E7999,我们上次也讲过skip的信息都是写在.frq后面的,我们可以看到有0E0F0F。然后剩下的都是10,因为我们这个特殊的测试例子,所以它总是skip 0x10,所以这就这样。我们再考虑一下(0x4A1-0x3E8+1)=0xBA0xBA/3=0x3E0x3E*0x10=0x3E03E0就是992

    但是indexIntervalskipInterval有什么用呢?

/** Returns the nth term in the set. */

final Term get(int position) throws IOException {

    if (size == 0)

       return null;

 

    SegmentTermEnum enumerator = getEnum();

    if (enumerator != null && enumerator.term() != null

           && position >= enumerator.position

           && position < (enumerator.position +

enumerator.indexInterval))

       return scanEnum(position); // can avoid seek

 

    seekEnum(position / enumerator.indexInterval); // must seek

    return scanEnum(position);

}

 

private final Term scanEnum(int position) throws IOException {

    SegmentTermEnum enumerator = getEnum();

    while (enumerator.position < position)

       if (!enumerator.next())

           return null;

 

    return enumerator.term();

}

    可以看到如果position[enumerator.position,enumerator.position + enumerator.indexInterva)这个区间中,就不用seek了,直接scanscanEnum函数比较简单,直接循环找到相应的position就可以了。

         看一下seekEnumseek函数:

private final void seekEnum(int indexOffset) throws IOException {

    getEnum().seek(indexPointers[indexOffset],

           (indexOffset * getEnum().indexInterval) - 1,

           indexTerms[indexOffset], indexInfos[indexOffset]);

}

 

final void seek(long pointer, int p, Term t, TermInfo ti)

       throws IOException {

    input.seek(pointer);

    position = p;

    termBuffer.set(t);

    prevBuffer.reset();

    termInfo.set(ti);

}

    看到这里,我们差不多看懂了,差多个个indexInterval,我们先算出来,传到indexOffset中,我们再用seek函数将文件指到相应的位置,但是indexPointers是从哪来的呢?看一下这个函数:

private synchronized void ensureIndexIsRead() throws IOException {

    if (indexTerms != null) // index already read

       return; // do nothing

    try {

       int indexSize = (int) indexEnum.size; // otherwise read index

 

       indexTerms = new Term[indexSize];

       indexInfos = new TermInfo[indexSize];

       indexPointers = new long[indexSize];

 

       for (int i = 0; indexEnum.next(); i++) {

           indexTerms[i] = indexEnum.term();

           indexInfos[i] = indexEnum.termInfo();

           indexPointers[i] = indexEnum.indexPointer;

       }

    } finally {

       indexEnum.close();

       indexEnum = null;

    }

}

    可以看到,其实它是把tii中的内容已经保存到indexTermsindexInfosindexPointers中了。这样就可以用tii中的内容很快地找到在tis中我们所需要的内容。

    概括地讲就是indexInterval就是用来在termskip,而skipInterval就是在term那一行的documentskip。这里似乎用不着skipInterval

 

 

 

  评论这张
 
阅读(1027)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017