You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by mi...@apache.org on 2007/07/18 01:22:57 UTC

svn commit: r557082 - in /lucene/java/trunk: CHANGES.txt src/java/org/apache/lucene/index/IndexWriter.java src/test/org/apache/lucene/index/TestIndexWriterDelete.java

Author: mikemccand
Date: Tue Jul 17 16:22:56 2007
New Revision: 557082

URL: http://svn.apache.org/viewvc?view=rev&rev=557082
Log:
LUCENE-962: fixed case where unhandled exception in addDocument or updateDocument could fail to delete unreferenced files in the index

Modified:
    lucene/java/trunk/CHANGES.txt
    lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java
    lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexWriterDelete.java

Modified: lucene/java/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?view=diff&rev=557082&r1=557081&r2=557082
==============================================================================
--- lucene/java/trunk/CHANGES.txt (original)
+++ lucene/java/trunk/CHANGES.txt Tue Jul 17 16:22:56 2007
@@ -35,6 +35,11 @@
     IndexWriter's methods could cause deletes to be lost.
     (Steven Parkes via Mike McCandless)
       
+ 4. LUCENE-962: Fixed case where an unhandled exception in
+    IndexWriter.addDocument or IndexWriter.updateDocument could cause
+    unreferenced files in the index to not be deleted
+    (Steven Parkes via Mike McCandless)
+      
 New features
 
  1. LUCENE-906: Elision filter for French.

Modified: lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java?view=diff&rev=557082&r1=557081&r2=557082
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/index/IndexWriter.java Tue Jul 17 16:22:56 2007
@@ -1112,7 +1112,14 @@
    */
   public void addDocument(Document doc, Analyzer analyzer) throws CorruptIndexException, IOException {
     ensureOpen();
-    if (docWriter.addDocument(doc, analyzer))
+    boolean success = false;
+    try {
+      success = docWriter.addDocument(doc, analyzer);
+    } catch (IOException ioe) {
+      deleter.refresh();
+      throw ioe;
+    }
+    if (success)
       flush(true, false);
   }
 
@@ -1180,7 +1187,14 @@
     synchronized (this) {
       bufferDeleteTerm(term);
     }
-    if (docWriter.addDocument(doc, analyzer))
+    boolean success = false;
+    try {
+      success = docWriter.addDocument(doc, analyzer);
+    } catch (IOException ioe) {
+      deleter.refresh();
+      throw ioe;
+    }
+    if (success)
       flush(true, false);
     else
       maybeFlush();

Modified: lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexWriterDelete.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexWriterDelete.java?view=diff&rev=557082&r1=557081&r2=557082
==============================================================================
--- lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexWriterDelete.java (original)
+++ lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexWriterDelete.java Tue Jul 17 16:22:56 2007
@@ -576,8 +576,7 @@
 
     for(int pass=0;pass<2;pass++) {
       boolean autoCommit = (0==pass);
-      Directory ramDir = new RAMDirectory();
-      MockRAMDirectory dir = new MockRAMDirectory(ramDir);
+      MockRAMDirectory dir = new MockRAMDirectory();
       IndexWriter modifier = new IndexWriter(dir, autoCommit,
                                              new WhitespaceAnalyzer(), true);
       modifier.setUseCompoundFile(true);
@@ -673,6 +672,75 @@
 
       dir.close();
     }
+  }
+
+  // This test tests that the files created by the docs writer before
+  // a segment is written are cleaned up if there's an i/o error
+
+  public void testErrorInDocsWriterAdd() throws IOException {
+    
+    MockRAMDirectory.Failure failure = new MockRAMDirectory.Failure() {
+        boolean failed = false;
+        public MockRAMDirectory.Failure reset() {
+          failed = false;
+          return this;
+        }
+        public void eval(MockRAMDirectory dir)  throws IOException {
+          if (!failed) {
+            throw new IOException("fail in add doc");
+          }
+        }
+      };
+
+    // create a couple of files
+
+    String[] keywords = { "1", "2" };
+    String[] unindexed = { "Netherlands", "Italy" };
+    String[] unstored = { "Amsterdam has lots of bridges",
+        "Venice has lots of canals" };
+    String[] text = { "Amsterdam", "Venice" };
+
+    for(int pass=0;pass<2;pass++) {
+      boolean autoCommit = (0==pass);
+      MockRAMDirectory dir = new MockRAMDirectory();
+      IndexWriter modifier = new IndexWriter(dir, autoCommit,
+                                             new WhitespaceAnalyzer(), true);
+
+      dir.failOn(failure.reset());
+
+      for (int i = 0; i < keywords.length; i++) {
+        Document doc = new Document();
+        doc.add(new Field("id", keywords[i], Field.Store.YES,
+                          Field.Index.UN_TOKENIZED));
+        doc.add(new Field("country", unindexed[i], Field.Store.YES,
+                          Field.Index.NO));
+        doc.add(new Field("contents", unstored[i], Field.Store.NO,
+                          Field.Index.TOKENIZED));
+        doc.add(new Field("city", text[i], Field.Store.YES,
+                          Field.Index.TOKENIZED));
+        try {
+          modifier.addDocument(doc);
+        } catch (IOException io) {
+          break;
+        }
+      }
+
+      String[] startFiles = dir.list();
+      SegmentInfos infos = new SegmentInfos();
+      infos.read(dir);
+      IndexFileDeleter d = new IndexFileDeleter(dir, new KeepOnlyLastCommitDeletionPolicy(), infos, null, null);
+      String[] endFiles = dir.list();
+
+      if (!Arrays.equals(startFiles, endFiles)) {
+        fail("docswriter abort() failed to delete unreferenced files:\n  before delete:\n    "
+             + arrayToString(startFiles) + "\n  after delete:\n    "
+             + arrayToString(endFiles));
+      }
+
+      modifier.close();
+
+    }
+
   }
 
   private String arrayToString(String[] l) {