Index: lucene/contrib/CHANGES.txt =================================================================== --- lucene/contrib/CHANGES.txt (revision 1133480) +++ lucene/contrib/CHANGES.txt (working copy) @@ -79,6 +79,12 @@ First/SecondPassGroupingCollector. (Martijn van Groningen, Mike McCandless) +Bug Fixes + + * LUCENE-3185: Fix bug in NRTCachingDirectory.deleteFile that would + always throw exception and sometimes fail to actually delete the + file. (Mike McCandless) + Build * LUCENE-3149: Upgrade contrib/icu's ICU jar file to ICU 4.8. Index: lucene/contrib/misc/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java =================================================================== --- lucene/contrib/misc/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java (revision 1133480) +++ lucene/contrib/misc/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java (working copy) @@ -111,4 +111,12 @@ conf.setMergeScheduler(cachedFSDir.getMergeScheduler()); IndexWriter writer = new IndexWriter(cachedFSDir, conf); } + + public void testDeleteFile() throws Exception { + Directory dir = new NRTCachingDirectory(newDirectory(), 2.0, 25.0); + dir.createOutput("foo.txt").close(); + dir.deleteFile("foo.txt"); + assertEquals(0, dir.listAll().length); + dir.close(); + } } Index: lucene/contrib/misc/src/java/org/apache/lucene/store/NRTCachingDirectory.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/store/NRTCachingDirectory.java (revision 1133480) +++ lucene/contrib/misc/src/java/org/apache/lucene/store/NRTCachingDirectory.java (working copy) @@ -89,10 +89,10 @@ private final long maxCachedBytes; private static final boolean VERBOSE = false; - + /** * We will cache a newly created output if 1) it's a - * flush or a merge and the estimated size of the merged segmnt is <= + * flush or a merge and the estimated size of the merged segment is <= * maxMergeSizeMB, and 2) the total cached bytes is <= * maxCachedMB */ public NRTCachingDirectory(Directory delegate, double maxMergeSizeMB, double maxCachedMB) { @@ -102,13 +102,45 @@ } @Override + public LockFactory getLockFactory() { + return delegate.getLockFactory(); + } + + @Override + public void setLockFactory(LockFactory lf) throws IOException { + delegate.setLockFactory(lf); + } + + @Override + public String getLockID() { + return delegate.getLockID(); + } + + @Override + public Lock makeLock(String name) { + return delegate.makeLock(name); + } + + @Override + public void clearLock(String name) throws IOException { + delegate.clearLock(name); + } + + @Override + public String toString() { + return "NRTCachingDirectory(" + delegate + "; maxCacheMB=" + (maxCachedBytes/1024/1024.) + " maxMergeSizeMB=" + (maxMergeSizeBytes/1024/1024.) + ")"; + } + + @Override public synchronized String[] listAll() throws IOException { final Set files = new HashSet(); for(String f : cache.listAll()) { files.add(f); } for(String f : delegate.listAll()) { - assert !files.contains(f); + // Cannot do this -- if lucene calls createOutput but + // file already exists then this falsely trips: + //assert !files.contains(f): "file \"" + f + "\" is in both dirs"; files.add(f); } return files.toArray(new String[files.size()]); @@ -136,12 +168,15 @@ @Override public synchronized void deleteFile(String name) throws IOException { - // Delete from both, in case we are currently uncaching: if (VERBOSE) { System.out.println("nrtdir.deleteFile name=" + name); } - cache.deleteFile(name); - delegate.deleteFile(name); + if (cache.fileExists(name)) { + assert !delegate.fileExists(name); + cache.deleteFile(name); + } else { + delegate.deleteFile(name); + } } @Override @@ -207,16 +242,6 @@ } } - @Override - public Lock makeLock(String name) { - return delegate.makeLock(name); - } - - @Override - public void clearLock(String name) throws IOException { - delegate.clearLock(name); - } - /** Close this directory, which flushes any cached files * to the delegate and then closes the delegate. */ @Override