You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2011/05/20 15:48:36 UTC

svn commit: r1125390 - in /lucene/dev/branches/branch_3x: ./ lucene/ lucene/backwards/ lucene/backwards/src/test/org/apache/lucene/index/ lucene/src/java/org/apache/lucene/index/ lucene/src/test/org/apache/lucene/index/ solr/

Author: rmuir
Date: Fri May 20 13:48:36 2011
New Revision: 1125390

URL: http://svn.apache.org/viewvc?rev=1125390&view=rev
Log:
LUCENE-3117: pull SegmentReader.Norms out of SegmentReader.java

Added:
    lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/SegmentNorms.java
      - copied, changed from r1125376, lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/SegmentNorms.java
Removed:
    lucene/dev/branches/branch_3x/lucene/backwards/src/test/org/apache/lucene/index/TestIndexReaderClone.java
    lucene/dev/branches/branch_3x/lucene/backwards/src/test/org/apache/lucene/index/TestIndexReaderCloneNorms.java
Modified:
    lucene/dev/branches/branch_3x/   (props changed)
    lucene/dev/branches/branch_3x/lucene/   (props changed)
    lucene/dev/branches/branch_3x/lucene/backwards/   (props changed)
    lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/SegmentReader.java
    lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java
    lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexReaderCloneNorms.java
    lucene/dev/branches/branch_3x/solr/   (props changed)

Copied: lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/SegmentNorms.java (from r1125376, lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/SegmentNorms.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/SegmentNorms.java?p2=lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/SegmentNorms.java&p1=lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/SegmentNorms.java&r1=1125376&r2=1125390&rev=1125390&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/SegmentNorms.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/SegmentNorms.java Fri May 20 13:48:36 2011
@@ -104,6 +104,29 @@ final class SegmentNorms implements Clon
     }
   }
 
+  // Load bytes but do not cache them if they were not
+  // already cached
+  public synchronized void bytes(byte[] bytesOut, int offset, int len) throws IOException {
+    assert refCount > 0 && (origNorm == null || origNorm.refCount > 0);
+    if (bytes != null) {
+      // Already cached -- copy from cache:
+      assert len <= owner.maxDoc();
+      System.arraycopy(bytes, 0, bytesOut, offset, len);
+    } else {
+      // Not cached
+      if (origNorm != null) {
+        // Ask origNorm to load
+        origNorm.bytes(bytesOut, offset, len);
+      } else {
+        // We are orig -- read ourselves from disk:
+        synchronized(in) {
+          in.seek(normSeek);
+          in.readBytes(bytesOut, offset, len, false);
+        }
+      }
+    }
+  }
+
   // Load & cache full bytes array.  Returns bytes.
   public synchronized byte[] bytes() throws IOException {
     assert refCount > 0 && (origNorm == null || origNorm.refCount > 0);

Modified: lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/SegmentReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/SegmentReader.java?rev=1125390&r1=1125389&r2=1125390&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/SegmentReader.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/SegmentReader.java Fri May 20 13:48:36 2011
@@ -35,7 +35,6 @@ import org.apache.lucene.search.Similari
 import org.apache.lucene.store.BufferedIndexInput;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IndexInput;
-import org.apache.lucene.store.IndexOutput;
 import org.apache.lucene.util.BitVector;
 import org.apache.lucene.util.CloseableThreadLocal;
 import org.apache.lucene.util.StringHelper;
@@ -68,8 +67,8 @@ public class SegmentReader extends Index
   private int rollbackPendingDeleteCount;
 
   // optionally used for the .nrm file shared by multiple norms
-  private IndexInput singleNormStream;
-  private AtomicInteger singleNormRef;
+  IndexInput singleNormStream;
+  AtomicInteger singleNormRef;
 
   CoreReaders core;
 
@@ -316,242 +315,7 @@ public class SegmentReader extends Index
     }
   }
   
