You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ro...@apache.org on 2014/10/24 10:54:42 UTC

svn commit: r1634034 - in /lucene/dev/branches/lucene_solr_4_10: ./ lucene/ lucene/memory/ lucene/memory/src/java/org/apache/lucene/index/memory/ lucene/memory/src/test/org/apache/lucene/index/memory/

Author: romseygeek
Date: Fri Oct 24 08:54:41 2014
New Revision: 1634034

URL: http://svn.apache.org/r1634034
Log:
LUCENE-5911: Add freeze() method to MemoryIndex to allow thread-safe searching

Added:
    lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java
      - copied, changed from r1628154, lucene/dev/trunk/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java
    lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstRAMDir.java
      - copied, changed from r1628154, lucene/dev/trunk/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstRAMDir.java
Removed:
    lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/MemoryIndexTest.java
Modified:
    lucene/dev/branches/lucene_solr_4_10/   (props changed)
    lucene/dev/branches/lucene_solr_4_10/lucene/   (props changed)
    lucene/dev/branches/lucene_solr_4_10/lucene/CHANGES.txt   (contents, props changed)
    lucene/dev/branches/lucene_solr_4_10/lucene/memory/   (props changed)
    lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java

Modified: lucene/dev/branches/lucene_solr_4_10/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_10/lucene/CHANGES.txt?rev=1634034&r1=1634033&r2=1634034&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_10/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/lucene_solr_4_10/lucene/CHANGES.txt Fri Oct 24 08:54:41 2014
@@ -5,6 +5,11 @@ http://s.apache.org/luceneversions
 
 ======================= Lucene 4.10.2 ======================
 
+New Features
+
+* LUCENE-5911: Add MemoryIndex.freeze() to allow thread-safe searching over a 
+  MemoryIndex. (Alan Woodward, David Smiley, Robert Muir)
+
 Bug fixes
 
 * LUCENE-5977: Fix tokenstream safety checks in IndexWriter to properly

Modified: lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java?rev=1634034&r1=1634033&r2=1634034&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java (original)
+++ lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java Fri Oct 24 08:54:41 2014
@@ -17,15 +17,6 @@ package org.apache.lucene.index.memory;
  * limitations under the License.
  */
 
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
@@ -37,8 +28,8 @@ import org.apache.lucene.index.AtomicRea
 import org.apache.lucene.index.BinaryDocValues;
 import org.apache.lucene.index.DocsAndPositionsEnum;
 import org.apache.lucene.index.DocsEnum;
-import org.apache.lucene.index.FieldInfo.IndexOptions;
 import org.apache.lucene.index.FieldInfo;
+import org.apache.lucene.index.FieldInfo.IndexOptions;
 import org.apache.lucene.index.FieldInfos;
 import org.apache.lucene.index.FieldInvertState;
 import org.apache.lucene.index.Fields;
@@ -56,21 +47,30 @@ import org.apache.lucene.search.IndexSea
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.similarities.Similarity;
-import org.apache.lucene.store.RAMDirectory; // for javadocs
+import org.apache.lucene.store.RAMDirectory;
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.ByteBlockPool;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.BytesRefHash.DirectBytesStartArray;
 import org.apache.lucene.util.BytesRefHash;
+import org.apache.lucene.util.BytesRefHash.DirectBytesStartArray;
 import org.apache.lucene.util.Counter;
+import org.apache.lucene.util.IntBlockPool;
 import org.apache.lucene.util.IntBlockPool.SliceReader;
 import org.apache.lucene.util.IntBlockPool.SliceWriter;
