⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 indexwriter.java

📁 Lucene 2.1的源代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            numSegments++;          }        }        if (!exceedsUpperLimit) {          // if none of the merged segments exceed upperBound, done          break;        }      }      lowerBound = upperBound;      upperBound *= mergeFactor;    }  }  /**   * Merges the named range of segments, replacing them in the stack with a   * single segment.   */  private final int mergeSegments(SegmentInfos sourceSegments, int minSegment, int end)    throws IOException {    // We may be called solely because there are deletes    // pending, in which case doMerge is false:    boolean doMerge = end > 0;    final String mergedName = newSegmentName();    SegmentMerger merger = null;    final Vector segmentsToDelete = new Vector();    String segmentsInfosFileName = segmentInfos.getCurrentSegmentFileName();    String nextSegmentsFileName = segmentInfos.getNextSegmentFileName();    SegmentInfo newSegment = null;    int mergedDocCount = 0;    // This is try/finally to make sure merger's readers are closed:    try {      if (doMerge) {        if (infoStream != null) infoStream.print("merging segments");        merger = new SegmentMerger(this, mergedName);        for (int i = minSegment; i < end; i++) {          SegmentInfo si = sourceSegments.info(i);          if (infoStream != null)            infoStream.print(" " + si.name + " (" + si.docCount + " docs)");          IndexReader reader = SegmentReader.get(si); // no need to set deleter (yet)          merger.add(reader);          if ((reader.directory() == this.directory) || // if we own the directory              (reader.directory() == this.ramDirectory))            segmentsToDelete.addElement(reader);   // queue segment for deletion        }      }      SegmentInfos rollback = null;      boolean success = false;      // This is try/finally to rollback our internal state      // if we hit exception when doing the merge:      try {        if (doMerge) {          mergedDocCount = merger.merge();          if (infoStream != null) {            infoStream.println(" into "+mergedName+" ("+mergedDocCount+" docs)");          }          newSegment = new SegmentInfo(mergedName, mergedDocCount,                                       directory, false, true);        }        if (!inTransaction            && (sourceSegments != ramSegmentInfos || bufferedDeleteTerms.size() > 0)) {          // Now save the SegmentInfo instances that          // we are replacing:          rollback = (SegmentInfos) segmentInfos.clone();        }        if (doMerge) {          if (sourceSegments == ramSegmentInfos) {            segmentInfos.addElement(newSegment);          } else {            for (int i = end-1; i > minSegment; i--)     // remove old infos & add new              sourceSegments.remove(i);            segmentInfos.set(minSegment, newSegment);          }        }        if (sourceSegments == ramSegmentInfos) {          // Should not be necessary: no prior commit should          // have left pending files, so just defensive:          deleter.clearPendingFiles();          maybeApplyDeletes(doMerge);          doAfterFlush();        }        if (!inTransaction) {          segmentInfos.write(directory);     // commit before deleting        } else {          commitPending = true;        }        success = true;      } finally {        if (success) {          // The non-ram-segments case is already committed          // (above), so all the remains for ram segments case          // is to clear the ram segments:          if (sourceSegments == ramSegmentInfos) {            ramSegmentInfos.removeAllElements();          }        } else if (!inTransaction) {            // Must rollback so our state matches index:          if (sourceSegments == ramSegmentInfos && 0 == bufferedDeleteTerms.size()) {            // Simple case: newSegment may or may not have            // been added to the end of our segment infos,            // so just check & remove if so:            if (newSegment != null &&                 segmentInfos.size() > 0 &&                 segmentInfos.info(segmentInfos.size()-1) == newSegment) {              segmentInfos.remove(segmentInfos.size()-1);            }          } else if (rollback != null) {            // Rollback the individual SegmentInfo            // instances, but keep original SegmentInfos            // instance (so we don't try to write again the            // same segments_N file -- write once):            segmentInfos.clear();            segmentInfos.addAll(rollback);          }          // Erase any pending files that we were going to delete:          // i.e. old del files added by SegmentReader.doCommit()           deleter.clearPendingFiles();          // Delete any partially created files:          deleter.deleteFile(nextSegmentsFileName);          deleter.findDeletableFiles();          deleter.deleteFiles();        }      }    } finally {      // close readers before we attempt to delete now-obsolete segments      if (doMerge) merger.closeReaders();    }    if (!inTransaction) {      // Attempt to delete all files we just obsoleted:      deleter.deleteFile(segmentsInfosFileName);    // delete old segments_N file      deleter.deleteSegments(segmentsToDelete);     // delete now-unused segments      // Includes the old del files      deleter.commitPendingFiles();    } else {      deleter.addPendingFile(segmentsInfosFileName);    // delete old segments_N file      deleter.deleteSegments(segmentsToDelete, protectedSegments);     // delete now-unused segments    }    if (useCompoundFile && doMerge) {      segmentsInfosFileName = nextSegmentsFileName;      nextSegmentsFileName = segmentInfos.getNextSegmentFileName();      Vector filesToDelete;      boolean success = false;      try {        filesToDelete = merger.createCompoundFile(mergedName + ".cfs");        newSegment.setUseCompoundFile(true);        if (!inTransaction) {          segmentInfos.write(directory);     // commit again so readers know we've switched this segment to a compound file        }        success = true;      } finally {        if (!success && !inTransaction) {            // Must rollback:          newSegment.setUseCompoundFile(false);          deleter.deleteFile(mergedName + ".cfs");          deleter.deleteFile(nextSegmentsFileName);        }      }      if (!inTransaction) {        deleter.deleteFile(segmentsInfosFileName);  // delete old segments_N file      }      // We can delete these segments whether or not we are      // in a transaction because we had just written them      // above so they can't need protection by the      // transaction:      deleter.deleteFiles(filesToDelete);  // delete now-unused segments    }    return mergedDocCount;  }  // Called during flush to apply any buffered deletes.  If  // doMerge is true then a new segment was just created and  // flushed from the ram segments.  private final void maybeApplyDeletes(boolean doMerge) throws IOException {    if (bufferedDeleteTerms.size() > 0) {      if (infoStream != null)        infoStream.println("flush " + numBufferedDeleteTerms + " buffered deleted terms on "                           + segmentInfos.size() + " segments.");      if (doMerge) {        IndexReader reader = null;        try {          reader = SegmentReader.get(segmentInfos.info(segmentInfos.size() - 1));          reader.setDeleter(deleter);          // Apply delete terms to the segment just flushed from ram          // apply appropriately so that a delete term is only applied to          // the documents buffered before it, not those buffered after it.          applyDeletesSelectively(bufferedDeleteTerms, reader);        } finally {          if (reader != null)            reader.close();        }      }      int infosEnd = segmentInfos.size();      if (doMerge) {        infosEnd--;      }      for (int i = 0; i < infosEnd; i++) {        IndexReader reader = null;        try {          reader = SegmentReader.get(segmentInfos.info(i));          reader.setDeleter(deleter);          // Apply delete terms to disk segments          // except the one just flushed from ram.          applyDeletes(bufferedDeleteTerms, reader);        } finally {          if (reader != null)            reader.close();        }      }      // Clean up bufferedDeleteTerms.      bufferedDeleteTerms.clear();      numBufferedDeleteTerms = 0;    }  }  private final boolean checkNonDecreasingLevels(int start) {    int lowerBound = -1;    int upperBound = minMergeDocs;    for (int i = segmentInfos.size() - 1; i >= start; i--) {      int docCount = segmentInfos.info(i).docCount;      if (docCount <= lowerBound) {        return false;      }      while (docCount > upperBound) {        lowerBound = upperBound;        upperBound *= mergeFactor;      }    }    return true;  }  // For test purposes.  final synchronized int getBufferedDeleteTermsSize() {    return bufferedDeleteTerms.size();  }  // For test purposes.  final synchronized int getNumBufferedDeleteTerms() {    return numBufferedDeleteTerms;  }  // Number of ram segments a delete term applies to.  private class Num {    private int num;    Num(int num) {      this.num = num;    }    int getNum() {      return num;    }    void setNum(int num) {      this.num = num;    }  }  // Buffer a term in bufferedDeleteTerms, which records the  // current number of documents buffered in ram so that the  // delete term will be applied to those ram segments as  // well as the disk segments.  private void bufferDeleteTerm(Term term) {    Num num = (Num) bufferedDeleteTerms.get(term);    if (num == null) {      bufferedDeleteTerms.put(term, new Num(ramSegmentInfos.size()));    } else {      num.setNum(ramSegmentInfos.size());    }    numBufferedDeleteTerms++;  }  // Apply buffered delete terms to the segment just flushed from ram  // apply appropriately so that a delete term is only applied to  // the documents buffered before it, not those buffered after it.  private final void applyDeletesSelectively(HashMap deleteTerms,      IndexReader reader) throws IOException {    Iterator iter = deleteTerms.entrySet().iterator();    while (iter.hasNext()) {      Entry entry = (Entry) iter.next();      Term term = (Term) entry.getKey();      TermDocs docs = reader.termDocs(term);      if (docs != null) {        int num = ((Num) entry.getValue()).getNum();        try {          while (docs.next()) {            int doc = docs.doc();            if (doc >= num) {              break;            }            reader.deleteDocument(doc);          }        } finally {          docs.close();        }      }    }  }  // Apply buffered delete terms to this reader.  private final void applyDeletes(HashMap deleteTerms, IndexReader reader)      throws IOException {    Iterator iter = deleteTerms.entrySet().iterator();    while (iter.hasNext()) {      Entry entry = (Entry) iter.next();      reader.deleteDocuments((Term) entry.getKey());    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -