Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 908561) +++ CHANGES.txt (working copy) @@ -64,6 +64,13 @@ * LUCENE-2240: SimpleAnalyzer and WhitespaceAnalyzer now have Version ctors. (Simon Willnauer via Uwe Schindler) +* LUCENE-2259: Add IndexWriter.removeUnusedFiles, to attempt removing + unused files. This is only useful on Windows, which prevents + deletion of open files. IndexWriter will eventually remove these + files itself; this method just lets you do so when you know the + files are no longer open by IndexReaders. (luocanrao via Mike + McCandless) + Bug fixes * LUCENE-2092: BooleanQuery was ignoring disableCoord in its hashCode Index: src/test/org/apache/lucene/index/TestIndexWriter.java =================================================================== --- src/test/org/apache/lucene/index/TestIndexWriter.java (revision 908561) +++ src/test/org/apache/lucene/index/TestIndexWriter.java (working copy) @@ -4670,4 +4670,62 @@ dir.close(); assertFalse(failed.get()); } + + public void testDeleteUnusedFiles() throws Exception { + + for(int iter=0;iter<2;iter++) { + Directory dir = new MockRAMDirectory(); + IndexWriter w = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED); + Document doc = new Document(); + doc.add(new Field("field", "go", Field.Store.NO, Field.Index.ANALYZED)); + w.addDocument(doc); + IndexReader r; + if (iter == 0) { + // use NRT + r = w.getReader(); + } else { + // don't use NRT + w.commit(); + r = IndexReader.open(dir); + } + + List files = Arrays.asList(dir.listAll()); + assertTrue(files.contains("_0.cfs")); + w.addDocument(doc); + w.optimize(); + if (iter == 1) { + w.commit(); + } + IndexReader r2 = r.reopen(); + assertTrue(r != r2); + files = Arrays.asList(dir.listAll()); + assertTrue(files.contains("_0.cfs")); + // optimize created this + assertTrue(files.contains("_2.cfs")); + w.deleteUnusedFiles(); + + files = Arrays.asList(dir.listAll()); + // r still holds this file open + assertTrue(files.contains("_0.cfs")); + assertTrue(files.contains("_2.cfs")); + + r.close(); + if (iter == 0) { + // on closing NRT reader, it calls writer.deleteUnusedFiles + files = Arrays.asList(dir.listAll()); + assertFalse(files.contains("_0.cfs")); + } else { + // now writer can remove it + w.deleteUnusedFiles(); + files = Arrays.asList(dir.listAll()); + assertFalse(files.contains("_0.cfs")); + } + assertTrue(files.contains("_2.cfs")); + + w.close(); + r2.close(); + + dir.close(); + } + } } Index: src/java/org/apache/lucene/index/DirectoryReader.java =================================================================== --- src/java/org/apache/lucene/index/DirectoryReader.java (revision 908561) +++ src/java/org/apache/lucene/index/DirectoryReader.java (working copy) @@ -883,6 +883,12 @@ // not a good idea): FieldCache.DEFAULT.purge(this); + if (writer != null) { + // Since we just closed, writer may now be able to + // delete unused files: + writer.deleteUnusedFiles(); + } + // throw the first exception if (ioe != null) throw ioe; } Index: src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- src/java/org/apache/lucene/index/IndexWriter.java (revision 908561) +++ src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -4883,4 +4883,25 @@ synchronized boolean isClosed() { return closed; } + + /** Expert: remove any index files that are no longer + * used. + * + *

IndexWriter normally deletes unused files itself, + * during indexing. However, on Windows, which disallows + * deletion of open files, if there is a reader open on + * the index then those files cannot be deleted. This is + * fine, because IndexWriter will periodically retry + * the deletion.

+ * + *

However, IndexWriter doesn't try that often: only + * on open, close, flushing a new segment, and finishing + * a merge. If you don't do any of these actions with your + * IndexWriter, you'll see the unused files linger. If + * that's a problem, call this method to delete them + * (once you've closed the open readers that were + * preventing their deletion). */ + public synchronized void deleteUnusedFiles() throws IOException { + deleter.deletePendingFiles(); + } } Index: src/java/org/apache/lucene/index/IndexFileDeleter.java =================================================================== --- src/java/org/apache/lucene/index/IndexFileDeleter.java (revision 908561) +++ src/java/org/apache/lucene/index/IndexFileDeleter.java (working copy) @@ -338,7 +338,7 @@ deletePendingFiles(); } - private void deletePendingFiles() throws IOException { + public void deletePendingFiles() throws IOException { if (deletable != null) { List oldDeletable = deletable; deletable = null;