lucene 源码小析

lucene3.0

源代码流程:   index
IndexWriter:
1, setMessageID:  基本没用
2, DocumentWriter: 写多个document的writer。
3, directory.clearLock        NativeFSLockFactory    
(其中Directory的生成根据系统
if (Constants.WINDOWS) {
      return new SimpleFSDirectory(path, lockFactory);
    } else {
      return new NIOFSDirectory(path, lockFactory);
    }


4, Lock writeLock = directory.makeLock   (NativeFSLockFactory来完成clearlock和getlock)
5, writeLock.obtain(writeLockTimeout)     也就是说我觉得以上工作都只是init一个lock,但是并没有去obtain

6, if create is true:        以下读取的应该是原有的directory中的index
7, Segmentinfo seg = new Segmentinfos();
8, clear();         把以前的segment clear
9, checksum;   应该是核查文件的正确性
10, lastgeneration = generation = generationFromSegmentFileName(String filename);    generation是个int
11, int format = input.readInt();   格式都是负数,至于保存在哪个文件中,目前还未知,应该是Segments那个
if(format < 0){     // file contains explicit format info
        // check that it is a format we can understand
        if (format < CURRENT_FORMAT)
          throw new CorruptIndexException("Unknown format version: " + format);
        version = input.readLong(); // read version
        counter = input.readInt(); // read counter
      }
      else{     // file is in old format without explicit format info
        counter = format;
      }

if(format >= 0){    // in old format the version number may be at the end of the file
        if (input.getFilePointer() >= input.length())
          version = System.currentTimeMillis(); // old file format without version number
        else
          version = input.readLong(); // read version
      }

12,segmentInfos.clear();      应该是读取之前存在的directory之后执行的clear()操作
13,deleter = new IndexFileDeleter
14,pushMaxBufferedDocs();       这个似乎只是让LogDocMergePolicy设置一个minMergeSize
final MergePolicy mp = mergePolicy;
LogDocMergePolicy lmp = (LogDocMergePolicy) mp;
lmp.setMinMergeDocs(maxBufferedDocs);

addDocument:
1, DocumentsWriter:
# 得到一个线程,在lucene2.3之后,DocumentWriter多线程写document
final DocumentsWriterThreadState state = getThreadState(doc, delTerm);
state.consumer.processDocument();
processDocument方法里面 startDocument              好像没有什么用

重要:
init:  DocFieldProcessorPerThread extends DocConsumerPerThread
DocFieldProcessorPerField       单独的class
DocFieldConsumersPerThread extends DocFieldConsumerPerThread
DocInverterPerThread extends DocFieldConsumerPerThread
DocFieldConsumersPerField extends DocFieldConsumerPerField
DocInverterPerField extends DocFieldConsumerPerField
调用过程:
DocFieldProcessorPerThread 调用DocFieldConsumerPerThread 作为自己的consumer
然后调用DocFieldProcessorPerField 处理每一个Field的hash和QuictSort
然后调用每一个Field的Consumer,也就最终是DocInverterPerField 的processFields方法

2, finishDocument(state, perDoc);        完成后续工作,具体内容没完全看完。
其中第一步进行   balanceRam    系统中有3块内存,posting table, byte blocks, char blocks. 应该是调节3者的平衡,因为一个document如果分词太多,可能占据了posting 的绝大部分。
3, flush(boolean triggerMerge, boolean flushDocStores, boolean flushDeletes);     
ensureOpen(false)
doFlush() doFlushInternal    做了很多flush、delete、写混合index等工作,还有flush后处理工作以及checkpoint();
docwriter.clearFlushPending
maybeMerge()
updatePendingMerges              做一个merge前准备工作
mergeScheduler.merge(this);   this表示DocumentsWriter


optimize               没有仔细看,主要工作就是merge
如文档所说,optimize(boolean doWait)      : you can specify whether the call should block until the optimize completes          应该指的是在optimize完成之前,整个indexwriter的call被block了。
代码:
if (doWait)
      synchronized(this)

close
从文档看因为lock的原因,如果在close过程中发生Exception,即使是在flush部分后发生Exception,也一样会保证原disk上的index不变
另外,从eg看writer.close()都只是放在try中,而没有放在finally中


IndexReader.deleteDocument(int doc)/deleteDocuments(Term term)
本质调用doDelete()
DirectoryReader.doDelete()      调用subReader,也就是segmentReader
SegmentReader.doDelete()     
     deletedDocs.getAndSet(docNum)    实际上在deleteDocs这个BitVector中添加要删除的docNum
和IndexWriter一样,close的时候会提交一个commit,commit的工作很多,包括减少本身(IndexReader)引用,用IndexFileDeleter删除需要删除的文件等等。pending的工作,正好和上面的doDelete符合,上面的doDelete删除的时候,如果失败,就会添加到pending中。

重要:
这里有一个结构很不错: 例子中IndexReader实际上是DirectoryReader,通过以下方法调用SegmentReader。这种自身不同类别调用,方法得到重用,结构清晰。
for (int i = 0; i < subReaders.length; i++)
        subReaders[i].commit();        subReader即segmentReader

另外,整个lucene中用了很多checkpoint机制,例如startCommit()即开始一个checkpoint。这样一旦出错,可以rollback.   例如在IndexReader.close的时候,DirectoryReader.commit --> startCommit --> segmentReader(startCommit) -->  segmentReader.commit --> if (!success) rollbackCommit --> segmentReader.rollbackCommit




Deleter:
几个重要的方法:
1, deleter.checkpoint
2, deleter.close
3, deleter.refresh

你可能感兴趣的:(多线程,windows,工作,Lucene)