You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by yo...@apache.org on 2010/12/17 16:15:02 UTC

svn commit: r1050415 - in /lucene/dev/trunk/lucene/src/java/org/apache/lucene/index: IndexReader.java MultiFields.java

Author: yonik
Date: Fri Dec 17 15:15:01 2010
New Revision: 1050415

URL: http://svn.apache.org/viewvc?rev=1050415&view=rev
Log:
LUCENE-2815: fix MultiFields thread safety, don't cache null terms(field)

Modified:
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/IndexReader.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/MultiFields.java

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/IndexReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/IndexReader.java?rev=1050415&r1=1050414&r2=1050415&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/IndexReader.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/IndexReader.java Fri Dec 17 15:15:01 2010
@@ -1420,7 +1420,7 @@ public abstract class IndexReader implem
   }
 
 
-  private Fields fields;
+  private volatile Fields fields;
 
   /** @lucene.internal */
   void storeFields(Fields fields) {

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/MultiFields.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/MultiFields.java?rev=1050415&r1=1050414&r2=1050415&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/MultiFields.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/MultiFields.java Fri Dec 17 15:15:01 2010
@@ -19,9 +19,10 @@ package org.apache.lucene.index;
 
 import java.io.IOException;
 import java.util.Map;
-import java.util.HashMap;
 import java.util.List;
 import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+
 import org.apache.lucene.util.ReaderUtil;
 import org.apache.lucene.util.ReaderUtil.Gather;  // for javadocs
 import org.apache.lucene.util.Bits;
@@ -45,7 +46,7 @@ import org.apache.lucene.util.BytesRef;
 public final class MultiFields extends Fields {
   private final Fields[] subs;
   private final ReaderUtil.Slice[] subSlices;
-  private final Map<String,Terms> terms = new HashMap<String,Terms>();
+  private final Map<String,Terms> terms = new ConcurrentHashMap<String,Terms>();
 
   /** Returns a single {@link Fields} instance for this
    *  reader, merging fields/terms/docs/positions on the
@@ -240,32 +241,32 @@ public final class MultiFields extends F
   @Override
   public Terms terms(String field) throws IOException {
 
-    final Terms result;
+    Terms result = terms.get(field);
+    if (result != null)
+      return result;
 
-    if (!terms.containsKey(field)) {
 
-      // Lazy init: first time this field is requested, we
-      // create & add to terms:
-      final List<Terms> subs2 = new ArrayList<Terms>();
-      final List<ReaderUtil.Slice> slices2 = new ArrayList<ReaderUtil.Slice>();
-
-      // Gather all sub-readers that share this field
-      for(int i=0;i<subs.length;i++) {
-        final Terms terms = subs[i].terms(field);
-        if (terms != null) {
-          subs2.add(terms);
-          slices2.add(subSlices[i]);
-        }
-      }
-      if (subs2.size() == 0) {
-        result = null;
-      } else {
-        result = new MultiTerms(subs2.toArray(Terms.EMPTY_ARRAY),
-                                slices2.toArray(ReaderUtil.Slice.EMPTY_ARRAY));
+    // Lazy init: first time this field is requested, we
+    // create & add to terms:
+    final List<Terms> subs2 = new ArrayList<Terms>();
+    final List<ReaderUtil.Slice> slices2 = new ArrayList<ReaderUtil.Slice>();
+
+    // Gather all sub-readers that share this field
+    for(int i=0;i<subs.length;i++) {
+      final Terms terms = subs[i].terms(field);
+      if (terms != null) {
+        subs2.add(terms);
+        slices2.add(subSlices[i]);
       }
-      terms.put(field, result);
+    }
+    if (subs2.size() == 0) {
+      result = null;
+      // don't cache this case with an unbounded cache, since the number of fields that don't exist
+      // is unbounded.
     } else {
-      result = terms.get(field);
+      result = new MultiTerms(subs2.toArray(Terms.EMPTY_ARRAY),
+          slices2.toArray(ReaderUtil.Slice.EMPTY_ARRAY));
+      terms.put(field, result);
     }
 
     return result;