首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

lucene2.4源码学习二 写文件之WaitQueue

2013-03-19 
lucene2.4源码学习2 写文件之WaitQueuelucene是多线程写文件的,但是也要写出来的文件号是从小到大的。也就

lucene2.4源码学习2 写文件之WaitQueue
lucene是多线程写文件的,但是也要写出来的文件号是从小到大的。也就是最后写的时候还需要一个同步的过程。

当文档号低的还没有生成完,但是另外一个线程的已经生成好一个文档号高的文档了,这个时候怎么办,这个时候文档号高的是不能写的,要等到文档号低的写完再写。

lucene的做法是把这些高的文档加入到一个队列,即WaitQueue。

这样当低文档写完的时候,还会去写准备好的高的文档。注意有个while循环,而writeDocument方法有个nextWriteLoc++会不断往前

 synchronized public boolean add(DocWriter doc) throws IOException {      assert doc.docID >= nextWriteDocID;      if (doc.docID == nextWriteDocID) {        writeDocument(doc);        while(true) {          doc = waiting[nextWriteLoc];          if (doc != null) {            numWaiting--;            waiting[nextWriteLoc] = null;            waitingBytes -= doc.sizeInBytes();           [color=red] writeDocument(doc);[/color]          } else            break;        }




 private void writeDocument(DocWriter doc) throws IOException {      assert doc == skipDocWriter || nextWriteDocID == doc.docID;      boolean success = false;      try {        doc.finish();        nextWriteDocID++;        numDocsInStore++;       
 nextWriteLoc++;

        assert nextWriteLoc <= waiting.length;
        if (nextWriteLoc == waiting.length)
          nextWriteLoc = 0;
        success = true;
      } finally {
        if (!success)
          setAborting();
      }
    }


但是这样会有个问题,这个队列越来越大怎么办,会吃掉很多内存。所以设置了一个上限,
 synchronized boolean doPause() {      return waitingBytes > waitQueuePauseBytes;    }


 private long ramBufferSize = (long) (IndexWriter.DEFAULT_RAM_BUFFER_SIZE_MB*1024*1024);  private long waitQueuePauseBytes = (long) (ramBufferSize*0.1);


waitQueuePauseBytes算下来就是1.6*1024*1024,其实还是很大了,呵呵。

超过这个值得时候,这个线程就会暂停,
 if (doPause)        waitForWaitQueue();


 synchronized void waitForWaitQueue() {    do {      try {        wait();      } catch (InterruptedException e) {        Thread.currentThread().interrupt();      }    } while (!waitQueue.doResume());  }


这个时候就是等待notify。

还有个苏醒的条件是doResume,
 synchronized boolean doResume() {      return waitingBytes <= waitQueueResumeBytes;    }


这个值得大小其实就是之前说的暂停值得一半。

看起来整个过程是比较麻烦的了,多线程搞同步就是比较麻烦啊,呵呵。
不过lucene为什么要文档号按顺序写呢?

热点排行