-  /**
-   * Byte[] referencing is used because a new norm object needs 
-   * to be created for each clone, and the byte array is all 
-   * that is needed for sharing between cloned readers.  The 
-   * current norm referencing is for sharing between readers 
-   * whereas the byte[] referencing is for copy on write which 
-   * is independent of reader references (i.e. incRef, decRef).
-   */
-
-  final class Norm implements Cloneable {
-    private int refCount = 1;
-
-    // If this instance is a clone, the originalNorm
-    // references the Norm that has a real open IndexInput:
-    private Norm origNorm;
-
-    private IndexInput in;
-    private long normSeek;
-
-    // null until bytes is set
-    private AtomicInteger bytesRef;
-    private byte[] bytes;
-    private boolean dirty;
-    private int number;
-    private boolean rollbackDirty;
-    
-    public Norm(IndexInput in, int number, long normSeek) {
-      this.in = in;
-      this.number = number;
-      this.normSeek = normSeek;
-    }
-
-    public synchronized void incRef() {
-      assert refCount > 0 && (origNorm == null || origNorm.refCount > 0);
-      refCount++;
-    }
-
-    private void closeInput() throws IOException {
-      if (in != null) {
-        if (in != singleNormStream) {
-          // It's private to us -- just close it
-          in.close();
-        } else {
-          // We are sharing this with others -- decRef and
-          // maybe close the shared norm stream
-          if (singleNormRef.decrementAndGet() == 0) {
-            singleNormStream.close();
-            singleNormStream = null;
-          }
-        }
-
-        in = null;
-      }
-    }
-
-    public synchronized void decRef() throws IOException {
-      assert refCount > 0 && (origNorm == null || origNorm.refCount > 0);
-
-      if (--refCount == 0) {
-        if (origNorm != null) {
-          origNorm.decRef();
-          origNorm = null;
-        } else {
-          closeInput();
-        }
-
-        if (bytes != null) {
-          assert bytesRef != null;
-          bytesRef.decrementAndGet();
-          bytes = null;
-          bytesRef = null;
-        } else {
-          assert bytesRef == null;
-        }
-      }
-    }
-
-    // Load bytes but do not cache them if they were not
-    // already cached
-    public synchronized void bytes(byte[] bytesOut, int offset, int len) throws IOException {
-      assert refCount > 0 && (origNorm == null || origNorm.refCount > 0);
-      if (bytes != null) {
-        // Already cached -- copy from cache:
-        assert len <= maxDoc();
-        System.arraycopy(bytes, 0, bytesOut, offset, len);
-      } else {
-        // Not cached
-        if (origNorm != null) {
-          // Ask origNorm to load
-          origNorm.bytes(bytesOut, offset, len);
-        } else {
-          // We are orig -- read ourselves from disk:
-          synchronized(in) {
-            in.seek(normSeek);
-            in.readBytes(bytesOut, offset, len, false);
-          }
-        }
-      }
-    }
-
-    // Load & cache full bytes array.  Returns bytes.
-    public synchronized byte[] bytes() throws IOException {
-      assert refCount > 0 && (origNorm == null || origNorm.refCount > 0);
-      if (bytes == null) {                     // value not yet read
-        assert bytesRef == null;
-        if (origNorm != null) {
-          // Ask origNorm to load so that for a series of
-          // reopened readers we share a single read-only
-          // byte[]
-          bytes = origNorm.bytes();
-          bytesRef = origNorm.bytesRef;
-          bytesRef.incrementAndGet();
-
-          // Once we've loaded the bytes we no longer need
-          // origNorm:
-          origNorm.decRef();
-          origNorm = null;
-
-        } else {
-          // We are the origNorm, so load the bytes for real
-          // ourself:
-          final int count = maxDoc();
-          bytes = new byte[count];
-
-          // Since we are orig, in must not be null
-          assert in != null;
-
-          // Read from disk.
-          synchronized(in) {
-            in.seek(normSeek);
-            in.readBytes(bytes, 0, count, false);
-          }
-
-          bytesRef = new AtomicInteger(1);
-          closeInput();
-        }
-      }
-
-      return bytes;
-    }
-
-    // Only for testing
-    AtomicInteger bytesRef() {
-      return bytesRef;
-    }
-
-    // Called if we intend to change a norm value.  We make a
-    // private copy of bytes if it's shared with others:
-    public synchronized byte[] copyOnWrite() throws IOException {
-      assert refCount > 0 && (origNorm == null || origNorm.refCount > 0);
-      bytes();
-      assert bytes != null;
-      assert bytesRef != null;
-      if (bytesRef.get() > 1) {
-        // I cannot be the origNorm for another norm
-        // instance if I'm being changed.  Ie, only the
-        // "head Norm" can be changed:
-        assert refCount == 1;
-        final AtomicInteger oldRef = bytesRef;
-        bytes = cloneNormBytes(bytes);
-        bytesRef = new AtomicInteger(1);
-        oldRef.decrementAndGet();
-      }
-      dirty = true;
-      return bytes;
-    }
-    
-    // Returns a copy of this Norm instance that shares
-    // IndexInput & bytes with the original one
-    @Override
-    public synchronized Object clone() {
-      assert refCount > 0 && (origNorm == null || origNorm.refCount > 0);
-        
-      Norm clone;
-      try {
-        clone = (Norm) super.clone();
-      } catch (CloneNotSupportedException cnse) {
-        // Cannot happen
-        throw new RuntimeException("unexpected CloneNotSupportedException", cnse);
-      }
-      clone.refCount = 1;
-
-      if (bytes != null) {
-        assert bytesRef != null;
-        assert origNorm == null;
-
-        // Clone holds a reference to my bytes:
-        clone.bytesRef.incrementAndGet();
-      } else {
-        assert bytesRef == null;
-        if (origNorm == null) {
-          // I become the origNorm for the clone:
-          clone.origNorm = this;
-        }
-        clone.origNorm.incRef();
-      }
-
-      // Only the origNorm will actually readBytes from in:
-      clone.in = null;
-
-      return clone;
-    }
-
-    // Flush all pending changes to the next generation
-    // separate norms file.
-    public void reWrite(SegmentInfo si) throws IOException {
-      assert refCount > 0 && (origNorm == null || origNorm.refCount > 0): "refCount=" + refCount + " origNorm=" + origNorm;
-
-      // NOTE: norms are re-written in regular directory, not cfs
-      si.advanceNormGen(this.number);
-      final String normFileName = si.getNormFileName(this.number);
-      IndexOutput out = directory().createOutput(normFileName);
-      boolean success = false;
-      try {
-        try {
-          out.writeBytes(SegmentMerger.NORMS_HEADER, 0, SegmentMerger.NORMS_HEADER.length);
-          out.writeBytes(bytes, maxDoc());
-        } finally {
-          out.close();
-        }
-        success = true;
-      } finally {
-        if (!success) {
-          try {
-            directory().deleteFile(normFileName);
-          } catch (Throwable t) {
-            // suppress this so we keep throwing the
-            // original exception
-          }
-        }
-      }
-      this.dirty = false;
-    }
-  }
-
-  Map<String,Norm> norms = new HashMap<String,Norm>();
+  Map<String,SegmentNorms> norms = new HashMap<String,SegmentNorms>();
   
   /**
    * @throws CorruptIndexException if the index is corrupt
@@ -743,7 +507,7 @@ public class SegmentReader extends Index
         }
       }
 
-      clone.norms = new HashMap<String,Norm>();
+      clone.norms = new HashMap<String,SegmentNorms>();
 
       // Clone norms
       for (int i = 0; i < fieldNormsChanged.length; i++) {
@@ -751,9 +515,9 @@ public class SegmentReader extends Index
         // Clone unchanged norms to the cloned reader
         if (doClone || !fieldNormsChanged[i]) {
           final String curField = core.fieldInfos.fieldInfo(i).name;
-          Norm norm = this.norms.get(curField);
+          SegmentNorms norm = this.norms.get(curField);
           if (norm != null)
-            clone.norms.put(curField, (Norm) norm.clone());
+            clone.norms.put(curField, (SegmentNorms) norm.clone());
         }
       }
 
@@ -823,7 +587,7 @@ public class SegmentReader extends Index
 
     if (normsDirty) {               // re-write norms
       si.setNumFields(core.fieldInfos.size());
-      for (final Norm norm : norms.values()) {
+      for (final SegmentNorms norm : norms.values()) {
         if (norm.dirty) {
           norm.reWrite(si);
         }
@@ -849,7 +613,7 @@ public class SegmentReader extends Index
       deletedDocs = null;
     }
 
-    for (final Norm norm : norms.values()) {
+    for (final SegmentNorms norm : norms.values()) {
       norm.decRef();
     }
     if (core != null) {
@@ -1051,7 +815,7 @@ public class SegmentReader extends Index
   @Override
   public byte[] norms(String field) throws IOException {
     ensureOpen();
-    final Norm norm = norms.get(field);
+    final SegmentNorms norm = norms.get(field);
     if (norm == null) {
       // not indexed, or norms not stored
       return null;  
@@ -1062,7 +826,7 @@ public class SegmentReader extends Index
   @Override
   protected void doSetNorm(int doc, String field, byte value)
           throws IOException {
-    Norm norm = norms.get(field);
+    SegmentNorms norm = norms.get(field);
     if (norm == null)                             // not an indexed field
       return;
 
@@ -1076,7 +840,7 @@ public class SegmentReader extends Index
     throws IOException {
 
     ensureOpen();
-    Norm norm = norms.get(field);
+    SegmentNorms norm = norms.get(field);
     if (norm == null) {
       Arrays.fill(bytes, offset, bytes.length, Similarity.getDefault().encodeNormValue(1.0f));
       return;
@@ -1142,7 +906,7 @@ public class SegmentReader extends Index
           }
         }
 
-        norms.put(fi.name, new Norm(normInput, fi.number, normSeek));
+        norms.put(fi.name, new SegmentNorms(normInput, fi.number, normSeek, this));
         nextNormSeek += maxDoc; // increment also if some norms are separate
       }
     }
@@ -1166,7 +930,7 @@ public class SegmentReader extends Index
     if (singleNormStream != null) {
       return false;
     }
-    for (final Norm norm : norms.values()) {
+    for (final SegmentNorms norm : norms.values()) {
       if (norm.refCount > 0) {
         return false;
       }
@@ -1308,7 +1072,7 @@ public class SegmentReader extends Index
     rollbackDeletedDocsDirty = deletedDocsDirty;
     rollbackNormsDirty = normsDirty;
     rollbackPendingDeleteCount = pendingDeleteCount;
-    for (Norm norm : norms.values()) {
+    for (SegmentNorms norm : norms.values()) {
       norm.rollbackDirty = norm.dirty;
     }
   }
@@ -1319,7 +1083,7 @@ public class SegmentReader extends Index
     deletedDocsDirty = rollbackDeletedDocsDirty;
     normsDirty = rollbackNormsDirty;
     pendingDeleteCount = rollbackPendingDeleteCount;
-    for (Norm norm : norms.values()) {
+    for (SegmentNorms norm : norms.values()) {
       norm.dirty = norm.rollbackDirty;
     }
   }

Modified: lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java?rev=1125390&r1=1125389&r2=1125390&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java Fri May 20 13:48:36 2011
@@ -17,7 +17,7 @@ package org.apache.lucene.index;
  * limitations under the License.
  */
 
