Index: src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- src/java/org/apache/lucene/index/IndexWriter.java (revision 633410) +++ src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -2632,6 +2632,10 @@ * each input Directory, so it is up to the caller to * enforce this. * + *
NOTE: while this is running, any attempts to + * add or delete documents (with another thread) will be + * paused until this method completes. + * *
After this completes, the index is optimized. * *
This method is transactional in how Exceptions are @@ -2670,11 +2674,16 @@ * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public synchronized void addIndexes(Directory[] dirs) + public void addIndexes(Directory[] dirs) throws CorruptIndexException, IOException { ensureOpen(); + + // Do not allow add docs or deletes while we are running: + docWriter.pauseAllThreads(); + try { + if (infoStream != null) message("flush at addIndexes"); flush(true, false); @@ -2684,11 +2693,13 @@ startTransaction(); try { - for (int i = 0; i < dirs.length; i++) { - SegmentInfos sis = new SegmentInfos(); // read infos from dir - sis.read(dirs[i]); - for (int j = 0; j < sis.size(); j++) { - segmentInfos.addElement(sis.info(j)); // add each info + synchronized(this) { + for (int i = 0; i < dirs.length; i++) { + SegmentInfos sis = new SegmentInfos(); // read infos from dir + sis.read(dirs[i]); + for (int j = 0; j < sis.size(); j++) { + segmentInfos.addElement(sis.info(j)); // add each info + } } } @@ -2705,6 +2716,8 @@ } catch (OutOfMemoryError oom) { hitOOM = true; throw oom; + } finally { + docWriter.resumeAllThreads(); } } @@ -2726,6 +2739,10 @@ * each input Directory, so it is up to the caller to * enforce this. * + *
NOTE: while this is running, any attempts to + * add or delete documents (with another thread) will be + * paused until this method completes. + * *
* This requires this index not be among those to be added, and the
* upper bound* of those segment doc counts not exceed maxMergeDocs.
@@ -2737,11 +2754,14 @@
* @throws CorruptIndexException if the index is corrupt
* @throws IOException if there is a low-level IO error
*/
- public synchronized void addIndexesNoOptimize(Directory[] dirs)
+ public void addIndexesNoOptimize(Directory[] dirs)
throws CorruptIndexException, IOException {
ensureOpen();
+ // Do not allow add docs or deletes while we are running:
+ docWriter.pauseAllThreads();
+
try {
if (infoStream != null)
message("flush at addIndexesNoOptimize");
@@ -2753,17 +2773,19 @@
try {
- for (int i = 0; i < dirs.length; i++) {
- if (directory == dirs[i]) {
- // cannot add this index: segments may be deleted in merge before added
- throw new IllegalArgumentException("Cannot add this index to itself");
- }
+ synchronized(this) {
+ for (int i = 0; i < dirs.length; i++) {
+ if (directory == dirs[i]) {
+ // cannot add this index: segments may be deleted in merge before added
+ throw new IllegalArgumentException("Cannot add this index to itself");
+ }
- SegmentInfos sis = new SegmentInfos(); // read infos from dir
- sis.read(dirs[i]);
- for (int j = 0; j < sis.size(); j++) {
- SegmentInfo info = sis.info(j);
- segmentInfos.addElement(info); // add each info
+ SegmentInfos sis = new SegmentInfos(); // read infos from dir
+ sis.read(dirs[i]);
+ for (int j = 0; j < sis.size(); j++) {
+ SegmentInfo info = sis.info(j);
+ segmentInfos.addElement(info); // add each info
+ }
}
}
@@ -2788,18 +2810,30 @@
} catch (OutOfMemoryError oom) {
hitOOM = true;
throw oom;
+ } finally {
+ docWriter.resumeAllThreads();
}
}
/* If any of our segments are using a directory != ours
* then copy them over. Currently this is only used by
* addIndexesNoOptimize(). */
- private synchronized void copyExternalSegments() throws CorruptIndexException, IOException {
- final int numSegments = segmentInfos.size();
- for(int i=0;i
The provided IndexReaders are not closed.
+ *NOTE: the index in each Directory must not be + * changed (opened by a writer) while this method is + * running. This method does not acquire a write lock in + * each input Directory, so it is up to the caller to + * enforce this. + * + *
NOTE: while this is running, any attempts to + * add or delete documents (with another thread) will be + * paused until this method completes. + * *
See {@link #addIndexes(Directory[])} for * details on transactional semantics, temporary free * space required in the Directory, and non-CFS segments @@ -2830,10 +2876,14 @@ * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public synchronized void addIndexes(IndexReader[] readers) + public void addIndexes(IndexReader[] readers) throws CorruptIndexException, IOException { ensureOpen(); + + // Do not allow add docs or deletes while we are running: + docWriter.pauseAllThreads(); + try { optimize(); // start with zero or 1 seg @@ -2844,9 +2894,11 @@ IndexReader sReader = null; try { - if (segmentInfos.size() == 1){ // add existing index, if any - sReader = SegmentReader.get(segmentInfos.info(0)); - merger.add(sReader); + synchronized(this) { + if (segmentInfos.size() == 1){ // add existing index, if any + sReader = SegmentReader.get(segmentInfos.info(0)); + merger.add(sReader); + } } for (int i = 0; i < readers.length; i++) // add new indexes @@ -2864,10 +2916,12 @@ sReader = null; } - segmentInfos.setSize(0); // pop old infos & add new - info = new SegmentInfo(mergedName, docCount, directory, false, true, - -1, null, false); - segmentInfos.addElement(info); + synchronized(this) { + segmentInfos.setSize(0); // pop old infos & add new + info = new SegmentInfo(mergedName, docCount, directory, false, true, + -1, null, false); + segmentInfos.addElement(info); + } success = true; @@ -2895,7 +2949,9 @@ try { merger.createCompoundFile(mergedName + ".cfs"); - info.setUseCompoundFile(true); + synchronized(this) { + info.setUseCompoundFile(true); + } } finally { if (!success) { if (infoStream != null) @@ -2910,6 +2966,8 @@ } catch (OutOfMemoryError oom) { hitOOM = true; throw oom; + } finally { + docWriter.resumeAllThreads(); } }