Ok, the patch proposed by Christoph has another problem. It ends up openning IndexReader twice, but closes it only once. This leaves files open that shows up with running TestIndexReader with FSDirectory.
I's just brackets on the if that were missing. I'm attaching an updated patch and a modified TestIndexReader.java test file. It now has more checks, comments, and a few more test cases.

By the way, what's the policy on commits? Do I need to some +1s before committing fixes like this? What about larger changes like the file handles? (Assuming that my commit access still works).

Thanks.
Dmitry.




Index: src/java/org/apache/lucene/index/IndexReader.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-lucene/src/java/org/apache/lucene/index/IndexReader.java,v
retrieving revision 1.17
diff -B -u -w -r1.17 IndexReader.java
--- src/java/org/apache/lucene/index/IndexReader.java   12 Aug 2003 15:05:03 -0000     
 1.17
+++ src/java/org/apache/lucene/index/IndexReader.java   24 Sep 2003 02:21:14 -0000
@@ -80,11 +80,15 @@
 public abstract class IndexReader {
   protected IndexReader(Directory directory) {
     this.directory = directory;
+    segmentInfosAge = Long.MAX_VALUE;
   }
 
   Directory directory;
   private Lock writeLock;
 
+  //used to determine whether index has chaged since reader was opened
+  private long segmentInfosAge;
+  
   /** Returns an IndexReader reading the index in an FSDirectory in the named
   path. */
   public static IndexReader open(String path) throws IOException {
@@ -102,15 +106,21 @@
     synchronized (directory) {                   // in- & inter-process sync
       return (IndexReader)new Lock.With(directory.makeLock("commit.lock"), 
IndexWriter.COMMIT_LOCK_TIMEOUT) {
          public Object doBody() throws IOException {
+            IndexReader result = null;
+            
            SegmentInfos infos = new SegmentInfos();
            infos.read(directory);
-           if (infos.size() == 1)                // index is optimized
-             return new SegmentReader(infos.info(0), true);
-
+            if (infos.size() == 1) {             // index is optimized
+                result = new SegmentReader(infos.info(0), true);
+            } else {
            SegmentReader[] readers = new SegmentReader[infos.size()];
            for (int i = 0; i < infos.size(); i++)
              readers[i] = new SegmentReader(infos.info(i), i==infos.size()-1);
-           return new SegmentsReader(directory, readers);
+                result =  new SegmentsReader(directory, readers);
+            }
+        
+            result.segmentInfosAge = lastModified(directory);
+            return result;
          }
        }.run();
     }
@@ -258,6 +268,15 @@
       if (!writeLock.obtain(IndexWriter.WRITE_LOCK_TIMEOUT)) // obtain write lock
         throw new IOException("Index locked for write: " + writeLock);
       this.writeLock = writeLock;
+
+      // we have to check whether index has changed since this reader was opened.
+      // if so, this reader is no longer valid for deletion
+      if(lastModified(directory) > segmentInfosAge){
+          this.writeLock.release();
+          this.writeLock = null;
+          throw new IOException(
+            "IndexReader out of date and no longer valid for deletion");
+      }
     }
     doDelete(docNum);
   }

Attachment: TestIndexReader.java
Description: JavaScript source

Index: src/java/org/apache/lucene/store/RAMDirectory.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-lucene/src/java/org/apache/lucene/store/RAMDirectory.java,v
retrieving revision 1.8
diff -B -u -w -r1.8 RAMDirectory.java
--- src/java/org/apache/lucene/store/RAMDirectory.java  1 May 2003 19:50:17 -0000      
 1.8
+++ src/java/org/apache/lucene/store/RAMDirectory.java  24 Sep 2003 02:22:46 -0000
@@ -146,8 +146,23 @@
 
   /** Set the modified time of an existing file to now. */
   public void touchFile(String name) throws IOException {
+    final boolean MONITOR = false;
+    int count = 0;
+    
     RAMFile file = (RAMFile)files.get(name);
-    file.lastModified = System.currentTimeMillis();
+    long ts2, ts1 = System.currentTimeMillis();
+    do {
+        try {
+            Thread.sleep(0, 1);
+        } catch (InterruptedException e) {}
+        ts2 = System.currentTimeMillis();
+        if (MONITOR) count ++;
+    } while(ts1 == ts2);
+    
+    file.lastModified = ts2;
+
+    if (MONITOR)
+        System.out.println("SLEEP COUNT: " + count);        
   }
 
   /** Returns the length in bytes of a file in the directory. */

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to