You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2012/08/15 14:11:15 UTC

svn commit: r1373363 [1/2] - in /lucene/dev/branches/pforcodec_3892/lucene/core: ./ src/java/org/apache/lucene/codecs/ src/java/org/apache/lucene/codecs/block/ src/java/org/apache/lucene/codecs/lucene40/ src/java/org/apache/lucene/index/ src/java/org/a...

Author: mikemccand
Date: Wed Aug 15 12:11:13 2012
New Revision: 1373363

URL: http://svn.apache.org/viewvc?rev=1373363&view=rev
Log:
LUCENE-3892: revert wrong trunk merge commit

Added:
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/PayloadProcessorProvider.java
      - copied unchanged from r1373357, lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/PayloadProcessorProvider.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/MergedIterator.java
      - copied unchanged from r1373357, lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/MergedIterator.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPayloadProcessorProvider.java
      - copied unchanged from r1373357, lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPayloadProcessorProvider.java
Removed:
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MergedIterator.java
Modified:
    lucene/dev/branches/pforcodec_3892/lucene/core/   (props changed)
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/MappingMultiDocsAndPositionsEnum.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/TermsConsumer.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsWriter.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40TermVectorsWriter.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/AtomicReader.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/AtomicReaderContext.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/BufferedDeletesStream.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CoalescedDeletes.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CompositeReader.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CompositeReaderContext.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexReader.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexReaderContext.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MergeState.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MultiFields.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/SegmentMerger.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/TermCollectingRewrite.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/FieldCacheSanityChecker.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/codecs/lucene40/TestReuseDocsEnum.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestCustomNorms.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDeletionPolicy.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReader.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReaderReopen.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDoc.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocTermOrds.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocsAndPositions.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterCommit.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterForceMerge.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterUnicode.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPayloads.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPostingsOffsets.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPrefixCodedTerms.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestSegmentMerger.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestStressIndexing2.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestTermVectorsReader.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestThreadedForceMerge.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestTypePromotion.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/search/TestShardSearching.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/search/spans/TestPayloadSpans.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/store/TestLockFactory.java
    lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/util/junitcompat/TestFailIfDirectoryNotClosed.java

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/MappingMultiDocsAndPositionsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/MappingMultiDocsAndPositionsEnum.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/MappingMultiDocsAndPositionsEnum.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/MappingMultiDocsAndPositionsEnum.java Wed Aug 15 12:11:13 2012
@@ -123,7 +123,18 @@ public final class MappingMultiDocsAndPo
   
   @Override
   public BytesRef getPayload() throws IOException {
-    return current.getPayload();
+    BytesRef payload = current.getPayload();
+    if (mergeState.currentPayloadProcessor[upto] != null && payload != null) {
+      // to not violate the D&P api, we must give the processor a private copy
+      // TODO: reuse a BytesRef if there is a PPP
+      payload = BytesRef.deepCopyOf(payload);
+      mergeState.currentPayloadProcessor[upto].processPayload(payload);
+      if (payload.length == 0) {
+        // don't let PayloadProcessors corrumpt the index
+        return null;
+      }
+    }
+    return payload;
   }
 }
 

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java Wed Aug 15 12:11:13 2012
@@ -27,6 +27,8 @@ import org.apache.lucene.index.FieldInfo
 import org.apache.lucene.index.FieldInfos;
 import org.apache.lucene.index.Fields;
 import org.apache.lucene.index.MergeState;
+import org.apache.lucene.index.PayloadProcessorProvider.PayloadProcessor;
+import org.apache.lucene.index.PayloadProcessorProvider.ReaderPayloadProcessor;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.search.DocIdSetIterator;
@@ -168,7 +170,12 @@ public abstract class TermVectorsWriter 
       final AtomicReader reader = mergeState.readers.get(i);
       final int maxDoc = reader.maxDoc();
       final Bits liveDocs = reader.getLiveDocs();
