中文(中国)更改
 
powered by
Hawk Search
Hawk Search

 
分类

 
文章

 
日历

三月 2010
« 四    
1234567
891011121314
15161718192021
22232425262728
293031  
 
 
Javen-Studio Thinking of Life, Imagination of Future.
NEWS

Annotated Lucene:第四节 索引创建过程(2)

4.3.3 TermsHashPerField.addToken()

该方法负责进行将上面分解出的token字符串添加到PostingList表中,添加位置等信息的处理会调用接下来的consumer的方法,如FreqProxTermsWriterPerField或TermVectorsTermsWriterPerField。此方法涉及到访问和管理三个内存中的数据池,即CharBlockPool、IntBlockPool和ByteBlockPool。这三个池均采用分片(slice或block)来管理,每一片有固定的长度,定义在DocumentsWriter中,并且也由DocumentsWriter来分配新的块或者回收不用的块,以达到节省内存和提高效率的作用。

TermsHashPerField会维护一个postingHash的散列表,用来存储和管理每一个添加的token及其位置信息,即RawPostingsList类。添加的时候先会计算termText的hashCode值,同时处理掉非法Unicode字符,然后在postingsHash表中查找该TermText的RawPostingsList,找不到则添加一个新的,否则就追加新的位置信息。TermText文本会写入到CharBlockPool中去,同时RawPostingsList中记录其位置即textStart值。ByteBlockPool中写入各个postiong和freq数据(freq在fieldInfo的omitTf设置为false时记录),这个处理在后面的类方法中进行(FreqProxTermsWriterPerField和TermVectorsTermsWriterPerField),RawPostingsList.byteStart记录起始偏移。IntBlockPool中记录这些数据在ByteBlockPool中位置偏移,RawPostingsList.intStart记录起始偏移。

该方法处理逻辑和内存中重要的数据对象的关系图如下(其中假设consumer为FreqProxTermsWriter)

4.3.4 FreqProxTermsWriterPerField.newTerm()/addTerm()

该方法负责将term在文档中出现的位置(position)和频率(frequency),以及term自带的payloads以及term所在的文档编号等信息写入内存中的缓冲区,即TermsHashPerThread中的ByteBlockPool对象。调用TermsHashPerThread.writeByte()时同时会更新IntBlockPool中的值,指向对应的ByteBlockPool位置。

当field的omitTf为true时,只会记录term出现的文档的编号,记录时写入docId与上一个文档docId的差值,第一个为docId本身。如果omitTf为false,则term出现的position以及payloads(如果有的话),position会记录当前位置与上一个位置的差值的一半,第一个值为本身的一半;并且在最后(term出现在另一个文档时)写入文档编号(方法同omitTf=true),以及term出现在该文档的频率docFreq,不过如果docFreq=1就不会写入docFreq,并且docCode写入与1的或运算值。

处理后的数据结构如下图所示,其中假设docId=0,并且只画了处理content的field的在omitTf设置为false的数据,另外图中ByteBlockPool记录的是原始int数字,实际会写成VInt的字节序列,所以某些offset值只是示例。请参看图中的说明。

4.3.5 TermVectorsTermsWriterPerField.newTerm()/addTerm()

该方法负责将term在文档中出现的位置(position)和偏移(offset)向量(startOffset, endOffset)等信息写入内存中的缓冲区,即TermsHashPerThread中的ByteBlockPool对象。需要注意的是只有当field.isStorePositionWithTermVector()或field.isStoreOffsetWithTermVector()为true时,相应的信息(startOffset,endOffset)或position才会写入。

写入的这两项数据紧跟着上一节写入的ProxCode和Payload数据之后。写入position比较简单,即把该位置按VInt类型写入即可。偏移向量的写入是记录开始的偏移即startOffset,以及结束的偏移与开始偏移的差值即endOffset-startOffset,同样以VInt类型写入ByteBlockPool。另外这些数据只是写入到内存缓冲中,在finish()调用时才会把它们真正写入.tvx和.tvf和.tvd向量文件中,下一节再详细介绍。

处理后的数据结构如下图所示,另外写入数据到ByteBlockPool的方法与上一节中FreqProx写入的处理一致,同样需要调用TermsHashPerThread.writeByte()方法。请参看图中的说明。

发表评论