You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by si...@apache.org on 2012/11/06 16:01:03 UTC

svn commit: r1406169 - in /lucene/dev/branches/branch_4x: ./ lucene/ lucene/codecs/ lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/ lucene/core/ lucene/core/src/java/org/apache/lucene/codecs/lucene3x/ lucene/core/src/java/org/apache/lucene/...

Author: simonw
Date: Tue Nov  6 15:01:01 2012
New Revision: 1406169

URL: http://svn.apache.org/viewvc?rev=1406169&view=rev
Log:
LUCENE-4538: Cache DocValues DirectSource

Modified:
    lucene/dev/branches/branch_4x/   (props changed)
    lucene/dev/branches/branch_4x/lucene/   (props changed)
    lucene/dev/branches/branch_4x/lucene/CHANGES.txt   (contents, props changed)
    lucene/dev/branches/branch_4x/lucene/codecs/   (props changed)
    lucene/dev/branches/branch_4x/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPerDocProducer.java
    lucene/dev/branches/branch_4x/lucene/core/   (props changed)
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene3x/Lucene3xNormsProducer.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Bytes.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedDerefBytesImpl.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedSortedBytesImpl.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedStraightBytesImpl.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Floats.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Ints.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/PackedIntValues.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarDerefBytesImpl.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarSortedBytesImpl.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarStraightBytesImpl.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/index/DocValues.java
    lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java
    lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/codecs/lucene40/values/TestDocValues.java
    lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java
    lucene/dev/branches/branch_4x/lucene/memory/   (props changed)
    lucene/dev/branches/branch_4x/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndexNormDocValues.java

Modified: lucene/dev/branches/branch_4x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/CHANGES.txt?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_4x/lucene/CHANGES.txt Tue Nov  6 15:01:01 2012
@@ -145,6 +145,10 @@ Optimizations
   posting lists. All index data is represented as consecutive byte/int arrays to 
   reduce GC cost and memory overhead. (Simon Willnauer) 
 
+* LUCENE-4538: DocValues now caches direct sources in a ThreadLocal exposed via SourceCache. 
+  Users of this API can now simply obtain an instance via DocValues#getDirectSource per thread.
+  (Simon Willnauer)
+
 Build
 
 * Upgrade randomized testing to version 2.0.4: avoid hangs on shutdown

Modified: lucene/dev/branches/branch_4x/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPerDocProducer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPerDocProducer.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPerDocProducer.java (original)
+++ lucene/dev/branches/branch_4x/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPerDocProducer.java Tue Nov  6 15:01:01 2012
@@ -136,7 +136,7 @@ public class SimpleTextPerDocProducer ex
     }
 
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       boolean success = false;
       IndexInput in = input.clone();
       try {
@@ -198,9 +198,14 @@ public class SimpleTextPerDocProducer ex
       assert scratch.equals(END);
       return reader.getSource();
     }
-
+    
     @Override
     public Source getDirectSource() throws IOException {
+      return this.getSource(); // don't cache twice
+    }
+
+    @Override
+    protected Source loadDirectSource() throws IOException {
       return this.getSource();
     }
 

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene3x/Lucene3xNormsProducer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene3x/Lucene3xNormsProducer.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene3x/Lucene3xNormsProducer.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene3x/Lucene3xNormsProducer.java Tue Nov  6 15:01:01 2012
@@ -202,12 +202,12 @@ class Lucene3xNormsProducer extends PerD
     }
 
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       return new NormSource(bytes());
     }
 
     @Override