-
+      // set PayloadProcessor
+      if (mergeState.payloadProcessorProvider != null) {
+        mergeState.currentReaderPayloadProcessor = mergeState.readerPayloadProcessor[i];
+      } else {
+        mergeState.currentReaderPayloadProcessor = null;
+      }
       for (int docID = 0; docID < maxDoc; docID++) {
         if (liveDocs != null && !liveDocs.get(docID)) {
           // skip deleted docs
@@ -208,6 +215,9 @@ public abstract class TermVectorsWriter 
     TermsEnum termsEnum = null;
     DocsAndPositionsEnum docsAndPositionsEnum = null;
     
+    final ReaderPayloadProcessor readerPayloadProcessor = mergeState.currentReaderPayloadProcessor;
+    PayloadProcessor payloadProcessor = null;
+
     for(String fieldName : vectors) {
       final FieldInfo fieldInfo = mergeState.fieldInfos.fieldInfo(fieldName);
 
@@ -240,6 +250,10 @@ public abstract class TermVectorsWriter 
         final int freq = (int) termsEnum.totalTermFreq();
         
         startTerm(termsEnum.term(), freq);
+        
+        if (hasPayloads && readerPayloadProcessor != null) {
+          payloadProcessor = readerPayloadProcessor.getProcessor(fieldName, termsEnum.term());
+        }
 
         if (hasPositions || hasOffsets) {
           docsAndPositionsEnum = termsEnum.docsAndPositions(null, docsAndPositionsEnum);
@@ -254,7 +268,17 @@ public abstract class TermVectorsWriter 
             final int startOffset = docsAndPositionsEnum.startOffset();
             final int endOffset = docsAndPositionsEnum.endOffset();
             
-            final BytesRef payload = docsAndPositionsEnum.getPayload();
+            BytesRef payload = docsAndPositionsEnum.getPayload();
+                
+            if (payloadProcessor != null && payload != null) {
+              // to not violate the D&P api, we must give the processor a private copy
+              payload = BytesRef.deepCopyOf(payload);
+              payloadProcessor.processPayload(payload);
+              if (payload.length == 0) {
+                // don't let PayloadProcessors corrumpt the index
+                payload = null;
+              }
+            }
 
             assert !hasPositions || pos >= 0;
             addPosition(pos, startOffset, endOffset, payload);

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/TermsConsumer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/TermsConsumer.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/TermsConsumer.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/TermsConsumer.java Wed Aug 15 12:11:13 2012
@@ -154,7 +154,14 @@ public abstract class TermsConsumer {
         postingsEnumIn = (MultiDocsAndPositionsEnum) termsEnum.docsAndPositions(null, postingsEnumIn, DocsAndPositionsEnum.FLAG_PAYLOADS);
         assert postingsEnumIn != null;
         postingsEnum.reset(postingsEnumIn);
-
+        // set PayloadProcessor
+        if (mergeState.payloadProcessorProvider != null) {
+          for (int i = 0; i < mergeState.readers.size(); i++) {
+            if (mergeState.readerPayloadProcessor[i] != null) {
+              mergeState.currentPayloadProcessor[i] = mergeState.readerPayloadProcessor[i].getProcessor(mergeState.fieldInfo.name, term);
+            }
+          }
+        }
         final PostingsConsumer postingsConsumer = startTerm(term);
         final TermStats stats = postingsConsumer.merge(mergeState, postingsEnum, visitedDocs);
         if (stats.docFreq > 0) {
@@ -181,7 +188,14 @@ public abstract class TermsConsumer {
         postingsEnumIn = (MultiDocsAndPositionsEnum) termsEnum.docsAndPositions(null, postingsEnumIn);
         assert postingsEnumIn != null;
         postingsEnum.reset(postingsEnumIn);
-
+        // set PayloadProcessor
+        if (mergeState.payloadProcessorProvider != null) {
+          for (int i = 0; i < mergeState.readers.size(); i++) {
+            if (mergeState.readerPayloadProcessor[i] != null) {
+              mergeState.currentPayloadProcessor[i] = mergeState.readerPayloadProcessor[i].getProcessor(mergeState.fieldInfo.name, term);
+            }
+          }
+        }
         final PostingsConsumer postingsConsumer = startTerm(term);
         final TermStats stats = postingsConsumer.merge(mergeState, postingsEnum, visitedDocs);
         if (stats.docFreq > 0) {

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsWriter.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsWriter.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsWriter.java Wed Aug 15 12:11:13 2012
@@ -318,7 +318,7 @@ final class BlockPostingsWriter extends 
     // current block
 
     if (lastBlockDocID != -1 && docBufferUpto == 1) {
-      // TODO: can we move this to startDoc?  ie we can write skip
+      // nocomit move to startDoc?  ie we can write skip
       // data as soon as the next doc starts...
       if (DEBUG) {
         System.out.println("  bufferSkip at writeBlock: lastDocID=" + lastBlockDocID + " docCount=" + (docCount-1));

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40TermVectorsWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40TermVectorsWriter.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40TermVectorsWriter.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40TermVectorsWriter.java Wed Aug 15 12:11:13 2012
@@ -315,7 +315,12 @@ public final class Lucene40TermVectorsWr
     int numDocs = 0;
     for (int i = 0; i < mergeState.readers.size(); i++) {
       final AtomicReader reader = mergeState.readers.get(i);
-
+      // set PayloadProcessor
+      if (mergeState.payloadProcessorProvider != null) {
+        mergeState.currentReaderPayloadProcessor = mergeState.readerPayloadProcessor[i];
+      } else {
+        mergeState.currentReaderPayloadProcessor = null;
+      }
       final SegmentReader matchingSegmentReader = mergeState.matchingSegmentReaders[idx++];
       Lucene40TermVectorsReader matchingVectorsReader = null;
       if (matchingSegmentReader != null) {
@@ -348,8 +353,8 @@ public final class Lucene40TermVectorsWr
     final int maxDoc = reader.maxDoc();
     final Bits liveDocs = reader.getLiveDocs();
     int totalNumDocs = 0;
-    if (matchingVectorsReader != null) {
-      // We can bulk-copy because the fieldInfos are "congruent"
+    if (matchingVectorsReader != null && mergeState.currentReaderPayloadProcessor == null) {
+      // We can bulk-copy because the fieldInfos are "congruent" and there is no payload processor
       for (int docNum = 0; docNum < maxDoc;) {
         if (!liveDocs.get(docNum)) {
           // skip deleted docs
@@ -399,8 +404,8 @@ public final class Lucene40TermVectorsWr
                                       int rawDocLengths2[])
           throws IOException {
     final int maxDoc = reader.maxDoc();
-    if (matchingVectorsReader != null) {
-      // We can bulk-copy because the fieldInfos are "congruent"
+    if (matchingVectorsReader != null && mergeState.currentReaderPayloadProcessor == null) {
+      // We can bulk-copy because the fieldInfos are "congruent" and there is no payload processor
       int docCount = 0;
       while (docCount < maxDoc) {
         int len = Math.min(MAX_RAW_MERGE_DOCS, maxDoc - docCount);

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/AtomicReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/AtomicReader.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/AtomicReader.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/AtomicReader.java Wed Aug 15 12:11:13 2012
@@ -54,7 +54,7 @@ public abstract class AtomicReader exten
   }
 
   @Override
-  public final AtomicReaderContext getContext() {
+  public final AtomicReaderContext getTopReaderContext() {
     ensureOpen();
     return readerContext;
   }

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/AtomicReaderContext.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/AtomicReaderContext.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/AtomicReaderContext.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/AtomicReaderContext.java Wed Aug 15 12:11:13 2012
@@ -21,7 +21,8 @@ import java.util.Collections;
 import java.util.List;
 
 /**
- * {@link IndexReaderContext} for {@link AtomicReader} instances.
+ * {@link IndexReaderContext} for {@link AtomicReader} instances
+ * @lucene.experimental
  */
 public final class AtomicReaderContext extends IndexReaderContext {
   /** The readers ord in the top-level's leaves array */

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/BufferedDeletesStream.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/BufferedDeletesStream.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/BufferedDeletesStream.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/BufferedDeletesStream.java Wed Aug 15 12:11:13 2012
@@ -439,7 +439,7 @@ class BufferedDeletesStream {
   // Delete by query
   private static long applyQueryDeletes(Iterable<QueryAndLimit> queriesIter, ReadersAndLiveDocs rld, final SegmentReader reader) throws IOException {
     long delCount = 0;
-    final AtomicReaderContext readerContext = reader.getContext();
+    final AtomicReaderContext readerContext = reader.getTopReaderContext();
     boolean any = false;
     for (QueryAndLimit ent : queriesIter) {
       Query query = ent.query;

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CoalescedDeletes.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CoalescedDeletes.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CoalescedDeletes.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CoalescedDeletes.java Wed Aug 15 12:11:13 2012
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.lucene.search.Query;
+import org.apache.lucene.util.MergedIterator;
 import org.apache.lucene.index.BufferedDeletesStream.QueryAndLimit;
 
 class CoalescedDeletes {

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CompositeReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CompositeReader.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CompositeReader.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CompositeReader.java Wed Aug 15 12:11:13 2012
@@ -78,18 +78,16 @@ public abstract class CompositeReader ex
   }
   
   /** Expert: returns the sequential sub readers that this
-   *  reader is logically composed of. This method may not
-   *  return {@code null}.
-   *  
-   *  <p><b>NOTE:</b> In contrast to previous Lucene versions this method
-   *  is no longer public, code that wants to get all {@link AtomicReader}s
-   *  this composite is composed of should use {@link IndexReader#leaves()}.
-   * @see IndexReader#leaves()
+   *  reader is logically composed of. It contrast to previous
+   *  Lucene versions may not 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).
    */
-  protected abstract List<? extends IndexReader> getSequentialSubReaders();
+  public abstract List<? extends IndexReader> getSequentialSubReaders();
 
   @Override
-  public final CompositeReaderContext getContext() {
+  public final CompositeReaderContext getTopReaderContext() {
     ensureOpen();
     // lazy init without thread safety for perf reasons: Building the readerContext twice does not hurt!
     if (readerContext == null) {

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CompositeReaderContext.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CompositeReaderContext.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CompositeReaderContext.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/CompositeReaderContext.java Wed Aug 15 12:11:13 2012
@@ -24,6 +24,7 @@ import java.util.List;
 
 /**
  * {@link IndexReaderContext} for {@link CompositeReader} instance.
+ * @lucene.experimental
  */
 public final class CompositeReaderContext extends IndexReaderContext {
   private final List<IndexReaderContext> children;

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexReader.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexReader.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexReader.java Wed Aug 15 12:11:13 2012
@@ -21,7 +21,6 @@ import java.io.Closeable;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.WeakHashMap;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -378,11 +377,9 @@ public abstract class IndexReader implem
   protected abstract void doClose() throws IOException;
 
   /**
-   * Expert: Returns the root {@link IndexReaderContext} for this
-   * {@link IndexReader}'s sub-reader tree. 
-   * <p>
-   * Iff this reader is composed of sub
-   * readers, i.e. this reader being a composite reader, this method returns a
+   * Expert: Returns a the root {@link IndexReaderContext} for this
+   * {@link IndexReader}'s sub-reader tree. Iff this reader is composed of sub
+   * readers ,ie. this reader being a composite reader, this method returns a
    * {@link CompositeReaderContext} holding the reader's direct children as well as a
    * view of the reader tree's atomic leaf contexts. All sub-
    * {@link IndexReaderContext} instances referenced from this readers top-level
@@ -391,21 +388,14 @@ public abstract class IndexReader implem
    * atomic leaf reader at a time. If this reader is not composed of child
    * readers, this method returns an {@link AtomicReaderContext}.
    * <p>
-   * Note: Any of the sub-{@link CompositeReaderContext} instances referenced
-   * from this top-level context do not support {@link CompositeReaderContext#leaves()}.
-   * Only the top-level context maintains the convenience leaf-view
+   * Note: Any of the sub-{@link CompositeReaderContext} instances reference from this
+   * top-level context holds a <code>null</code> {@link CompositeReaderContext#leaves()}
+   * reference. Only the top-level context maintains the convenience leaf-view
    * for performance reasons.
+   * 
+   * @lucene.experimental
    */
-  public abstract IndexReaderContext getContext();
-  
-  /**
-   * Returns the reader's leaves, or itself if this reader is atomic.
-   * This is a convenience method calling {@code this.getContext().leaves()}.
-   * @see IndexReaderContext#leaves()
-   */
-  public final List<AtomicReaderContext> leaves() {
-    return getContext().leaves();
-  }
+  public abstract IndexReaderContext getTopReaderContext();
 
   /** Expert: Returns a key for this IndexReader, so FieldCache/CachingWrapperFilter can find
    * it again.

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexReaderContext.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexReaderContext.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexReaderContext.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexReaderContext.java Wed Aug 15 12:11:13 2012
@@ -22,6 +22,7 @@ import java.util.List;
 /**
  * A struct like class that represents a hierarchical relationship between
  * {@link IndexReader} instances. 
+ * @lucene.experimental
  */
 public abstract class IndexReaderContext {
   /** The reader context for this reader's immediate parent, or null if none */

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java Wed Aug 15 12:11:13 2012
@@ -260,6 +260,9 @@ public class IndexWriter implements Clos
   // to allow users to query an IndexWriter settings.
   private final LiveIndexWriterConfig config;
 
+  // The PayloadProcessorProvider to use when segments are merged
+  private PayloadProcessorProvider payloadProcessorProvider;
+
   DirectoryReader getReader() throws IOException {
     return getReader(true);
   }
@@ -760,15 +763,8 @@ public class IndexWriter implements Clos
   }
 
   /**
-   * Commits all changes to an index, waits for pending merges
-   * to complete, and closes all associated files.  
-   * <p>
-   * This is a "slow graceful shutdown" which may take a long time
-   * especially if a big merge is pending: If you only want to close
-   * resources use {@link #rollback()}. If you only want to commit
-   * pending changes and close resources see {@link #close(boolean)}.
-   * <p>
-   * Note that this may be a costly
+   * Commits all changes to an index and closes all
+   * associated files.  Note that this may be a costly
    * operation, so, try to re-use a single writer instead of
    * closing and opening a new one.  See {@link #commit()} for
    * caveats about write caching done by some IO devices.
@@ -1267,7 +1263,7 @@ public class IndexWriter implements Clos
       reader = (AtomicReader) readerIn;
     } else {
       // Composite reader: lookup sub-reader and re-base docID:
-      List<AtomicReaderContext> leaves = readerIn.leaves();
+      List<AtomicReaderContext> leaves = readerIn.getTopReaderContext().leaves();
       int subIndex = ReaderUtil.subIndex(docID, leaves);
       reader = leaves.get(subIndex).reader();
       docID -= leaves.get(subIndex).docBase;
@@ -2403,7 +2399,8 @@ public class IndexWriter implements Clos
                                          false, codec, null, null);
 
       SegmentMerger merger = new SegmentMerger(info, infoStream, trackingDir, config.getTermIndexInterval(),
-                                               MergeState.CheckAbort.NONE, globalFieldNumberMap, context);
+                                               MergeState.CheckAbort.NONE, payloadProcessorProvider,
+                                               globalFieldNumberMap, context);
 
       for (IndexReader reader : readers) {    // add new indexes
         merger.add(reader);
@@ -3506,7 +3503,7 @@ public class IndexWriter implements Clos
     final TrackingDirectoryWrapper dirWrapper = new TrackingDirectoryWrapper(directory);
 
     SegmentMerger merger = new SegmentMerger(merge.info.info, infoStream, dirWrapper, config.getTermIndexInterval(), checkAbort,
-                                             globalFieldNumberMap, context);
+                                             payloadProcessorProvider, globalFieldNumberMap, context);
 
     if (infoStream.isEnabled("IW")) {
       infoStream.message("IW", "merging " + segString(merge.segments));
@@ -4061,6 +4058,38 @@ public class IndexWriter implements Clos
   synchronized void deletePendingFiles() throws IOException {
     deleter.deletePendingFiles();
   }
+
+  /**
+   * Sets the {@link PayloadProcessorProvider} to use when merging payloads.
+   * Note that the given <code>pcp</code> will be invoked for every segment that
+   * is merged, not only external ones that are given through
+   * {@link #addIndexes}. If you want only the payloads of the external segments
+   * to be processed, you can return <code>null</code> whenever a
+   * {@link PayloadProcessorProvider.ReaderPayloadProcessor} is requested for the {@link Directory} of the
+   * {@link IndexWriter}.
+   * <p>
+   * The default is <code>null</code> which means payloads are processed
+   * normally (copied) during segment merges. You can also unset it by passing
+   * <code>null</code>.
+   * <p>
+   * <b>NOTE:</b> the set {@link PayloadProcessorProvider} will be in effect
+   * immediately, potentially for already running merges too. If you want to be
+   * sure it is used for further operations only, such as {@link #addIndexes} or
+   * {@link #forceMerge}, you can call {@link #waitForMerges()} before.
+   */
+  public void setPayloadProcessorProvider(PayloadProcessorProvider pcp) {
+    ensureOpen();
+    payloadProcessorProvider = pcp;
+  }
+
+  /**
+   * Returns the {@link PayloadProcessorProvider} that is used during segment
+   * merges to process payloads.
+   */
+  public PayloadProcessorProvider getPayloadProcessorProvider() {
+    ensureOpen();
+    return payloadProcessorProvider;
+  }
   
   /**
    * NOTE: this method creates a compound file for all files returned by

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MergeState.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MergeState.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MergeState.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MergeState.java Wed Aug 15 12:11:13 2012
@@ -19,6 +19,8 @@ package org.apache.lucene.index;
 
 import java.util.List;
 
+import org.apache.lucene.index.PayloadProcessorProvider.PayloadProcessor;
+import org.apache.lucene.index.PayloadProcessorProvider.ReaderPayloadProcessor;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.InfoStream;
@@ -192,6 +194,14 @@ public class MergeState {
   // Updated per field;
   public FieldInfo fieldInfo;
   
+  // Used to process payloads
+  // TODO: this is a FactoryFactory here basically
+  // and we could make a codec(wrapper) to do all of this privately so IW is uninvolved
+  public PayloadProcessorProvider payloadProcessorProvider;
+  public ReaderPayloadProcessor[] readerPayloadProcessor;
+  public ReaderPayloadProcessor currentReaderPayloadProcessor;
+  public PayloadProcessor[] currentPayloadProcessor;
+
   // TODO: get rid of this? it tells you which segments are 'aligned' (e.g. for bulk merging)
   // but is this really so expensive to compute again in different components, versus once in SM?
   public SegmentReader[] matchingSegmentReaders;

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java Wed Aug 15 12:11:13 2012
@@ -36,7 +36,7 @@ import org.apache.lucene.util.packed.Pac
  * 
  * <p><b>NOTE</b>: for multi readers, you'll get better
  * performance by gathering the sub readers using
- * {@link IndexReader#getContext()} to get the
+ * {@link IndexReader#getTopReaderContext()} to get the
  * atomic leaves and then operate per-AtomicReader,
  * instead of using this class.
  *
@@ -128,7 +128,7 @@ public class MultiDocValues extends DocV
       return puller.pull((AtomicReader) reader, field);
     }
     assert reader instanceof CompositeReader;
-    final List<AtomicReaderContext> leaves = reader.leaves();
+    final List<AtomicReaderContext> leaves = reader.getTopReaderContext().leaves();
     switch (leaves.size()) {
       case 0:
         // no fields

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MultiFields.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MultiFields.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MultiFields.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/MultiFields.java Wed Aug 15 12:11:13 2012
@@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentHa
 
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.MergedIterator;
 
 /**
  * Exposes flex API, merged from flex API of sub-segments.
@@ -38,7 +39,7 @@ import org.apache.lucene.util.BytesRef;
  *
  * <p><b>NOTE</b>: for composite readers, you'll get better
  * performance by gathering the sub readers using
- * {@link IndexReader#getContext()} to get the
+ * {@link IndexReader#getTopReaderContext()} to get the
  * atomic leaves and then operate per-AtomicReader,
  * instead of using this class.
  *
@@ -59,7 +60,7 @@ public final class MultiFields extends F
    *  It's better to get the sub-readers and iterate through them
    *  yourself. */
   public static Fields getFields(IndexReader reader) throws IOException {
-    final List<AtomicReaderContext> leaves = reader.leaves();
+    final List<AtomicReaderContext> leaves = reader.getTopReaderContext().leaves();
     switch (leaves.size()) {
       case 0:
         // no fields
@@ -91,7 +92,7 @@ public final class MultiFields extends F
 
   public static Bits getLiveDocs(IndexReader reader) {
     if (reader.hasDeletions()) {
-      final List<AtomicReaderContext> leaves = reader.leaves();
+      final List<AtomicReaderContext> leaves = reader.getTopReaderContext().leaves();
       final int size = leaves.size();
       assert size > 0 : "A reader with deletions must have at least one leave";
       if (size == 1) {
@@ -181,7 +182,7 @@ public final class MultiFields extends F
     this.subSlices = subSlices;
   }
 
-  @SuppressWarnings({"unchecked","rawtypes"})
+  @SuppressWarnings("unchecked")
   @Override
   public Iterator<String> iterator() {
     Iterator<String> subIterators[] = new Iterator[subs.length];
@@ -250,7 +251,7 @@ public final class MultiFields extends F
    */
   public static FieldInfos getMergedFieldInfos(IndexReader reader) {
     final FieldInfos.Builder builder = new FieldInfos.Builder();
-    for(final AtomicReaderContext ctx : reader.leaves()) {
+    for(final AtomicReaderContext ctx : reader.getTopReaderContext().leaves()) {
       builder.add(ctx.reader().getFieldInfos());
     }
     return builder.finish();

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/SegmentMerger.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/SegmentMerger.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/SegmentMerger.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/SegmentMerger.java Wed Aug 15 12:11:13 2012
@@ -56,11 +56,13 @@ final class SegmentMerger {
 
   // note, just like in codec apis Directory 'dir' is NOT the same as segmentInfo.dir!!
   SegmentMerger(SegmentInfo segmentInfo, InfoStream infoStream, Directory dir, int termIndexInterval,
-                MergeState.CheckAbort checkAbort, FieldInfos.FieldNumbers fieldNumbers, IOContext context) {
+                MergeState.CheckAbort checkAbort, PayloadProcessorProvider payloadProcessorProvider,
+                FieldInfos.FieldNumbers fieldNumbers, IOContext context) {
     mergeState.segmentInfo = segmentInfo;
     mergeState.infoStream = infoStream;
     mergeState.readers = new ArrayList<AtomicReader>();
     mergeState.checkAbort = checkAbort;
+    mergeState.payloadProcessorProvider = payloadProcessorProvider;
     directory = dir;
     this.termIndexInterval = termIndexInterval;
     this.codec = segmentInfo.getCodec();
@@ -73,7 +75,7 @@ final class SegmentMerger {
    * @param reader
    */
   final void add(IndexReader reader) {
-    for (final AtomicReaderContext ctx : reader.leaves()) {
+    for (final AtomicReaderContext ctx : reader.getTopReaderContext().leaves()) {
       final AtomicReader r = ctx.reader();
       mergeState.readers.add(r);
     }
@@ -272,6 +274,8 @@ final class SegmentMerger {
     // Remap docIDs
     mergeState.docMaps = new MergeState.DocMap[numReaders];
     mergeState.docBase = new int[numReaders];
+    mergeState.readerPayloadProcessor = new PayloadProcessorProvider.ReaderPayloadProcessor[numReaders];
+    mergeState.currentPayloadProcessor = new PayloadProcessorProvider.PayloadProcessor[numReaders];
 
     int docBase = 0;
 
@@ -285,6 +289,10 @@ final class SegmentMerger {
       mergeState.docMaps[i] = docMap;
       docBase += docMap.numDocs();
 
+      if (mergeState.payloadProcessorProvider != null) {
+        mergeState.readerPayloadProcessor[i] = mergeState.payloadProcessorProvider.getReaderProcessor(reader);
+      }
+
       i++;
     }
 

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java Wed Aug 15 12:11:13 2012
@@ -37,7 +37,7 @@ import org.apache.lucene.index.MultiRead
  * <p><b>NOTE</b>: this class almost always results in a
  * performance hit.  If this is important to your use case,
  * you'll get better performance by gathering the sub readers using
- * {@link IndexReader#getContext()} to get the
+ * {@link IndexReader#getTopReaderContext()} to get the
  * atomic leaves and then operate per-AtomicReader,
  * instead of using this class.
  */

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java Wed Aug 15 12:11:13 2012
@@ -122,7 +122,7 @@ public class IndexSearcher {
    * 
    * @lucene.experimental */
   public IndexSearcher(IndexReader r, ExecutorService executor) {
-    this(r.getContext(), executor);
+    this(r.getTopReaderContext(), executor);
   }
 
   /**
@@ -138,7 +138,7 @@ public class IndexSearcher {
    * href="https://issues.apache.org/jira/browse/LUCENE-2239">LUCENE-2239</a>).
    * 
    * @see IndexReaderContext
-   * @see IndexReader#getContext()
+   * @see IndexReader#getTopReaderContext()
    * @lucene.experimental
    */
   public IndexSearcher(IndexReaderContext context, ExecutorService executor) {
@@ -154,7 +154,7 @@ public class IndexSearcher {
    * Creates a searcher searching the provided top-level {@link IndexReaderContext}.
    *
    * @see IndexReaderContext
-   * @see IndexReader#getContext()
+   * @see IndexReader#getTopReaderContext()
    * @lucene.experimental
    */
   public IndexSearcher(IndexReaderContext context) {
@@ -639,7 +639,7 @@ public class IndexSearcher {
   
   /**
    * Returns this searchers the top-level {@link IndexReaderContext}.
-   * @see IndexReader#getContext()
+   * @see IndexReader#getTopReaderContext()
    */
   /* sugar for #getReader().getTopReaderContext() */
   public IndexReaderContext getTopReaderContext() {

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/QueryWrapperFilter.java Wed Aug 15 12:11:13 2012
@@ -50,7 +50,7 @@ public class QueryWrapperFilter extends 
   @Override
   public DocIdSet getDocIdSet(final AtomicReaderContext context, final Bits acceptDocs) throws IOException {
     // get a private context that is used to rewrite, createWeight and score eventually
-    final AtomicReaderContext privateContext = context.reader().getContext();
+    final AtomicReaderContext privateContext = context.reader().getTopReaderContext();
     final Weight weight = new IndexSearcher(privateContext).createNormalizedWeight(query);
     return new DocIdSet() {
       @Override

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/TermCollectingRewrite.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/TermCollectingRewrite.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/TermCollectingRewrite.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/TermCollectingRewrite.java Wed Aug 15 12:11:13 2012
@@ -46,7 +46,7 @@ abstract class TermCollectingRewrite<Q e
 
   
   final void collectTerms(IndexReader reader, MultiTermQuery query, TermCollector collector) throws IOException {
-    IndexReaderContext topReaderContext = reader.getContext();
+    IndexReaderContext topReaderContext = reader.getTopReaderContext();
     Comparator<BytesRef> lastTermComp = null;
     for (AtomicReaderContext context : topReaderContext.leaves()) {
       final Fields fields = context.reader().fields();

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadSpanUtil.java Wed Aug 15 12:11:13 2012
@@ -60,7 +60,7 @@ public class PayloadSpanUtil {
    * @param context
    *          that contains doc with payloads to extract
    *          
-   * @see IndexReader#getContext()
+   * @see IndexReader#getTopReaderContext()
    */
   public PayloadSpanUtil(IndexReaderContext context) {
     this.context = context;

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/FieldCacheSanityChecker.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/FieldCacheSanityChecker.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/FieldCacheSanityChecker.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/FieldCacheSanityChecker.java Wed Aug 15 12:11:13 2012
@@ -25,10 +25,8 @@ import java.util.Set;
 
 import org.apache.lucene.index.CompositeReader;
 import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.IndexReaderContext;
 import org.apache.lucene.search.FieldCache;
 import org.apache.lucene.search.FieldCache.CacheEntry;
-import org.apache.lucene.store.AlreadyClosedException;
 
 /** 
  * Provides methods for sanity checking that entries in the FieldCache 
@@ -274,28 +272,20 @@ public final class FieldCacheSanityCheck
   /**
    * Checks if the seed is an IndexReader, and if so will walk
    * the hierarchy of subReaders building up a list of the objects 
-   * returned by {@code seed.getCoreCacheKey()}
+   * returned by obj.getFieldCacheKey()
    */
   private List<Object> getAllDescendantReaderKeys(Object seed) {
     List<Object> all = new ArrayList<Object>(17); // will grow as we iter
     all.add(seed);
     for (int i = 0; i < all.size(); i++) {
-      final Object obj = all.get(i);
-      // TODO: We don't check closed readers here (as getTopReaderContext
-      // throws AlreadyClosedException), what should we do? Reflection?
-      if (obj instanceof IndexReader) {
-        try {
-          final List<IndexReaderContext> childs =
-            ((IndexReader) obj).getContext().children();
-          if (childs != null) { // it is composite reader
-            for (final IndexReaderContext ctx : childs) {
-              all.add(ctx.reader().getCoreCacheKey());
-            }
-          }
-        } catch (AlreadyClosedException ace) {
-          // ignore this reader
+      Object obj = all.get(i);
+      if (obj instanceof CompositeReader) {
+        List<? extends IndexReader> subs = ((CompositeReader)obj).getSequentialSubReaders();
+        for (int j = 0; (null != subs) && (j < subs.size()); j++) {
+          all.add(subs.get(j).getCoreCacheKey());
         }
       }
+      
     }
     // need to skip the first, because it was the seed
     return all.subList(1, all.size());

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/codecs/lucene40/TestReuseDocsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/codecs/lucene40/TestReuseDocsEnum.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/codecs/lucene40/TestReuseDocsEnum.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/codecs/lucene40/TestReuseDocsEnum.java Wed Aug 15 12:11:13 2012
@@ -23,9 +23,9 @@ import java.util.Random;
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.codecs.Codec;
 import org.apache.lucene.index.AtomicReader;
-import org.apache.lucene.index.AtomicReaderContext;
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
@@ -50,8 +50,7 @@ public class TestReuseDocsEnum extends L
     writer.commit();
 
     DirectoryReader open = DirectoryReader.open(dir);
-    for (AtomicReaderContext ctx : open.leaves()) {
-      AtomicReader indexReader = ctx.reader();
+    for (AtomicReader indexReader : open.getSequentialSubReaders()) {
       Terms terms = indexReader.terms("body");
       TermsEnum iterator = terms.iterator(null);
       IdentityHashMap<DocsEnum, Boolean> enums = new IdentityHashMap<DocsEnum, Boolean>();
@@ -77,8 +76,8 @@ public class TestReuseDocsEnum extends L
     writer.commit();
 
     DirectoryReader open = DirectoryReader.open(dir);
-    for (AtomicReaderContext ctx : open.leaves()) {
-      Terms terms = ctx.reader().terms("body");
+    for (AtomicReader indexReader : open.getSequentialSubReaders()) {
+      Terms terms = indexReader.terms("body");
       TermsEnum iterator = terms.iterator(null);
       IdentityHashMap<DocsEnum, Boolean> enums = new IdentityHashMap<DocsEnum, Boolean>();
       MatchNoBits bits = new Bits.MatchNoBits(open.maxDoc());
@@ -122,11 +121,11 @@ public class TestReuseDocsEnum extends L
 
     DirectoryReader firstReader = DirectoryReader.open(dir);
     DirectoryReader secondReader = DirectoryReader.open(dir);
-    List<AtomicReaderContext> leaves = firstReader.leaves();
-    List<AtomicReaderContext> leaves2 = secondReader.leaves();
+    List<? extends AtomicReader> sequentialSubReaders = firstReader.getSequentialSubReaders();
+    List<? extends AtomicReader> sequentialSubReaders2 = secondReader.getSequentialSubReaders();
     
-    for (AtomicReaderContext ctx : leaves) {
-      Terms terms = ctx.reader().terms("body");
+    for (IndexReader indexReader : sequentialSubReaders) {
+      Terms terms = ((AtomicReader) indexReader).terms("body");
       TermsEnum iterator = terms.iterator(null);
       IdentityHashMap<DocsEnum, Boolean> enums = new IdentityHashMap<DocsEnum, Boolean>();
       MatchNoBits bits = new Bits.MatchNoBits(firstReader.maxDoc());
@@ -134,7 +133,7 @@ public class TestReuseDocsEnum extends L
       DocsEnum docs = null;
       BytesRef term = null;
       while ((term = iterator.next()) != null) {
-        docs = iterator.docs(null, randomDocsEnum("body", term, leaves2, bits), random().nextBoolean() ? DocsEnum.FLAG_FREQS : 0);
+        docs = iterator.docs(null, randomDocsEnum("body", term, sequentialSubReaders2, bits), random().nextBoolean() ? DocsEnum.FLAG_FREQS : 0);
         enums.put(docs, true);
       }
       assertEquals(terms.size(), enums.size());
@@ -143,7 +142,7 @@ public class TestReuseDocsEnum extends L
       enums.clear();
       docs = null;
       while ((term = iterator.next()) != null) {
-        docs = iterator.docs(bits, randomDocsEnum("body", term, leaves2, bits), random().nextBoolean() ? DocsEnum.FLAG_FREQS : 0);
+        docs = iterator.docs(bits, randomDocsEnum("body", term, sequentialSubReaders2, bits), random().nextBoolean() ? DocsEnum.FLAG_FREQS : 0);
         enums.put(docs, true);
       }
       assertEquals(terms.size(), enums.size());
@@ -151,11 +150,11 @@ public class TestReuseDocsEnum extends L
     IOUtils.close(writer, firstReader, secondReader, dir);
   }
   
-  public DocsEnum randomDocsEnum(String field, BytesRef term, List<AtomicReaderContext> readers, Bits bits) throws IOException {
+  public DocsEnum randomDocsEnum(String field, BytesRef term, List<? extends AtomicReader> readers, Bits bits) throws IOException {
     if (random().nextInt(10) == 0) {
       return null;
     }
-    AtomicReader indexReader = readers.get(random().nextInt(readers.size())).reader();
+    AtomicReader indexReader = (AtomicReader) readers.get(random().nextInt(readers.size()));
     return indexReader.termDocsEnum(bits, field, term, random().nextBoolean() ? DocsEnum.FLAG_FREQS : 0);
   }
 

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestCustomNorms.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestCustomNorms.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestCustomNorms.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestCustomNorms.java Wed Aug 15 12:11:13 2012
@@ -143,7 +143,7 @@ public class TestCustomNorms extends Luc
     IndexReader reader = writer.getReader();
     writer.close();
     assertEquals(numAdded, reader.numDocs());
-    IndexReaderContext topReaderContext = reader.getContext();
+    IndexReaderContext topReaderContext = reader.getTopReaderContext();
     for (final AtomicReaderContext ctx : topReaderContext.leaves()) {
       AtomicReader atomicReader = ctx.reader();
       Source source = random().nextBoolean() ? atomicReader.normValues("foo").getSource() : atomicReader.normValues("foo").getDirectSource();

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDeletionPolicy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDeletionPolicy.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDeletionPolicy.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDeletionPolicy.java Wed Aug 15 12:11:13 2012
@@ -68,7 +68,7 @@ public class TestDeletionPolicy extends 
     public void onCommit(List<? extends IndexCommit> commits) throws IOException {
       IndexCommit lastCommit =  commits.get(commits.size()-1);
       DirectoryReader r = DirectoryReader.open(dir);
-      assertEquals("lastCommit.segmentCount()=" + lastCommit.getSegmentCount() + " vs IndexReader.segmentCount=" + r.leaves().size(), r.leaves().size(), lastCommit.getSegmentCount());
+      assertEquals("lastCommit.segmentCount()=" + lastCommit.getSegmentCount() + " vs IndexReader.segmentCount=" + r.getSequentialSubReaders().size(), r.getSequentialSubReaders().size(), lastCommit.getSegmentCount());
       r.close();
       verifyCommitOrder(commits);
       numOnCommit++;
@@ -318,7 +318,7 @@ public class TestDeletionPolicy extends 
       final boolean needsMerging;
       {
         DirectoryReader r = DirectoryReader.open(dir);
-        needsMerging = r.leaves().size() != 1;
+        needsMerging = r.getSequentialSubReaders().size() != 1;
         r.close();
       }
       if (needsMerging) {
@@ -435,7 +435,7 @@ public class TestDeletionPolicy extends 
 
     DirectoryReader r = DirectoryReader.open(dir);
     // Still merged, still 11 docs
-    assertEquals(1, r.leaves().size());
+    assertEquals(1, r.getSequentialSubReaders().size());
     assertEquals(11, r.numDocs());
     r.close();
 
@@ -451,7 +451,7 @@ public class TestDeletionPolicy extends 
     r = DirectoryReader.open(dir);
     // Not fully merged because we rolled it back, and now only
     // 10 docs
-    assertTrue(r.leaves().size() > 1);
+    assertTrue(r.getSequentialSubReaders().size() > 1);
     assertEquals(10, r.numDocs());
     r.close();
 
@@ -461,7 +461,7 @@ public class TestDeletionPolicy extends 
     writer.close();
 
     r = DirectoryReader.open(dir);
-    assertEquals(1, r.leaves().size());
+    assertEquals(1, r.getSequentialSubReaders().size());
     assertEquals(10, r.numDocs());
     r.close();
 
@@ -473,7 +473,7 @@ public class TestDeletionPolicy extends 
     // Reader still sees fully merged index, because writer
     // opened on the prior commit has not yet committed:
     r = DirectoryReader.open(dir);
-    assertEquals(1, r.leaves().size());
+    assertEquals(1, r.getSequentialSubReaders().size());
     assertEquals(10, r.numDocs());
     r.close();
 
@@ -481,7 +481,7 @@ public class TestDeletionPolicy extends 
 
     // Now reader sees not-fully-merged index:
     r = DirectoryReader.open(dir);
-    assertTrue(r.leaves().size() > 1);
+    assertTrue(r.getSequentialSubReaders().size() > 1);
     assertEquals(10, r.numDocs());
     r.close();
 

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReader.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReader.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReader.java Wed Aug 15 12:11:13 2012
@@ -549,7 +549,7 @@ public void testFilesOpenClose() throws 
     assertEquals("IndexReaders have different values for numDocs.", index1.numDocs(), index2.numDocs());
     assertEquals("IndexReaders have different values for maxDoc.", index1.maxDoc(), index2.maxDoc());
     assertEquals("Only one IndexReader has deletions.", index1.hasDeletions(), index2.hasDeletions());
-    assertEquals("Single segment test differs.", index1.leaves().size() == 1, index2.leaves().size() == 1);
+    assertEquals("Single segment test differs.", index1.getSequentialSubReaders().size() == 1, index2.getSequentialSubReaders().size() == 1);
     
     // check field names
     FieldInfos fieldInfos1 = MultiFields.getMergedFieldInfos(index1);
@@ -785,7 +785,7 @@ public void testFilesOpenClose() throws 
     DirectoryReader r2 = DirectoryReader.openIfChanged(r);
     assertNotNull(r2);
     r.close();
-    AtomicReader sub0 = r2.leaves().get(0).reader();
+    AtomicReader sub0 = r2.getSequentialSubReaders().get(0);
     final int[] ints2 = FieldCache.DEFAULT.getInts(sub0, "number", false);
     r2.close();
     assertTrue(ints == ints2);
@@ -814,8 +814,9 @@ public void testFilesOpenClose() throws 
     assertNotNull(r2);
     r.close();
   
-    for(AtomicReaderContext s : r2.leaves()) {
-      assertEquals(36, s.reader().getUniqueTermCount());
+    List<? extends AtomicReader> subs = r2.getSequentialSubReaders();
+    for(AtomicReader s : subs) {
+      assertEquals(36, s.getUniqueTermCount());
     }
     r2.close();
     writer.close();
@@ -841,7 +842,7 @@ public void testFilesOpenClose() throws 
       // expected
     }
   
-    assertEquals(-1, ((SegmentReader) r.leaves().get(0).reader()).getTermInfosIndexDivisor());
+    assertEquals(-1, ((SegmentReader) r.getSequentialSubReaders().get(0)).getTermInfosIndexDivisor());
     writer = new IndexWriter(
         dir,
         newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())).
@@ -856,11 +857,11 @@ public void testFilesOpenClose() throws 
     assertNotNull(r2);
     assertNull(DirectoryReader.openIfChanged(r2));
     r.close();
-    List<AtomicReaderContext> leaves = r2.leaves();
-    assertEquals(2, leaves.size());
-    for(AtomicReaderContext ctx : leaves) {
+    List<? extends AtomicReader> subReaders = r2.getSequentialSubReaders();
+    assertEquals(2, subReaders.size());
+    for(AtomicReader s : subReaders) {
       try {
-        ctx.reader().docFreq(new Term("field", "f"));
+        s.docFreq(new Term("field", "f"));
         fail("did not hit expected exception");
       } catch (IllegalStateException ise) {
         // expected

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReaderReopen.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReaderReopen.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReaderReopen.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReaderReopen.java Wed Aug 15 12:11:13 2012
@@ -171,8 +171,8 @@ public class TestDirectoryReaderReopen e
     TestDirectoryReader.assertIndexEquals(index1, index2_refreshed);
 
     index2_refreshed.close();
-    assertReaderClosed(index2, true);
-    assertReaderClosed(index2_refreshed, true);
+    assertReaderClosed(index2, true, true);
+    assertReaderClosed(index2_refreshed, true, true);
 
     index2 = test.openReader();
     
@@ -190,8 +190,28 @@ public class TestDirectoryReaderReopen e
     
     index1.close();
     index2.close();
-    assertReaderClosed(index1, true);
-    assertReaderClosed(index2, true);
+    assertReaderClosed(index1, true, true);
+    assertReaderClosed(index2, true, true);
+  }
+  
+  private void performTestsWithExceptionInReopen(TestReopen test) throws Exception {
+    DirectoryReader index1 = test.openReader();
+    DirectoryReader index2 = test.openReader();
+
+    TestDirectoryReader.assertIndexEquals(index1, index2);
+    
+    try {
+      refreshReader(index1, test, 0, true);
+      fail("Expected exception not thrown.");
+    } catch (Exception e) {
+      // expected exception
+    }
+    
+    // index2 should still be usable and unaffected by the failed reopen() call
+    TestDirectoryReader.assertIndexEquals(index1, index2);
+
+    index1.close();
+    index2.close();
   }
   
   public void testThreadSafety() throws Exception {
@@ -335,11 +355,11 @@ public class TestDirectoryReaderReopen e
     reader.close();
     
     for (final DirectoryReader readerToClose : readersToClose) {
-      assertReaderClosed(readerToClose, true);
+      assertReaderClosed(readerToClose, true, true);
     }
 
-    assertReaderClosed(reader, true);
-    assertReaderClosed(firstReader, true);
+    assertReaderClosed(reader, true, true);
+    assertReaderClosed(firstReader, true, true);
 
     dir.close();
   }
@@ -354,7 +374,7 @@ public class TestDirectoryReaderReopen e
     DirectoryReader refreshedReader;
   }
   
-  abstract static class ReaderThreadTask {
+  private abstract static class ReaderThreadTask {
     protected volatile boolean stopped;
     public void stop() {
       this.stopped = true;
@@ -364,8 +384,8 @@ public class TestDirectoryReaderReopen e
   }
   
   private static class ReaderThread extends Thread {
-    ReaderThreadTask task;
-    Throwable error;
+    private ReaderThreadTask task;
+    private Throwable error;
     
     
     ReaderThread(ReaderThreadTask task) {
@@ -449,9 +469,9 @@ public class TestDirectoryReaderReopen e
 
     DirectoryReader r = DirectoryReader.open(dir);
     if (multiSegment) {
-      assertTrue(r.leaves().size() > 1);
+      assertTrue(r.getSequentialSubReaders().size() > 1);
     } else {
-      assertTrue(r.leaves().size() == 1);
+      assertTrue(r.getSequentialSubReaders().size() == 1);
     }
     r.close();
   }
@@ -513,25 +533,46 @@ public class TestDirectoryReaderReopen e
     }
   }  
   
-  static void assertReaderClosed(IndexReader reader, boolean checkSubReaders) {
+  static void assertReaderClosed(IndexReader reader, boolean checkSubReaders, boolean checkNormsClosed) {
     assertEquals(0, reader.getRefCount());
     
+    if (checkNormsClosed && reader instanceof AtomicReader) {
+      // TODO: should we really assert something here? we check for open files and this is obselete...
+      // assertTrue(((SegmentReader) reader).normsClosed());
+    }
+    
     if (checkSubReaders && reader instanceof CompositeReader) {
-      // we cannot use reader context here, as reader is
-      // already closed and calling getTopReaderContext() throws AlreadyClosed!
       List<? extends IndexReader> subReaders = ((CompositeReader) reader).getSequentialSubReaders();
-      for (final IndexReader r : subReaders) {
-        assertReaderClosed(r, checkSubReaders);
+      for (IndexReader r : subReaders) {
+        assertReaderClosed(r, checkSubReaders, checkNormsClosed);
       }
     }
   }
 
-  abstract static class TestReopen {
+  /*
+  private void assertReaderOpen(DirectoryReader reader) {
+    reader.ensureOpen();
+    
+    if (reader instanceof DirectoryReader) {
+      DirectoryReader[] subReaders = reader.getSequentialSubReaders();
+      for (int i = 0; i < subReaders.length; i++) {
+        assertReaderOpen(subReaders[i]);
+      }
+    }
+  }
+  */
+
+  private void assertRefCountEquals(int refCount, DirectoryReader reader) {
+    assertEquals("Reader has wrong refCount value.", refCount, reader.getRefCount());
+  }
+
+
+  private abstract static class TestReopen {
     protected abstract DirectoryReader openReader() throws IOException;
     protected abstract void modifyIndex(int i) throws IOException;
   }
   
-  static class KeepAllCommits implements IndexDeletionPolicy {
+  private static class KeepAllCommits implements IndexDeletionPolicy {
     public void onInit(List<? extends IndexCommit> commits) {
     }
     public void onCommit(List<? extends IndexCommit> commits) {

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDoc.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDoc.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDoc.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDoc.java Wed Aug 15 12:11:13 2012
@@ -204,7 +204,7 @@ public class TestDoc extends LuceneTestC
       final SegmentInfo si = new SegmentInfo(si1.info.dir, Constants.LUCENE_MAIN_VERSION, merged, -1, false, codec, null, null);
 
       SegmentMerger merger = new SegmentMerger(si, InfoStream.getDefault(), trackingDir, IndexWriterConfig.DEFAULT_TERM_INDEX_INTERVAL,
-                                               MergeState.CheckAbort.NONE, new FieldInfos.FieldNumbers(), context);
+                                               MergeState.CheckAbort.NONE, null, new FieldInfos.FieldNumbers(), context);
 
       merger.add(r1);
       merger.add(r2);

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocTermOrds.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocTermOrds.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocTermOrds.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocTermOrds.java Wed Aug 15 12:11:13 2012
@@ -154,11 +154,11 @@ public class TestDocTermOrds extends Luc
       System.out.println("TEST: reader=" + r);
     }
 
-    for(AtomicReaderContext ctx : r.leaves()) {
+    for(IndexReader subR : r.getSequentialSubReaders()) {
       if (VERBOSE) {
-        System.out.println("\nTEST: sub=" + ctx.reader());
+        System.out.println("\nTEST: sub=" + subR);
       }
-      verify(ctx.reader(), idToOrds, termsArray, null);
+      verify((AtomicReader) subR, idToOrds, termsArray, null);
     }
 
     // Also test top-level reader: its enum does not support
@@ -273,11 +273,11 @@ public class TestDocTermOrds extends Luc
         idToOrdsPrefix[id] = newOrdsArray;
       }
 
-      for(AtomicReaderContext ctx : r.leaves()) {
+      for(IndexReader subR : r.getSequentialSubReaders()) {
         if (VERBOSE) {
-          System.out.println("\nTEST: sub=" + ctx.reader());
+          System.out.println("\nTEST: sub=" + subR);
         }
-        verify(ctx.reader(), idToOrdsPrefix, termsArray, prefixRef);
+        verify((AtomicReader) subR, idToOrdsPrefix, termsArray, prefixRef);
       }
 
       // Also test top-level reader: its enum does not support

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java Wed Aug 15 12:11:13 2012
@@ -91,7 +91,7 @@ public class TestDocValuesIndexing exten
     writer.close(true);
 
     DirectoryReader reader = DirectoryReader.open(dir, 1);
-    assertEquals(1, reader.leaves().size());
+    assertEquals(1, reader.getSequentialSubReaders().size());
 
     IndexSearcher searcher = new IndexSearcher(reader);
 

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocsAndPositions.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocsAndPositions.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocsAndPositions.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestDocsAndPositions.java Wed Aug 15 12:11:13 2012
@@ -63,7 +63,7 @@ public class TestDocsAndPositions extend
     int num = atLeast(13);
     for (int i = 0; i < num; i++) {
       BytesRef bytes = new BytesRef("1");
-      IndexReaderContext topReaderContext = reader.getContext();
+      IndexReaderContext topReaderContext = reader.getTopReaderContext();
       for (AtomicReaderContext atomicReaderContext : topReaderContext.leaves()) {
         DocsAndPositionsEnum docsAndPosEnum = getDocsAndPositions(
             atomicReaderContext.reader(), bytes, null);
@@ -138,7 +138,7 @@ public class TestDocsAndPositions extend
     int num = atLeast(13);
     for (int i = 0; i < num; i++) {
       BytesRef bytes = new BytesRef("" + term);
-      IndexReaderContext topReaderContext = reader.getContext();
+      IndexReaderContext topReaderContext = reader.getTopReaderContext();
       for (AtomicReaderContext atomicReaderContext : topReaderContext.leaves()) {
         DocsAndPositionsEnum docsAndPosEnum = getDocsAndPositions(
             atomicReaderContext.reader(), bytes, null);
@@ -214,7 +214,7 @@ public class TestDocsAndPositions extend
     int num = atLeast(13);
     for (int i = 0; i < num; i++) {
       BytesRef bytes = new BytesRef("" + term);
-      IndexReaderContext topReaderContext = reader.getContext();
+      IndexReaderContext topReaderContext = reader.getTopReaderContext();
       for (AtomicReaderContext context : topReaderContext.leaves()) {
         int maxDoc = context.reader().maxDoc();
         DocsEnum docsEnum = _TestUtil.docs(random(), context.reader(), fieldName, bytes, null, null, DocsEnum.FLAG_FREQS);
@@ -292,7 +292,7 @@ public class TestDocsAndPositions extend
     for (int i = 0; i < num; i++) {
       BytesRef bytes = new BytesRef("even");
 
-      IndexReaderContext topReaderContext = reader.getContext();
+      IndexReaderContext topReaderContext = reader.getTopReaderContext();
       for (AtomicReaderContext atomicReaderContext : topReaderContext.leaves()) {
         DocsAndPositionsEnum docsAndPosEnum = getDocsAndPositions(
             atomicReaderContext.reader(), bytes, null);

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java Wed Aug 15 12:11:13 2012
@@ -289,9 +289,8 @@ public class TestFieldsReader extends Lu
     
     assertEquals(numDocs, r.numDocs());
 
-    for(AtomicReaderContext ctx : r.leaves()) {
-      final AtomicReader sub = ctx.reader();
-      final int[] ids = FieldCache.DEFAULT.getInts(sub, "id", false);
+    for(IndexReader sub : r.getSequentialSubReaders()) {
+      final int[] ids = FieldCache.DEFAULT.getInts((AtomicReader) sub, "id", false);
       for(int docID=0;docID<sub.numDocs();docID++) {
         final Document doc = sub.document(docID);
         final Field f = (Field) doc.getField("nf");

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java Wed Aug 15 12:11:13 2012
@@ -1498,9 +1498,9 @@ public class TestIndexWriter extends Luc
 
     assertNoUnreferencedFiles(dir, "no tv files");
     DirectoryReader r0 = DirectoryReader.open(dir);
-    for (AtomicReaderContext ctx : r0.leaves()) {
-      SegmentReader sr = (SegmentReader) ctx.reader();
-      assertFalse(sr.getFieldInfos().hasVectors());
+    for (IndexReader r : r0.getSequentialSubReaders()) {
+      SegmentInfoPerCommit s = ((SegmentReader) r).getSegmentInfo();
+      assertFalse(((SegmentReader) r).getFieldInfos().hasVectors());
     }
     
     r0.close();

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterCommit.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterCommit.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterCommit.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterCommit.java Wed Aug 15 12:11:13 2012
@@ -286,7 +286,7 @@ public class TestIndexWriterCommit exten
 
     // Reader should see index as multi-seg at this
     // point:
-    assertTrue("Reader incorrectly sees one segment", reader.leaves().size() > 1);
+    assertTrue("Reader incorrectly sees one segment", reader.getSequentialSubReaders().size() > 1);
     reader.close();
 
     // Abort the writer:
@@ -297,7 +297,7 @@ public class TestIndexWriterCommit exten
     reader = DirectoryReader.open(dir);
 
     // Reader should still see index as multi-segment
-    assertTrue("Reader incorrectly sees one segment", reader.leaves().size() > 1);
+    assertTrue("Reader incorrectly sees one segment", reader.getSequentialSubReaders().size() > 1);
     reader.close();
 
     if (VERBOSE) {
@@ -316,7 +316,7 @@ public class TestIndexWriterCommit exten
     reader = DirectoryReader.open(dir);
 
     // Reader should see index as one segment
-    assertEquals("Reader incorrectly sees more than one segment", 1, reader.leaves().size());
+    assertEquals("Reader incorrectly sees more than one segment", 1, reader.getSequentialSubReaders().size());
     reader.close();
     dir.close();
   }

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java Wed Aug 15 12:11:13 2012
@@ -1293,7 +1293,7 @@ public class TestIndexWriterExceptions e
         assertTrue(reader.numDocs() > 0);
         SegmentInfos sis = new SegmentInfos();
         sis.read(dir);
-        for(AtomicReaderContext context : reader.leaves()) {
+        for(AtomicReaderContext context : reader.getTopReaderContext().leaves()) {
           assertFalse(context.reader().getFieldInfos().hasVectors());
         }
         reader.close();

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterForceMerge.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterForceMerge.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterForceMerge.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterForceMerge.java Wed Aug 15 12:11:13 2012
@@ -187,7 +187,7 @@ public class TestIndexWriterForceMerge e
       if (0 == pass) {
         writer.close();
         DirectoryReader reader = DirectoryReader.open(dir);
-        assertEquals(1, reader.leaves().size());
+        assertEquals(1, reader.getSequentialSubReaders().size());
         reader.close();
       } else {
         // Get another segment to flush so we can verify it is
@@ -197,7 +197,7 @@ public class TestIndexWriterForceMerge e
         writer.close();
 
         DirectoryReader reader = DirectoryReader.open(dir);
-        assertTrue(reader.leaves().size() > 1);
+        assertTrue(reader.getSequentialSubReaders().size() > 1);
         reader.close();
 
         SegmentInfos infos = new SegmentInfos();

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterUnicode.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterUnicode.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterUnicode.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterUnicode.java Wed Aug 15 12:11:13 2012
@@ -315,7 +315,7 @@ public class TestIndexWriterUnicode exte
     IndexReader r = writer.getReader();
 
     // Test each sub-segment
-    for (AtomicReaderContext ctx : r.leaves()) {
+    for (AtomicReaderContext ctx : r.getTopReaderContext().leaves()) {
       checkTermsOrder(ctx.reader(), allTerms, false);
     }
     checkTermsOrder(r, allTerms, true);

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java Wed Aug 15 12:11:13 2012
@@ -339,13 +339,13 @@ public class TestParallelCompositeReader
     if (compositeComposite) {
       rd1 = new MultiReader(DirectoryReader.open(dir1), DirectoryReader.open(dir1));
       rd2 = new MultiReader(DirectoryReader.open(dir2), DirectoryReader.open(dir2));
-      assertEquals(2, rd1.getContext().children().size());
-      assertEquals(2, rd2.getContext().children().size());
+      assertEquals(2, rd1.getSequentialSubReaders().size());
+      assertEquals(2, rd2.getSequentialSubReaders().size());
     } else {
       rd1 = DirectoryReader.open(dir1);
       rd2 = DirectoryReader.open(dir2);
-      assertEquals(3, rd1.getContext().children().size());
-      assertEquals(3, rd2.getContext().children().size());
+      assertEquals(3, rd1.getSequentialSubReaders().size());
+      assertEquals(3, rd2.getSequentialSubReaders().size());
     }
     ParallelCompositeReader pr = new ParallelCompositeReader(rd1, rd2);
     return newSearcher(pr);

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPayloads.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPayloads.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPayloads.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPayloads.java Wed Aug 15 12:11:13 2012
@@ -604,7 +604,7 @@ public class TestPayloads extends Lucene
     field.setTokenStream(ts);
     writer.addDocument(doc);
     DirectoryReader reader = writer.getReader();
-    AtomicReader sr = SlowCompositeReaderWrapper.wrap(reader);
+    AtomicReader sr = reader.getSequentialSubReaders().get(0);
     DocsAndPositionsEnum de = sr.termPositionsEnum(null, "field", new BytesRef("withPayload"));
     de.nextDoc();
     de.nextPosition();

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPostingsOffsets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPostingsOffsets.java?rev=1373363&r1=1373362&r2=1373363&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPostingsOffsets.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/test/org/apache/lucene/index/TestPostingsOffsets.java Wed Aug 15 12:11:13 2012
@@ -289,9 +289,9 @@ public class TestPostingsOffsets extends
     w.close();
 
     final String[] terms = new String[] {"a", "b", "c", "d"};
-    for(AtomicReaderContext ctx : r.leaves()) {
+    for(IndexReader reader : r.getSequentialSubReaders()) {
       // TODO: improve this
-      AtomicReader sub = ctx.reader();
+      AtomicReader sub = (AtomicReader) reader;
       //System.out.println("\nsub=" + sub);
       final TermsEnum termsEnum = sub.fields().terms("content").iterator(null);
       DocsEnum docs = null;