-import org.apache.lucene.index.SegmentReader.Norm;
+import org.apache.lucene.index.SegmentNorms;
 import org.apache.lucene.search.Similarity;
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.document.Document;
@@ -330,7 +330,7 @@ public class TestIndexReaderClone extend
     origSegmentReader.close();
     assertDelDocsRefCountEquals(1, origSegmentReader);
     // check the norm refs
-    Norm norm = clonedSegmentReader.norms.get("field1");
+    SegmentNorms norm = clonedSegmentReader.norms.get("field1");
     assertEquals(1, norm.bytesRef().get());
     clonedSegmentReader.close();
     dir1.close();

Modified: lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexReaderCloneNorms.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexReaderCloneNorms.java?rev=1125390&r1=1125389&r2=1125390&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexReaderCloneNorms.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexReaderCloneNorms.java Fri May 20 13:48:36 2011
@@ -29,7 +29,7 @@ import org.apache.lucene.document.Field;
 import org.apache.lucene.document.Field.Index;
 import org.apache.lucene.document.Field.Store;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
-import org.apache.lucene.index.SegmentReader.Norm;
+import org.apache.lucene.index.SegmentNorms;
 import org.apache.lucene.search.DefaultSimilarity;
 import org.apache.lucene.search.Similarity;
 import org.apache.lucene.store.Directory;
