快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

澳门威利斯人网站44_酒文化网进入



这一小结的内容我将大年夜概讲讲IndexFiles的一个历程.

为了方便查看, 照样把IndexFile.java的源代码放在前面.

1: public class IndexFiles {

2:

3:  private IndexFiles() {}

4:

5:  static final File INDEX_DIR = new File("index");

6:

7:  /** Index all text files under a directory. */

8:  public static void main(String[] args) {

9:   String usage = "java org.apache.lucene.demo.IndexFiles ";

10:   if (args.length == 0) {

11:    System.err.println("Usage: " + usage);

12:    System.exit(1);

13:   }

14:

15:   if (INDEX_DIR.exists()) {

16:    System.out.println("Cannot save index to '" +INDEX_DIR+ "' directory, please delete it first");

17:    System.exit(1);

18:   }

19:

20:   final File docDir = new File(args[0]);

21:   if (!docDir.exists() || !docDir.canRead()) {

22:    System.out.println("Document directory '" +docDir.getAbsolutePath()+ "' does not exist or is not readable, please check the path");

23:    System.exit(1);

24:   }

25:

26:   Date start = new Date();

27:   try {

28:    IndexWriter writer = new IndexWriter(FSDirectory.open(INDEX_DIR), new StandardAnalyzer(Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);

29:    System.out.println("Indexing to directory '" +INDEX_DIR+ "'...");

30:    indexDocs(writer, docDir);

31:    System.out.println("Optimizing...");

32:    //writer.optimize();

33:    writer.close();

34:

35:    Date end = new Date();

36:    System.out.println(end.getTime() - start.getTime() + " total milliseconds");

37:

38:   } catch (IOException e) {

39:    System.out.println(" caught a " + e.getClass() +

40:    "n with message: " + e.getMessage());

41:   }

42:  }

43:

44:  static void indexDocs(IndexWriter writer, File file)

45:   throws IOException {

46:   /澳门威利斯人网站44/ do not try to index files that cannot be read

47:   if (file.canRead()) {

48:    if (file.isDirectory()) {

49:     String[] files = file.list();

50:     // an IO error could occur

51:     if (files != null) {

52:      for (int i = 0; i

这段代码应该是对照好理解的, 首先main函数吸收参数, 调用indexDocs历程, 把一个文件夹下的所有的文件进行索引, 应用FileDocument.Document(file)的措施来天生一个一个的Document工具, 应用这个措施天生的文档将具有3个默认澳门威利斯人网站44的域: path, modified, content, 默认环境下, path和modified是不分词的, content是必要分词的.

然后再调用writer.addDocument措施, 进入天生索引文件的主历程.

一. IndexWriter.addDocument(Document)                       //没有什么好说的

-> 二. IndexWriter.addDocument(Document, Analyzer),     //因为没有传入Analyzer参数, 应用默认的

---> 三.DocumentWriter.addDocument(Document, Analyzer)

-----> 四.DocumentWriter.updateDocument(Document, Analyzer, Term)  //下面具体说一下这个措施)

这个措施的前两个参数没什么好说的, 第三个参数表示必要删除的Term, 这里先不管他.

1) 在DocumentWriter.updateDocument(Document, Analyzer, Term)中

final DocumentsWriterThreadState state = getThreadState(doc, delTerm);

该措施获取一个ThreadState, 下面我再解释一下这个措施.

在一个DocumentWriter中, 可能是多线程的, 也便是说, 可能有很多个进程同时对文档进行处置惩罚, 在必要这些进程的时刻, 他们可能是余暇的, 也可能是忙碌的, 有可能是应用一个现有的进程, 也有可能是必要创建一个新的进程, 每个进程包孕了自力的Posting Table与其他状态信息, 必要在完成后合并的.

怎么选择进程便是在上面这一段法度榜样了, 让我们进入这个措施内部.

2)在DocumentWriter.getThreadState中, 我来把措施枚举出来, 去掉落一些不太紧张的代码:

synchronized DocumentsWriterThreadState getThreadState(Document doc, Term delTerm) throws IOException {

//首先查看当前的进程状态信息, threadBindings是一个Hash表, 进程与状态逐一对应的

DocumentsWriterThreadState state = threadBindings.get(Thread.currentThread());

//假如当前的进程状态信息是弗成用的

if (state == null) {

//查看其他进程, 选择一个起码应用的进程

DocumentsWriterThreadState minThreadState = null;

for(int i=0;i= MAX_THREAD_STATE)) {

state = minThreadState;

state.numThreads++;

} else {

//否则新建一个"私有的Thread State,在docWriter中加入该Thread,

//并且在consumer中加入这个 Thread,

DocumentsWriterThreadState[] newArray = new DocumentsWriterThreadState[1+threadStates.length];

if (threadStates.length > 0)

System.arraycopy(threadStates, 0, newArray, 0, threadStates.length);

state = newArray[threadStates.length] = new DocumentsWriterThreadState(this);

threadStates = newArray;

}

threadBindings.put(Thread.currentThread(), state);

}

//然后调用waitReady(DocumentWriterThreadState)函数, 等待进程控线

waitReady(state);

//分配Segment名称

initSegmentName(false);

state.isIdle = false;

boolean success = false;

try {

state.docState.docID = nextDocID;

assert writer.testPoint("DocumentsWriter.ThreadState.init start");

if (delTerm != null) {

addDeleteTerm(delTerm, state.docState.docID);

state.doFlushAfter = timeToFlushDeletes();

}

assert writer.testPoint("DocumentsWriter.ThreadState.init after delTerm");

nextDocID++;

numDocsInRAM++;

// We must at this point commit to flushing to ensure we

// always get N docs when we flush by doc count, even if

// > 1 thread is adding documents:

if (!flushPending &&

maxBufferedDocs != IndexWriter.DISABLE_AUTO_FLUSH

&& numDocsInRAM >= maxBufferedDocs) {

flushPending = true;

state.doFlushAfter = true;

}

success = true;

} finally {

if (!success)澳门威利斯人网站44 {

// Forcefully idle this ThreadState:

state.isIdle = true;

notifyAll();

if (state.doFlushAfter) {

state.doFlushAfter = false;

flushPending = false;

}

}

}

return state;

}

3) 返回到DocumentWriter.updateDocument(Document, Analyzer, Term)中, 履行到:

try {

// This call is not synchronized and does all the

// work

final DocWriter perDoc = state.consumer.processDocument();

// This call is synchronized but fast

finishDocument(state, perDoc);

success = true;

}

这个模块是异常难以理解的. 首先讲讲Lucene 3.0.0中的consumer是如何的.

着实Lucene 3.0.0中应用的是设计模式中的责任链模式, 在网上有很多的文章解说这个模式, 责任链模式着实对付用户来说便是使得从用户的角度看到只有一个输入输出端口, 而法度榜样根据自己的必要添加其他的操作, 下面我拿一个好理解的UML图出来大年夜概说说, 应用了网上一篇文章的图.

这类似于一个击鼓传花的游戏, 每小我都有一个下家,  击鼓者相称于客户, 传花者则为责任链中的一个一个的人,  击鼓者不用担心花会呈现在谁的手上, 只必要传花者的一系列的通报就行了, 所有的详细类都是承袭自传花者澳门威利斯人网站44这个抽象类. 每小我可以接下花, 也可以交给下一小我, 这有点类似于Lucene中的索引文档的历程.

读取文档 –> 阐发Field内容 –> 1) 分词等等                - > 排序 –> ...

2) 加入Posting Table

3) 谋略Hash

我们可以把此中的一些内容自力出来成为一个一个类, 这样可以有效削减法度澳门威利斯人网站44榜样的耦合性.

下一章我将具体讲讲Lucene中的Index Chain与一些对照轻易呈现肴杂的内容.

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: