LUCENE-2209: add expert IndexWriter.removeUnusedFiles to force IW to retry deletion of files no longer used (only useful on windows)

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@909357 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2010-02-12 11:07:31 +00:00
parent 5995714461
commit 7efc00511e
5 changed files with 93 additions and 1 deletions

View File

@ -64,6 +64,13 @@ API Changes
* 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

View File

@ -883,6 +883,12 @@ class DirectoryReader extends IndexReader implements Cloneable {
// 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;
}

View File

@ -338,7 +338,7 @@ final class IndexFileDeleter {
deletePendingFiles();
}
private void deletePendingFiles() throws IOException {
public void deletePendingFiles() throws IOException {
if (deletable != null) {
List<String> oldDeletable = deletable;
deletable = null;

View File

@ -4883,4 +4883,25 @@ public class IndexWriter implements Closeable {
synchronized boolean isClosed() {
return closed;
}
/** Expert: remove any index files that are no longer
* used.
*
* <p> 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.</p>
*
* <p> 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();
}
}

View File

@ -4670,4 +4670,62 @@ public class TestIndexWriter extends LuceneTestCase {
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<String> 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();
}
}
}