@@ -161,7 +161,7 @@ public class TestIndexReaderCloneNorms e
     TestIndexReaderReopen.createIndex(random, dir1, false);
     SegmentReader reader1 = SegmentReader.getOnlySegmentReader(dir1);
     reader1.norms("field1");
-    Norm r1norm = reader1.norms.get("field1");
+    SegmentNorms r1norm = reader1.norms.get("field1");
     AtomicInteger r1BytesRef = r1norm.bytesRef();
     SegmentReader reader2 = (SegmentReader)reader1.clone();
     assertEquals(2, r1norm.bytesRef().get());
@@ -180,14 +180,14 @@ public class TestIndexReaderCloneNorms e
     IndexReader reader2C = (IndexReader) reader1.clone();
     SegmentReader segmentReader2C = SegmentReader.getOnlySegmentReader(reader2C);
     segmentReader2C.norms("field1"); // load the norms for the field
-    Norm reader2CNorm = segmentReader2C.norms.get("field1");
+    SegmentNorms reader2CNorm = segmentReader2C.norms.get("field1");
     assertTrue("reader2CNorm.bytesRef()=" + reader2CNorm.bytesRef(), reader2CNorm.bytesRef().get() == 2);
     
     
     
     IndexReader reader3C = (IndexReader) reader2C.clone();
     SegmentReader segmentReader3C = SegmentReader.getOnlySegmentReader(reader3C);