-import org.apache.lucene.util.IntBlockPool;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.lucene.util.RecyclingByteBlockAllocator;
 import org.apache.lucene.util.RecyclingIntBlockAllocator;
 
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
 
 /**
  * High-performance single-document main memory Apache Lucene fulltext search index. 
@@ -154,18 +154,12 @@ import org.apache.lucene.util.RecyclingI
  * </pre>
  * 
  * 
- * <h4>No thread safety guarantees</h4>
- * 
- * An instance can be queried multiple times with the same or different queries,
- * but an instance is not thread-safe. If desired use idioms such as:
- * <pre class="prettyprint">
- * MemoryIndex index = ...
- * synchronized (index) {
- *    // read and/or write index (i.e. add fields and/or query)
- * } 
- * </pre>
- * 
- * 
+ * <h4>Thread safety guarantees</h4>
+ *
+ * MemoryIndex is not normally thread-safe for adds or queries.  However, queries
+ * are thread-safe after {@code freeze()} has been called.
+ *
+ *
  * <h4>Performance Notes</h4>
  * 
  * Internally there's a new data structure geared towards efficient indexing 
@@ -213,6 +207,10 @@ public class MemoryIndex {
   private HashMap<String,FieldInfo> fieldInfos = new HashMap<>();
 
   private Counter bytesUsed;
+
+  private boolean frozen = false;
+
+  private Similarity normSimilarity = IndexSearcher.getDefaultSimilarity();
   
   /**
    * Sorts term entries into ascending order; also works for
@@ -418,6 +416,8 @@ public class MemoryIndex {
    */
   public void addField(String fieldName, TokenStream stream, float boost, int positionIncrementGap, int offsetGap) {
     try {
+      if (frozen)
+        throw new IllegalArgumentException("Cannot call addField() when MemoryIndex is frozen");
       if (fieldName == null)
         throw new IllegalArgumentException("fieldName must not be null");
       if (stream == null)
@@ -503,6 +503,15 @@ public class MemoryIndex {
   }
 
   /**
+   * Set the Similarity to be used for calculating field norms
+   */
+  public void setSimilarity(Similarity similarity) {
+    if (frozen)
+      throw new IllegalArgumentException("Cannot set Similarity when MemoryIndex is frozen");
+    this.normSimilarity = similarity;
+  }
+
+  /**
    * Creates and returns a searcher that can be used to execute arbitrary
    * Lucene queries and to collect the resulting query results as hits.
    * 
@@ -511,9 +520,24 @@ public class MemoryIndex {
   public IndexSearcher createSearcher() {
     MemoryIndexReader reader = new MemoryIndexReader();
     IndexSearcher searcher = new IndexSearcher(reader); // ensures no auto-close !!
-    reader.setSearcher(searcher); // to later get hold of searcher.getSimilarity()
+    searcher.setSimilarity(normSimilarity);
     return searcher;
   }
+
+  /**
+   * Prepares the MemoryIndex for querying in a non-lazy way.
+   *
+   * After calling this you can query the MemoryIndex from multiple threads, but you
+   * cannot subsequently add new data.
+   */
+  public void freeze() {
+    this.frozen = true;
+    sortFields();
+    for (Map.Entry<String,Info> info : sortedFields) {
+      info.getValue().sortTerms();
+    }
+    calculateNormValues();
+  }
   
   /**
    * Convenience method that efficiently returns the relevance score by
@@ -687,10 +711,10 @@ public class MemoryIndex {
     private final long sumTotalTermFreq;
 
     /** the last position encountered in this field for multi field support*/
-    private int lastPosition;
+    private final int lastPosition;
 
     /** the last offset encountered in this field for multi field support*/
-    private int lastOffset;
+    private final int lastOffset;
 
     public Info(BytesRefHash terms, SliceByteStartArray sliceArray, int numTokens, int numOverlapTokens, float boost, int lastPosition, int lastOffset, long sumTotalTermFreq) {
       this.terms = terms;
@@ -735,8 +759,6 @@ public class MemoryIndex {
    */
   private final class MemoryIndexReader extends AtomicReader {
     
-    private IndexSearcher searcher; // needed to find searcher.getSimilarity() 
-    
     private MemoryIndexReader() {
       super(); // avoid as much superclass baggage as possible
     }
@@ -1170,15 +1192,6 @@ public class MemoryIndex {
         return null;
       }
     }
-
-    private Similarity getSimilarity() {
-      if (searcher != null) return searcher.getSimilarity();
-      return IndexSearcher.getDefaultSimilarity();
-    }
-    
-    private void setSearcher(IndexSearcher searcher) {
-      this.searcher = searcher;
-    }
   
     @Override
     public int numDocs() {
@@ -1203,33 +1216,35 @@ public class MemoryIndex {
       if (DEBUG) System.err.println("MemoryIndexReader.doClose");
     }
     
-    /** performance hack: cache norms to avoid repeated expensive calculations */
-    private NumericDocValues cachedNormValues;
-    private String cachedFieldName;
-    private Similarity cachedSimilarity;
-    
     @Override
     public NumericDocValues getNormValues(String field) {
-      FieldInfo fieldInfo = fieldInfos.get(field);
-      if (fieldInfo == null || fieldInfo.omitsNorms())
-        return null;
-      NumericDocValues norms = cachedNormValues;
-      Similarity sim = getSimilarity();
-      if (!field.equals(cachedFieldName) || sim != cachedSimilarity) { // not cached?
-        Info info = getInfo(field);
-        int numTokens = info != null ? info.numTokens : 0;
-        int numOverlapTokens = info != null ? info.numOverlapTokens : 0;
-        float boost = info != null ? info.getBoost() : 1.0f; 
-        FieldInvertState invertState = new FieldInvertState(field, 0, numTokens, numOverlapTokens, 0, boost);
-        long value = sim.computeNorm(invertState);
-        norms = new MemoryIndexNormDocValues(value);
-        // cache it for future reuse
-        cachedNormValues = norms;
-        cachedFieldName = field;
-        cachedSimilarity = sim;
-        if (DEBUG) System.err.println("MemoryIndexReader.norms: " + field + ":" + value + ":" + numTokens);
-      }
-      return norms;
+      if (norms == null)
+        return calculateFieldNormValue(field);
+      return norms.get(field);
+    }
+
+  }
+
+  private Map<String, NumericDocValues> norms = null;
+
+  private NumericDocValues calculateFieldNormValue(String field) {
+    FieldInfo fieldInfo = fieldInfos.get(field);
+    if (fieldInfo == null)
+      return null;
+    Info info = fields.get(field);
+    int numTokens = info != null ? info.numTokens : 0;
+    int numOverlapTokens = info != null ? info.numOverlapTokens : 0;
+    float boost = info != null ? info.getBoost() : 1.0f;
+    FieldInvertState invertState = new FieldInvertState(field, 0, numTokens, numOverlapTokens, 0, boost);
+    long value = normSimilarity.computeNorm(invertState);
+    if (DEBUG) System.err.println("MemoryIndexReader.norms: " + field + ":" + value + ":" + numTokens);
+    return new MemoryIndexNormDocValues(value);
+  }
+
+  private void calculateNormValues() {
+    norms = new HashMap<>();
+    for (String field : fieldInfos.keySet()) {
+      norms.put(field, calculateFieldNormValue(field));
     }
   }
   
@@ -1240,8 +1255,11 @@ public class MemoryIndex {
     this.fieldInfos.clear();
     this.fields.clear();
     this.sortedFields = null;
+    this.norms = null;
+    this.normSimilarity = IndexSearcher.getDefaultSimilarity();
     byteBlockPool.reset(false, false); // no need to 0-fill the buffers
     intBlockPool.reset(true, false); // here must must 0-fill since we use slices
+    this.frozen = false;
   }
   
   private static final class SliceByteStartArray extends DirectBytesStartArray {

Copied: lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java (from r1628154, lucene/dev/trunk/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java?p2=lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java&p1=lucene/dev/trunk/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java&r1=1628154&r2=1634034&rev=1634034&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java (original)
+++ lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java Fri Oct 24 08:54:41 2014
@@ -17,10 +17,17 @@ package org.apache.lucene.index.memory;
  * limitations under the License.
  */
 
+import java.io.IOException;
+
 import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.FieldInvertState;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.similarities.BM25Similarity;
+import org.apache.lucene.search.similarities.DefaultSimilarity;
 import org.apache.lucene.util.LuceneTestCase;
 import org.junit.Before;
 import org.junit.Test;
@@ -63,6 +70,14 @@ public class TestMemoryIndex extends Luc
       assertThat(e.getMessage(), containsString("frozen"));
     }
 
+    try {
+      mi.setSimilarity(new BM25Similarity(1, 1));
+      fail("Expected an IllegalArgumentException when setting the Similarity after calling freeze()");
+    }
+    catch (RuntimeException e) {
+      assertThat(e.getMessage(), containsString("frozen"));
+    }
+
     assertThat(mi.search(new TermQuery(new Term("f1", "some"))), not(is(0.0f)));
 
     mi.reset();
@@ -70,6 +85,32 @@ public class TestMemoryIndex extends Luc
     assertThat(mi.search(new TermQuery(new Term("f1", "some"))), is(0.0f));
     assertThat(mi.search(new TermQuery(new Term("f1", "wibble"))), not(is(0.0f)));
 
+    // check we can set the Similarity again
+    mi.setSimilarity(new DefaultSimilarity());
+
+  }
+
+  @Test
+  public void testSimilarities() throws IOException {
+
+    MemoryIndex mi = new MemoryIndex();
+    mi.addField("f1", "a long text field that contains many many terms", analyzer);
+
+    IndexSearcher searcher = mi.createSearcher();
+    AtomicReader reader = (AtomicReader) searcher.getIndexReader();
+    float n1 = reader.getNormValues("f1").get(0);
+
+    // Norms aren't cached, so we can change the Similarity
+    mi.setSimilarity(new DefaultSimilarity() {
+      @Override
+      public float lengthNorm(FieldInvertState state) {
+        return 74;
+      }
+    });
+    float n2 = reader.getNormValues("f1").get(0);
+
+    assertTrue(n1 != n2);
+
   }
 
 

Copied: lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstRAMDir.java (from r1628154, lucene/dev/trunk/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstRAMDir.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstRAMDir.java?p2=lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstRAMDir.java&p1=lucene/dev/trunk/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstRAMDir.java&r1=1628154&r2=1634034&rev=1634034&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstRAMDir.java (original)
+++ lucene/dev/branches/lucene_solr_4_10/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstRAMDir.java Fri Oct 24 08:54:41 2014
@@ -21,6 +21,7 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.Reader;
 import java.nio.charset.StandardCharsets;
 import java.util.HashSet;
 import java.util.Set;
@@ -36,11 +37,12 @@ import org.apache.lucene.analysis.TokenF
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+import org.apache.lucene.codecs.lucene41.Lucene41PostingsFormat;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.FieldType;
 import org.apache.lucene.document.TextField;
-import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.AtomicReader;
 import org.apache.lucene.index.CompositeReader;
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.DocsAndPositionsEnum;
@@ -67,8 +69,8 @@ import org.apache.lucene.search.spans.Sp
 import org.apache.lucene.search.spans.SpanQuery;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.RAMDirectory;
-import org.apache.lucene.util.ByteBlockPool.Allocator;
 import org.apache.lucene.util.ByteBlockPool;
+import org.apache.lucene.util.ByteBlockPool.Allocator;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LineFileDocs;
@@ -147,7 +149,7 @@ public class TestMemoryIndexAgainstRAMDi
     Directory ramdir = new RAMDirectory();
     Analyzer analyzer = randomAnalyzer();
     IndexWriter writer = new IndexWriter(ramdir,
-                                         new IndexWriterConfig(analyzer).setCodec(TestUtil.alwaysPostingsFormat(TestUtil.getDefaultPostingsFormat())));
+                                         new IndexWriterConfig(TEST_VERSION_CURRENT, analyzer).setCodec(TestUtil.alwaysPostingsFormat(new Lucene41PostingsFormat())));
     Document doc = new Document();
     Field field1 = newTextField("foo", fooField.toString(), Field.Store.NO);
     Field field2 = newTextField("term", termField.toString(), Field.Store.NO);
@@ -158,8 +160,8 @@ public class TestMemoryIndexAgainstRAMDi
     
     memory.addField("foo", fooField.toString(), analyzer);
     memory.addField("term", termField.toString(), analyzer);
-    
-    LeafReader reader = (LeafReader) memory.createSearcher().getIndexReader();
+
+    AtomicReader reader = (AtomicReader) memory.createSearcher().getIndexReader();
     DirectoryReader competitor = DirectoryReader.open(ramdir);
     duellReaders(competitor, reader);
     IOUtils.close(reader, competitor);
@@ -167,9 +169,9 @@ public class TestMemoryIndexAgainstRAMDi
     ramdir.close();    
   }
 
-  private void duellReaders(CompositeReader other, LeafReader memIndexReader)
+  private void duellReaders(CompositeReader other, AtomicReader memIndexReader)
       throws IOException {
-    LeafReader competitor = SlowCompositeReaderWrapper.wrap(other);
+    AtomicReader competitor = SlowCompositeReaderWrapper.wrap(other);
     Fields memFields = memIndexReader.fields();
     for (String field : competitor.fields()) {
       Terms memTerms = memFields.terms(field);
@@ -254,8 +256,8 @@ public class TestMemoryIndexAgainstRAMDi
       case 1: return new MockAnalyzer(random(), MockTokenizer.SIMPLE, true, MockTokenFilter.ENGLISH_STOPSET);
       case 2: return new Analyzer() {
         @Override
-        protected TokenStreamComponents createComponents(String fieldName) {
-          Tokenizer tokenizer = new MockTokenizer();
+        protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
+          Tokenizer tokenizer = new MockTokenizer(reader);
           return new TokenStreamComponents(tokenizer, new CrazyTokenFilter(tokenizer));
         }
       };
@@ -312,7 +314,7 @@ public class TestMemoryIndexAgainstRAMDi
     Analyzer analyzer = new MockAnalyzer(random());
     MemoryIndex memory = new MemoryIndex(random().nextBoolean(),  random().nextInt(50) * 1024 * 1024);
     memory.addField("foo", "bar", analyzer);
-    LeafReader reader = (LeafReader) memory.createSearcher().getIndexReader();
+    AtomicReader reader = (AtomicReader) memory.createSearcher().getIndexReader();
     DocsEnum disi = TestUtil.docs(random(), reader, "foo", new BytesRef("bar"), null, null, DocsEnum.FLAG_NONE);
     int docid = disi.docID();
     assertEquals(-1, docid);
@@ -342,7 +344,7 @@ public class TestMemoryIndexAgainstRAMDi
     MemoryIndex memory = new MemoryIndex(true,  random().nextInt(50) * 1024 * 1024);
     for (int i = 0; i < numIters; i++) { // check reuse
       memory.addField("foo", "bar", analyzer);
-      LeafReader reader = (LeafReader) memory.createSearcher().getIndexReader();
+      AtomicReader reader = (AtomicReader) memory.createSearcher().getIndexReader();
       assertEquals(1, reader.terms("foo").getSumTotalTermFreq());
       DocsAndPositionsEnum disi = reader.termPositionsEnum(new Term("foo", "bar"));
       int docid = disi.docID();
@@ -393,7 +395,7 @@ public class TestMemoryIndexAgainstRAMDi
     MockAnalyzer mockAnalyzer = new MockAnalyzer(random());
     mindex.addField("field", "the quick brown fox", mockAnalyzer);
     mindex.addField("field", "jumps over the", mockAnalyzer);
-    LeafReader reader = (LeafReader) mindex.createSearcher().getIndexReader();
+    AtomicReader reader = (AtomicReader) mindex.createSearcher().getIndexReader();
     assertEquals(7, reader.terms("field").getSumTotalTermFreq());
     PhraseQuery query = new PhraseQuery();
     query.add(new Term("field", "fox"));
@@ -412,7 +414,7 @@ public class TestMemoryIndexAgainstRAMDi
     MemoryIndex mindex = new MemoryIndex(random().nextBoolean(),  random().nextInt(50) * 1024 * 1024);
     MockAnalyzer mockAnalyzer = new MockAnalyzer(random());
     mindex.addField("field", "the quick brown fox", mockAnalyzer);
-    LeafReader reader = (LeafReader) mindex.createSearcher().getIndexReader();
+    AtomicReader reader = (AtomicReader) mindex.createSearcher().getIndexReader();
     assertNull(reader.getNumericDocValues("not-in-index"));
     assertNull(reader.getNormValues("not-in-index"));
     assertNull(reader.termDocsEnum(new Term("not-in-index", "foo")));
@@ -428,10 +430,10 @@ public class TestMemoryIndexAgainstRAMDi
       Directory dir = newDirectory();
       MockAnalyzer mockAnalyzer = new MockAnalyzer(random());
       mockAnalyzer.setMaxTokenLength(TestUtil.nextInt(random(), 1, IndexWriter.MAX_TERM_LENGTH));
-      IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random(), mockAnalyzer));
+      IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random(), TEST_VERSION_CURRENT, mockAnalyzer));
       Document nextDoc = lineFileDocs.nextDoc();
       Document doc = new Document();
-      for (Field field : nextDoc.getFields()) {
+      for (IndexableField field : nextDoc.getFields()) {
         if (field.fieldType().indexed()) {
           doc.add(field);
           if (random().nextInt(3) == 0) {
@@ -442,11 +444,11 @@ public class TestMemoryIndexAgainstRAMDi
       
       writer.addDocument(doc);
       writer.close();
-      for (IndexableField field : doc.indexableFields()) {
+      for (IndexableField field : doc.getFields()) {
           memory.addField(field.name(), ((Field)field).stringValue(), mockAnalyzer);  
       }
       DirectoryReader competitor = DirectoryReader.open(dir);
-      LeafReader memIndexReader= (LeafReader) memory.createSearcher().getIndexReader();
+      AtomicReader memIndexReader= (AtomicReader) memory.createSearcher().getIndexReader();
       duellReaders(competitor, memIndexReader);
       IOUtils.close(competitor, memIndexReader);
       memory.reset();
@@ -484,7 +486,7 @@ public class TestMemoryIndexAgainstRAMDi
     doc.add(new Field(field_name, "foo bar foo bar foo", type));
 
     Directory dir = newDirectory();
-    IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random(), mockAnalyzer));
+    IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random(), TEST_VERSION_CURRENT, mockAnalyzer));
     writer.updateDocument(new Term("id", "1"), doc);
     writer.commit();
     writer.close();