-    public Source getDirectSource() throws IOException {
+    protected Source loadDirectSource() throws IOException {
       return getSource();
     }
 

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Bytes.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Bytes.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Bytes.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Bytes.java Tue Nov  6 15:01:01 2012
@@ -307,7 +307,7 @@ public final class Bytes {
 
   /**
    * Opens all necessary files, but does not read any data in until you call
-   * {@link #load}.
+   * {@link #loadSource}.
    */
   static abstract class BytesReaderBase extends DocValues {
     protected final IndexInput idxIn;

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedDerefBytesImpl.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedDerefBytesImpl.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedDerefBytesImpl.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedDerefBytesImpl.java Tue Nov  6 15:01:01 2012
@@ -79,12 +79,12 @@ class FixedDerefBytesImpl {
     }
 
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       return new FixedDerefSource(cloneData(), cloneIndex(), size, numValuesStored);
     }
 
     @Override
-    public Source getDirectSource()
+    protected Source loadDirectSource()
         throws IOException {
       return new DirectFixedDerefSource(cloneData(), cloneIndex(), size, getType());
     }

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedSortedBytesImpl.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedSortedBytesImpl.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedSortedBytesImpl.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedSortedBytesImpl.java Tue Nov  6 15:01:01 2012
@@ -135,13 +135,13 @@ class FixedSortedBytesImpl {
     }
 
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       return new FixedSortedSource(cloneData(), cloneIndex(), size, valueCount,
           comparator);
     }
 
     @Override
-    public Source getDirectSource() throws IOException {
+    protected Source loadDirectSource() throws IOException {
       return new DirectFixedSortedSource(cloneData(), cloneIndex(), size,
           valueCount, comparator, type);
     }

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedStraightBytesImpl.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedStraightBytesImpl.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedStraightBytesImpl.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedStraightBytesImpl.java Tue Nov  6 15:01:01 2012
@@ -280,7 +280,7 @@ class FixedStraightBytesImpl {
     }
 
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       return size == 1 ? new SingleByteSource(cloneData(), maxDoc) : 
         new FixedStraightSource(cloneData(), size, maxDoc, type);
     }
@@ -291,7 +291,7 @@ class FixedStraightBytesImpl {
     }
    
     @Override
-    public Source getDirectSource() throws IOException {
+    protected Source loadDirectSource() throws IOException {
       return new DirectFixedStraightSource(cloneData(), size, getType());
     }
     

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Floats.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Floats.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Floats.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Floats.java Tue Nov  6 15:01:01 2012
@@ -124,7 +124,7 @@ public class Floats {
     }
     
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       final IndexInput indexInput = cloneData();
       try {
         return arrayTemplate.newFromInput(indexInput, maxDoc);

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Ints.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Ints.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Ints.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Ints.java Tue Nov  6 15:01:01 2012
@@ -148,7 +148,7 @@ public final class Ints {
     }
 
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       final IndexInput indexInput = cloneData();
       try {
         return arrayTemplate.newFromInput(indexInput, maxDoc);

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/PackedIntValues.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/PackedIntValues.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/PackedIntValues.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/PackedIntValues.java Tue Nov  6 15:01:01 2012
@@ -148,7 +148,7 @@ class PackedIntValues {
 
   /**
    * Opens all necessary files, but does not read any data in until you call
-   * {@link #load}.
+   * {@link #loadSource}.
    */
   static class PackedIntsReader extends DocValues {
     private final IndexInput datIn;
@@ -181,7 +181,7 @@ class PackedIntValues {
      * already previously loaded but then discarded the Source.
      */
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       boolean success = false;
       final Source source;
       IndexInput input = null;
@@ -216,7 +216,7 @@ class PackedIntValues {
 
 
     @Override
-    public Source getDirectSource() throws IOException {
+    protected Source loadDirectSource() throws IOException {
       return values != null ? new FixedStraightBytesImpl.DirectFixedStraightSource(datIn.clone(), 8, Type.FIXED_INTS_64) : new PackedIntsSource(datIn.clone(), true);
     }
   }

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarDerefBytesImpl.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarDerefBytesImpl.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarDerefBytesImpl.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarDerefBytesImpl.java Tue Nov  6 15:01:01 2012
@@ -99,12 +99,12 @@ class VarDerefBytesImpl {
     }
 
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       return new VarDerefSource(cloneData(), cloneIndex(), totalBytes);
     }
    
     @Override
-    public Source getDirectSource()
+    protected Source loadDirectSource()
         throws IOException {
       return new DirectVarDerefSource(cloneData(), cloneIndex(), getType());
     }

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarSortedBytesImpl.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarSortedBytesImpl.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarSortedBytesImpl.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarSortedBytesImpl.java Tue Nov  6 15:01:01 2012
@@ -161,13 +161,13 @@ final class VarSortedBytesImpl {
     }
 
     @Override
-    public org.apache.lucene.index.DocValues.Source load()
+    public org.apache.lucene.index.DocValues.Source loadSource()
         throws IOException {
       return new VarSortedSource(cloneData(), cloneIndex(), comparator);
     }
 
     @Override
-    public Source getDirectSource() throws IOException {
+    protected Source loadDirectSource() throws IOException {
       return new DirectSortedSource(cloneData(), cloneIndex(), comparator, getType());
     }
     

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarStraightBytesImpl.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarStraightBytesImpl.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarStraightBytesImpl.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarStraightBytesImpl.java Tue Nov  6 15:01:01 2012
@@ -247,12 +247,12 @@ class VarStraightBytesImpl {
     }
 
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       return new VarStraightSource(cloneData(), cloneIndex());
     }
 
     @Override
-    public Source getDirectSource()
+    protected Source loadDirectSource()
         throws IOException {
       return new DirectVarStraightSource(cloneData(), cloneIndex(), getType());
     }

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/index/DocValues.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/index/DocValues.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/index/DocValues.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/index/DocValues.java Tue Nov  6 15:01:01 2012
@@ -33,8 +33,8 @@ import org.apache.lucene.document.Packed
 import org.apache.lucene.document.ShortDocValuesField; // javadocs
 import org.apache.lucene.document.SortedBytesDocValuesField; // javadocs
 import org.apache.lucene.document.StraightBytesDocValuesField; // javadocs
-import org.apache.lucene.store.DataOutput;
 import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.CloseableThreadLocal;
 import org.apache.lucene.util.packed.PackedInts;
 
 /**
@@ -95,7 +95,6 @@ public abstract class DocValues implemen
 
   private volatile SourceCache cache = new SourceCache.DirectSourceCache();
   private final Object cacheLock = new Object();
-  
   /** Sole constructor. (For invocation by subclass 
    *  constructors, typically implicit.) */
   protected DocValues() {
@@ -112,12 +111,12 @@ public abstract class DocValues implemen
    * @see #getSource()
    * @see #setCache(SourceCache)
    */
-  public abstract Source load() throws IOException;
+  protected abstract Source loadSource() throws IOException;
 
   /**
    * Returns a {@link Source} instance through the current {@link SourceCache}.
    * Iff no {@link Source} has been loaded into the cache so far the source will
-   * be loaded through {@link #load()} and passed to the {@link SourceCache}.
+   * be loaded through {@link #loadSource()} and passed to the {@link SourceCache}.
    * The caller of this method should not close the obtained {@link Source}
    * instance unless it is not needed for the rest of its life time.
    * <p>
@@ -129,12 +128,30 @@ public abstract class DocValues implemen
   public Source getSource() throws IOException {
     return cache.load(this);
   }
+  
+  /**
+   * Returns a disk resident {@link Source} instance through the current
+   * {@link SourceCache}. Direct Sources are cached per thread in the
+   * {@link SourceCache}. The obtained instance should not be shared with other
+   * threads.
+   */
+  public Source getDirectSource() throws IOException {
+    return this.cache.loadDirect(this);
+  }
+  
 
   /**
-   * Returns a disk resident {@link Source} instance. Direct Sources are not
-   * cached in the {@link SourceCache} and should not be shared between threads.
+   * Loads a new {@link Source direct source} instance from this {@link DocValues} field
+   * instance. Source instances returned from this method are not cached. It is
+   * the callers responsibility to maintain the instance and release its
+   * resources once the source is not needed anymore.
+   * <p>
+   * For managed {@link Source direct source} instances see {@link #getDirectSource()}.
+   * 
+   * @see #getDirectSource()
+   * @see #setCache(SourceCache)
    */
-  public abstract Source getDirectSource() throws IOException;
+  protected abstract Source loadDirectSource() throws IOException;
 
   /**
    * Returns the {@link Type} of this {@link DocValues} instance
@@ -163,10 +180,10 @@ public abstract class DocValues implemen
 
   /**
    * Sets the {@link SourceCache} used by this {@link DocValues} instance. This
-   * method should be called before {@link #load()} is called. All {@link Source} instances in the currently used cache will be closed
+   * method should be called before {@link #loadSource()} is called. All {@link Source} instances in the currently used cache will be closed
    * before the new cache is installed.
    * <p>
-   * Note: All instances previously obtained from {@link #load()} will be lost.
+   * Note: All instances previously obtained from {@link #loadSource()} will be lost.
    * 
    * @throws IllegalArgumentException
    *           if the given cache is <code>null</code>
@@ -181,6 +198,14 @@ public abstract class DocValues implemen
       toClose.close(this);
     }
   }
+  /**
+   * Returns the currently used cache instance;
+   * @see #setCache(SourceCache)
+   */
+  // for tests
+  SourceCache getCache() {
+    return cache;
+  }
 
   /**
    * Source of per document values like long, double or {@link BytesRef}
@@ -687,9 +712,9 @@ public abstract class DocValues implemen
   /**
    * Abstract base class for {@link DocValues} {@link Source} cache.
    * <p>
-   * {@link Source} instances loaded via {@link DocValues#load()} are entirely memory resident
+   * {@link Source} instances loaded via {@link DocValues#loadSource()} are entirely memory resident
    * and need to be maintained by the caller. Each call to
-   * {@link DocValues#load()} will cause an entire reload of
+   * {@link DocValues#loadSource()} will cause an entire reload of
    * the underlying data. Source instances obtained from
    * {@link DocValues#getSource()} and {@link DocValues#getSource()}
    * respectively are maintained by a {@link SourceCache} that is closed (
@@ -721,6 +746,15 @@ public abstract class DocValues implemen
      * This method will not return <code>null</code>
      */
     public abstract Source load(DocValues values) throws IOException;
+    
+    /**
+     * Atomically loads a {@link Source direct source} into the per-thread cache from the given
+     * {@link DocValues} and returns it iff no other {@link Source direct source} has already
+     * been cached. Otherwise the cached source is returned.
+     * <p>
+     * This method will not return <code>null</code>
+     */
+    public abstract Source loadDirect(DocValues values) throws IOException;
 
     /**
      * Atomically invalidates the cached {@link Source} 
@@ -744,20 +778,34 @@ public abstract class DocValues implemen
      */
     public static final class DirectSourceCache extends SourceCache {
       private Source ref;
-
+      private final CloseableThreadLocal<Source> directSourceCache = new CloseableThreadLocal<Source>();
+      
       /** Sole constructor. */
       public DirectSourceCache() {
       }
 
       public synchronized Source load(DocValues values) throws IOException {
         if (ref == null) {
-          ref = values.load();
+          ref = values.loadSource();
         }
         return ref;
       }
 
       public synchronized void invalidate(DocValues values) {
         ref = null;
+        directSourceCache.close();
+      }
+
+      @Override
+      public synchronized Source loadDirect(DocValues values) throws IOException {
+        final Source source = directSourceCache.get();
+        if (source == null) {
+          final Source loadDirectSource = values.loadDirectSource();
+          directSourceCache.set(loadDirectSource);
+          return loadDirectSource;
+        } else {
+          return source;
+        }
       }
     }
   }

Modified: lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java Tue Nov  6 15:01:01 2012
@@ -185,7 +185,7 @@ class MultiDocValues extends DocValues {
   }
 
   @Override
-  public Source load() throws IOException {
+  protected Source loadSource() throws IOException {
     return new MultiSource(slices, starts, false, type);
   }
 
@@ -199,7 +199,7 @@ class MultiDocValues extends DocValues {
     }
 
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       return emptySource;
     }
 
@@ -209,7 +209,7 @@ class MultiDocValues extends DocValues {
     }
 
     @Override
-    public Source getDirectSource() throws IOException {
+    protected Source loadDirectSource() throws IOException {
       return emptySource;
     }
   }
@@ -226,7 +226,7 @@ class MultiDocValues extends DocValues {
     }
 
     @Override
-    public Source load() throws IOException {
+    protected Source loadSource() throws IOException {
       return emptyFixedSource;
     }
 
@@ -241,7 +241,7 @@ class MultiDocValues extends DocValues {
     }
 
     @Override
-    public Source getDirectSource() throws IOException {
+    protected Source loadDirectSource() throws IOException {
       return emptyFixedSource;
     }
   }
@@ -594,7 +594,7 @@ class MultiDocValues extends DocValues {
   }
 
   @Override
-  public Source getDirectSource() throws IOException {
+  protected Source loadDirectSource() throws IOException {
     return new MultiSource(slices, starts, true, type);
   }
   

Modified: lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/codecs/lucene40/values/TestDocValues.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/codecs/lucene40/values/TestDocValues.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/codecs/lucene40/values/TestDocValues.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/codecs/lucene40/values/TestDocValues.java Tue Nov  6 15:01:01 2012
@@ -423,8 +423,6 @@ public class TestDocValues extends Lucen
   private Source getSource(DocValues values) throws IOException {
     // getSource uses cache internally
     switch(random().nextInt(5)) {
-    case 3:
-      return values.load();
     case 2:
       return values.getDirectSource();
     case 1:

Modified: lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java (original)
+++ lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java Tue Nov  6 15:01:01 2012
@@ -48,7 +48,9 @@ import org.apache.lucene.document.String
 import org.apache.lucene.document.TextField;
 import org.apache.lucene.index.DocValues.SortedSource;
 import org.apache.lucene.index.DocValues.Source;
+import org.apache.lucene.index.DocValues.SourceCache;
 import org.apache.lucene.index.DocValues.Type;
+import org.apache.lucene.index.DocValues.SourceCache.DirectSourceCache;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.DocIdSetIterator;
@@ -579,15 +581,26 @@ public class TestDocValuesIndexing exten
   }
 
   private DocValues getDocValues(IndexReader reader, String field) throws IOException {
-    return MultiDocValues.getDocValues(reader, field);
-  }
+    final DocValues docValues = MultiDocValues.getDocValues(reader, field);
+    if (docValues == null) {
+      return docValues;
+    }
+    if (rarely()) {
+      docValues.setCache(new NotCachingSourceCache());
+    } else {
+      if (!(docValues.getCache() instanceof DirectSourceCache))  {
+        docValues.setCache(new DirectSourceCache());
+      }
+    }
+    return docValues;
+    }
 
   @SuppressWarnings("fallthrough")
   private Source getSource(DocValues values) throws IOException {
     // getSource uses cache internally
     switch(random().nextInt(5)) {
     case 3:
-      return values.load();
+      return values.loadSource();
     case 2:
       return values.getDirectSource();
     case 1:
@@ -767,7 +780,7 @@ public class TestDocValuesIndexing exten
     w.forceMerge(1);
     DirectoryReader r = w.getReader();
     w.close();
-    assertEquals(17, getOnlySegmentReader(r).docValues("field").load().getInt(0));
+    assertEquals(17, getOnlySegmentReader(r).docValues("field").loadSource().getInt(0));
     r.close();
     d.close();
   }
@@ -794,7 +807,7 @@ public class TestDocValuesIndexing exten
     w.forceMerge(1);
     DirectoryReader r = w.getReader();
     w.close();
-    assertEquals(17, getOnlySegmentReader(r).docValues("field").load().getInt(0));
+    assertEquals(17, getOnlySegmentReader(r).docValues("field").loadSource().getInt(0));
     r.close();
     d.close();
   }
@@ -1075,4 +1088,24 @@ public class TestDocValuesIndexing exten
     writer.close();
     dir.close();
   }
+  
+  /**
+  *
+  */
+ public static class NotCachingSourceCache extends SourceCache {
+   
+   @Override
+   public Source load(DocValues values) throws IOException {
+     return values.loadSource();
+   }
+   
+   @Override
+   public Source loadDirect(DocValues values) throws IOException {
+     return values.loadDirectSource();
+   }
+   
+   @Override
+   public void invalidate(DocValues values) {}
+ }
+ 
 }

Modified: lucene/dev/branches/branch_4x/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndexNormDocValues.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndexNormDocValues.java?rev=1406169&r1=1406168&r2=1406169&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndexNormDocValues.java (original)
+++ lucene/dev/branches/branch_4x/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndexNormDocValues.java Tue Nov  6 15:01:01 2012
@@ -33,12 +33,12 @@ class MemoryIndexNormDocValues extends D
     this.source = source;
   }
   @Override
-  public Source load() throws IOException {
+  protected Source loadSource() throws IOException {
     return source;
   }
 
   @Override
-  public Source getDirectSource() throws IOException {
+  protected Source loadDirectSource() throws IOException {
     return source;
   }