diff --git a/src/java/org/apache/lucene/index/IndexWriter.java b/src/java/org/apache/lucene/index/IndexWriter.java index b73a80bb059..21f69950f45 100644 --- a/src/java/org/apache/lucene/index/IndexWriter.java +++ b/src/java/org/apache/lucene/index/IndexWriter.java @@ -117,7 +117,8 @@ public class IndexWriter { * may also cause file handle problems. */ private boolean useCompoundFile = true; - + + private boolean closeDir; /** Setting to turn on usage of a compound file. When on, multiple files * for each segment are merged into a single file once the segment creation @@ -169,7 +170,7 @@ public class IndexWriter { */ public IndexWriter(String path, Analyzer a, boolean create) throws IOException { - this(FSDirectory.getDirectory(path, create), a, create); + this(FSDirectory.getDirectory(path, create), a, create, true); } /** @@ -189,7 +190,7 @@ public class IndexWriter { */ public IndexWriter(File path, Analyzer a, boolean create) throws IOException { - this(FSDirectory.getDirectory(path, create), a, create); + this(FSDirectory.getDirectory(path, create), a, create, true); } /** @@ -207,37 +208,43 @@ public class IndexWriter { * if it does not exist, and create is * false */ - public IndexWriter(Directory d, Analyzer a, final boolean create) + public IndexWriter(Directory d, Analyzer a, boolean create) throws IOException { - directory = d; - analyzer = a; + this(d, a, create, false); + } + + private IndexWriter(Directory d, Analyzer a, final boolean create, boolean closeDir) + throws IOException { + this.closeDir = closeDir; + directory = d; + analyzer = a; - Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME); - if (!writeLock.obtain(WRITE_LOCK_TIMEOUT)) // obtain write lock - throw new IOException("Index locked for write: " + writeLock); - this.writeLock = writeLock; // save it + Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME); + if (!writeLock.obtain(WRITE_LOCK_TIMEOUT)) // obtain write lock + throw new IOException("Index locked for write: " + writeLock); + this.writeLock = writeLock; // save it - synchronized (directory) { // in- & inter-process sync - new Lock.With(directory.makeLock(IndexWriter.COMMIT_LOCK_NAME), COMMIT_LOCK_TIMEOUT) { - public Object doBody() throws IOException { - if (create) - segmentInfos.write(directory); - else - segmentInfos.read(directory); - return null; - } - }.run(); - } + synchronized (directory) { // in- & inter-process sync + new Lock.With(directory.makeLock(IndexWriter.COMMIT_LOCK_NAME), COMMIT_LOCK_TIMEOUT) { + public Object doBody() throws IOException { + if (create) + segmentInfos.write(directory); + else + segmentInfos.read(directory); + return null; + } + }.run(); + } } - /** Flushes all changes to an index, closes all associated files, and closes - the directory that the index is stored in. */ + /** Flushes all changes to an index and closes all associated files. */ public synchronized void close() throws IOException { flushRamSegments(); ramDirectory.close(); writeLock.release(); // release write lock writeLock = null; - directory.close(); + if(closeDir) + directory.close(); } /** Release the write lock, if needed. */ @@ -379,7 +386,9 @@ public class IndexWriter { } /** Merges the provided indexes into this index. - *

After this completes, the index is optimized. */ + *

After this completes, the index is optimized.

+ *

The provided IndexReaders are not closed.

+ */ public synchronized void addIndexes(IndexReader[] readers) throws IOException { @@ -490,6 +499,8 @@ public class IndexWriter { } }.run(); } + + merger.closeReaders(); } /* Some operating systems (e.g. Windows) don't permit a file to be deleted diff --git a/src/java/org/apache/lucene/index/SegmentMerger.java b/src/java/org/apache/lucene/index/SegmentMerger.java index b631cae6450..71555c18872 100644 --- a/src/java/org/apache/lucene/index/SegmentMerger.java +++ b/src/java/org/apache/lucene/index/SegmentMerger.java @@ -88,26 +88,31 @@ final class SegmentMerger { */ final int merge() throws IOException { int value; - try { - value = mergeFields(); - mergeTerms(); - mergeNorms(); + + value = mergeFields(); + mergeTerms(); + mergeNorms(); - if (fieldInfos.hasVectors()) - mergeVectors(); - - } finally { - for (int i = 0; i < readers.size(); i++) { // close readers - IndexReader reader = (IndexReader) readers.elementAt(i); - reader.close(); - } - } + if (fieldInfos.hasVectors()) + mergeVectors(); if (useCompoundFile) createCompoundFile(); return value; } + + /** + * close all IndexReaders that have been added. + * Should not be called before merge(). + * @throws IOException + */ + final void closeReaders() throws IOException { + for (int i = 0; i < readers.size(); i++) { // close readers + IndexReader reader = (IndexReader) readers.elementAt(i); + reader.close(); + } + } private final void createCompoundFile() throws IOException { diff --git a/src/test/org/apache/lucene/index/DocTest.java b/src/test/org/apache/lucene/index/DocTest.java index 240bf654d0f..6c9441811e1 100644 --- a/src/test/org/apache/lucene/index/DocTest.java +++ b/src/test/org/apache/lucene/index/DocTest.java @@ -80,6 +80,7 @@ class DocTest { merger.add(r1); merger.add(r2); merger.merge(); + merger.closeReaders(); directory.close(); } diff --git a/src/test/org/apache/lucene/index/TestDoc.java b/src/test/org/apache/lucene/index/TestDoc.java index 675b475ad03..557174f7b3c 100644 --- a/src/test/org/apache/lucene/index/TestDoc.java +++ b/src/test/org/apache/lucene/index/TestDoc.java @@ -186,6 +186,7 @@ public class TestDoc extends TestCase { merger.add(r1); merger.add(r2); merger.merge(); + merger.closeReaders(); directory.close(); } diff --git a/src/test/org/apache/lucene/index/TestSegmentMerger.java b/src/test/org/apache/lucene/index/TestSegmentMerger.java index aaff8bca1e1..95c86484e2e 100644 --- a/src/test/org/apache/lucene/index/TestSegmentMerger.java +++ b/src/test/org/apache/lucene/index/TestSegmentMerger.java @@ -77,6 +77,7 @@ public class TestSegmentMerger extends TestCase { merger.add(reader2); try { int docsMerged = merger.merge(); + merger.closeReaders(); assertTrue(docsMerged == 2); //Should be able to open a new SegmentReader against the new directory SegmentReader mergedReader = new SegmentReader(new SegmentInfo(mergedSegment, docsMerged, mergedDir));