You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by sh...@apache.org on 2011/01/18 15:24:07 UTC

svn commit: r1060391 - in /lucene/java/branches/lucene_3_0: CHANGES.txt src/java/org/apache/lucene/index/SegmentInfo.java

Author: shaie
Date: Tue Jan 18 14:24:07 2011
New Revision: 1060391

URL: http://svn.apache.org/viewvc?rev=1060391&view=rev
Log:
LUCENE-2584: port fix to 3.0

Modified:
    lucene/java/branches/lucene_3_0/CHANGES.txt
    lucene/java/branches/lucene_3_0/src/java/org/apache/lucene/index/SegmentInfo.java

Modified: lucene/java/branches/lucene_3_0/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_3_0/CHANGES.txt?rev=1060391&r1=1060390&r2=1060391&view=diff
==============================================================================
--- lucene/java/branches/lucene_3_0/CHANGES.txt (original)
+++ lucene/java/branches/lucene_3_0/CHANGES.txt Tue Jan 18 14:24:07 2011
@@ -3,7 +3,10 @@ $Id$
 
 ======================= 3.0 branch (not yet released) ==================
 
-No changes.
+Bug fixes
+
+* LUCENE-2584: SegmentInfo.files() could hit ConcurrentModificationException if
+  called by multiple threads. (Alexander Kanarsky via Shai Erera)
 
 ======================= Release 3.0.3 2010-12-03 =======================
 

Modified: lucene/java/branches/lucene_3_0/src/java/org/apache/lucene/index/SegmentInfo.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_3_0/src/java/org/apache/lucene/index/SegmentInfo.java?rev=1060391&r1=1060390&r2=1060391&view=diff
==============================================================================
--- lucene/java/branches/lucene_3_0/src/java/org/apache/lucene/index/SegmentInfo.java (original)
+++ lucene/java/branches/lucene_3_0/src/java/org/apache/lucene/index/SegmentInfo.java Tue Jan 18 14:24:07 2011
@@ -22,11 +22,13 @@ import org.apache.lucene.store.IndexOutp
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.BitVector;
 import java.io.IOException;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Set;
 
 /**
  * Information about a segment such as it's name, directory, and files related
@@ -572,7 +574,7 @@ public final class SegmentInfo {
     return hasProx;
   }
 
-  private void addIfExists(List<String> files, String fileName) throws IOException {
+  private void addIfExists(Set<String> files, String fileName) throws IOException {
     if (dir.fileExists(fileName))
       files.add(fileName);
   }
@@ -590,16 +592,16 @@ public final class SegmentInfo {
       return files;
     }
     
-    files = new ArrayList<String>();
+    Set<String> filesSet = new HashSet<String>();
     
     boolean useCompoundFile = getUseCompoundFile();
 
     if (useCompoundFile) {
-      files.add(name + "." + IndexFileNames.COMPOUND_FILE_EXTENSION);
+      filesSet.add(name + "." + IndexFileNames.COMPOUND_FILE_EXTENSION);
     } else {
       final String[] exts = IndexFileNames.NON_STORE_INDEX_EXTENSIONS;
       for(int i=0;i<exts.length;i++)
-        addIfExists(files, name + "." + exts[i]);
+        addIfExists(filesSet, name + "." + exts[i]);
     }
 
     if (docStoreOffset != -1) {
@@ -607,23 +609,23 @@ public final class SegmentInfo {
       // vectors) with other segments
       assert docStoreSegment != null;
       if (docStoreIsCompoundFile) {
-        files.add(docStoreSegment + "." + IndexFileNames.COMPOUND_FILE_STORE_EXTENSION);
+        filesSet.add(docStoreSegment + "." + IndexFileNames.COMPOUND_FILE_STORE_EXTENSION);
       } else {
         final String[] exts = IndexFileNames.STORE_INDEX_EXTENSIONS;
         for(int i=0;i<exts.length;i++)
-          addIfExists(files, docStoreSegment + "." + exts[i]);
+          addIfExists(filesSet, docStoreSegment + "." + exts[i]);
       }
     } else if (!useCompoundFile) {
       // We are not sharing, and, these files were not
       // included in the compound file
       final String[] exts = IndexFileNames.STORE_INDEX_EXTENSIONS;
       for(int i=0;i<exts.length;i++)
-        addIfExists(files, name + "." + exts[i]);
+        addIfExists(filesSet, name + "." + exts[i]);
     }
 
     String delFileName = IndexFileNames.fileNameFromGeneration(name, "." + IndexFileNames.DELETES_EXTENSION, delGen);
     if (delFileName != null && (delGen >= YES || dir.fileExists(delFileName))) {
-      files.add(delFileName);
+      filesSet.add(delFileName);
     }
 
     // Careful logic for norms files    
@@ -632,14 +634,14 @@ public final class SegmentInfo {
         long gen = normGen[i];
         if (gen >= YES) {
           // Definitely a separate norm file, with generation:
-          files.add(IndexFileNames.fileNameFromGeneration(name, "." + IndexFileNames.SEPARATE_NORMS_EXTENSION + i, gen));
+          filesSet.add(IndexFileNames.fileNameFromGeneration(name, "." + IndexFileNames.SEPARATE_NORMS_EXTENSION + i, gen));
         } else if (NO == gen) {
           // No separate norms but maybe plain norms
           // in the non compound file case:
           if (!hasSingleNormFile && !useCompoundFile) {
             String fileName = name + "." + IndexFileNames.PLAIN_NORMS_EXTENSION + i;
             if (dir.fileExists(fileName)) {
-              files.add(fileName);
+              filesSet.add(fileName);
             }
           }
         } else if (CHECK_DIR == gen) {
@@ -651,7 +653,7 @@ public final class SegmentInfo {
             fileName = name + "." + IndexFileNames.PLAIN_NORMS_EXTENSION + i;
           }
           if (fileName != null && dir.fileExists(fileName)) {
-            files.add(fileName);
+            filesSet.add(fileName);
           }
         }
       }
@@ -669,11 +671,11 @@ public final class SegmentInfo {
       for(int i=0;i<allFiles.length;i++) {
         String fileName = allFiles[i];
         if (filter.accept(null, fileName) && fileName.length() > prefixLength && Character.isDigit(fileName.charAt(prefixLength)) && fileName.startsWith(prefix)) {
-          files.add(fileName);
+          filesSet.add(fileName);
         }
       }
     }
-    return files;
+    return files = new ArrayList<String>(filesSet);
   }
 
   /* Called whenever any change is made that affects which