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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值