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 2009/02/15 11:56:36 UTC

svn commit: r744653 - in /lucene/java/trunk/src: java/org/apache/lucene/index/DirectoryIndexReader.java java/org/apache/lucene/index/IndexReader.java java/org/apache/lucene/index/SegmentReader.java test/org/apache/lucene/index/TestIndexReaderClone.java

Author: mikemccand
Date: Sun Feb 15 10:56:36 2009
New Revision: 744653

URL: http://svn.apache.org/viewvc?rev=744653&view=rev
Log:
LUCENE-1314: allow clone of subreaders; add note to getSequentialSubReaders javadoc to not use sub-readers to make changes

Modified:
    lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java
    lucene/java/trunk/src/java/org/apache/lucene/index/IndexReader.java
    lucene/java/trunk/src/java/org/apache/lucene/index/SegmentReader.java
    lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderClone.java

Modified: lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java?rev=744653&r1=744652&r2=744653&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java Sun Feb 15 10:56:36 2009
@@ -80,7 +80,7 @@
   boolean hasSegmentInfos() {
     return segmentInfos != null;
   }
-  
+
   protected DirectoryIndexReader() {}
   
   DirectoryIndexReader(Directory directory, SegmentInfos segmentInfos,
@@ -167,11 +167,16 @@
   
   public final synchronized IndexReader clone(boolean openReadOnly) throws CorruptIndexException, IOException {
 
-    final SegmentInfos infos = (SegmentInfos) segmentInfos.clone();
-    DirectoryIndexReader newReader = doReopen(infos, true, openReadOnly);
+    final SegmentInfos clonedInfos;
+    if (segmentInfos != null) {
+      clonedInfos = (SegmentInfos) segmentInfos.clone();
+    } else {
+      clonedInfos = null;
+    }
+    DirectoryIndexReader newReader = doReopen(clonedInfos, true, openReadOnly);
     
     if (this != newReader) {
-      newReader.init(directory, infos, closeDirectory, openReadOnly);
+      newReader.init(directory, clonedInfos, closeDirectory, openReadOnly);
       newReader.deletionPolicy = deletionPolicy;
     }
 

Modified: lucene/java/trunk/src/java/org/apache/lucene/index/IndexReader.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/index/IndexReader.java?rev=744653&r1=744652&r2=744653&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/index/IndexReader.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/index/IndexReader.java Sun Feb 15 10:56:36 2009
@@ -1184,13 +1184,21 @@
     return DirectoryIndexReader.listCommits(dir);
   }
 
-  /** Returns the sequential sub readers that this reader is
-   *  logically composed of.  IndexSearcher uses this API to
-   *  drive searching by one sub reader at a time.  If this
-   *  reader is not composed of sequential child readers, it
-   *  should return null.  If this method returns an empty
-   *  array, that means this reader is a null reader (for
-   *  example a MultiReader that has no sub readers).*/
+  /** Expert: returns the sequential sub readers that this
+   *  reader is logically composed of.  For example,
+   *  IndexSearcher uses this API to drive searching by one
+   *  sub reader at a time.  If this reader is not composed
+   *  of sequential child readers, it should return null.
+   *  If this method returns an empty array, that means this
+   *  reader is a null reader (for example a MultiReader
+   *  that has no sub readers).
+   *  <p>
+   *  NOTE: for a MultiSegmentReader, which is obtained by
+   *  {@link #open} when the index has more than one
+   *  segment, you should not use the sub-readers returned
+   *  by this method to make any changes (setNorm,
+   *  deleteDocument, etc.).  Doing so will likely lead to
+   *  index corruption.  Use the parent reader instead. */
   public IndexReader[] getSequentialSubReaders() {
     return null;
   }

Modified: lucene/java/trunk/src/java/org/apache/lucene/index/SegmentReader.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/index/SegmentReader.java?rev=744653&r1=744652&r2=744653&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/index/SegmentReader.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/index/SegmentReader.java Sun Feb 15 10:56:36 2009
@@ -625,8 +625,15 @@
 
   protected synchronized DirectoryIndexReader doReopen(SegmentInfos infos, boolean doClone, boolean openReadOnly) throws CorruptIndexException, IOException {
     DirectoryIndexReader newReader;
-    
-    if (infos.size() == 1) {
+
+    if (infos == null) {
+      if (doClone) {
+        // OK: directly clone myself
+        newReader = reopenSegment(si, doClone, openReadOnly);
+      } else {
+        throw new UnsupportedOperationException("cannot reopen a standalone SegmentReader");
+      }
+    } else if (infos.size() == 1) {
       SegmentInfo si = infos.info(0);
       if (segment.equals(si.name) && si.getUseCompoundFile() == SegmentReader.this.si.getUseCompoundFile()) {
         newReader = reopenSegment(si, doClone, openReadOnly);

Modified: lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderClone.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderClone.java?rev=744653&r1=744652&r2=744653&view=diff
==============================================================================
--- lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderClone.java (original)
+++ lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderClone.java Sun Feb 15 10:56:36 2009
@@ -403,4 +403,24 @@
   private void assertDelDocsRefCountEquals(int refCount, SegmentReader reader) {
     assertEquals(refCount, reader.deletedDocsRef.refCount());
   }
+  
+  public void testCloneSubreaders() throws Exception {
+    final Directory dir1 = new MockRAMDirectory();
+ 
+    TestIndexReaderReopen.createIndex(dir1, true);
+    IndexReader reader = IndexReader.open(dir1);
+    reader.deleteDocument(1); // acquire write lock
+    IndexReader[] subs = reader.getSequentialSubReaders();
+    assert subs.length > 1;
+    
+    IndexReader[] clones = new IndexReader[subs.length];
+    for (int x=0; x < subs.length; x++) {
+      clones[x] = (IndexReader) subs[x].clone();
+    }
+    reader.close();
+    for (int x=0; x < subs.length; x++) {
+      clones[x].close();
+    }
+    dir1.close();
+  }
 }