-    Norm reader3CCNorm = segmentReader3C.norms.get("field1");
+    SegmentNorms reader3CCNorm = segmentReader3C.norms.get("field1");
     assertEquals(3, reader3CCNorm.bytesRef().get());
     
     // edit a norm and the refcount should be 1
@@ -207,13 +207,13 @@ public class TestIndexReaderCloneNorms e
     // norm values should be different 
     assertTrue(Similarity.getDefault().decodeNormValue(segmentReader3C.norms("field1")[5]) 
     		!= Similarity.getDefault().decodeNormValue(segmentReader4C.norms("field1")[5]));
-    Norm reader4CCNorm = segmentReader4C.norms.get("field1");
+    SegmentNorms reader4CCNorm = segmentReader4C.norms.get("field1");
     assertEquals(3, reader3CCNorm.bytesRef().get());
     assertEquals(1, reader4CCNorm.bytesRef().get());
         
     IndexReader reader5C = (IndexReader) reader4C.clone();
     SegmentReader segmentReader5C = SegmentReader.getOnlySegmentReader(reader5C);
-    Norm reader5CCNorm = segmentReader5C.norms.get("field1");
+    SegmentNorms reader5CCNorm = segmentReader5C.norms.get("field1");
     reader5C.setNorm(5, "field1", 0.7f);
     assertEquals(1, reader5CCNorm.bytesRef().get());