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 2011/03/18 13:42:31 UTC

svn commit: r1082893 - in /lucene/dev/branches/branch_3x: ./ lucene/ lucene/src/java/org/apache/lucene/index/ lucene/src/test/org/apache/lucene/index/ solr/

Author: mikemccand
Date: Fri Mar 18 12:42:31 2011
New Revision: 1082893

URL: http://svn.apache.org/viewvc?rev=1082893&view=rev
Log:
LUCENE-2960: allow certain IWC setters to take effect 'live' after IW has been constructed

Modified:
    lucene/dev/branches/branch_3x/   (props changed)
    lucene/dev/branches/branch_3x/lucene/   (props changed)
    lucene/dev/branches/branch_3x/lucene/CHANGES.txt
    lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java
    lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/IndexWriter.java
    lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/IndexWriterConfig.java
    lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexWriter.java
    lucene/dev/branches/branch_3x/solr/   (props changed)

Modified: lucene/dev/branches/branch_3x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/CHANGES.txt?rev=1082893&r1=1082892&r2=1082893&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_3x/lucene/CHANGES.txt Fri Mar 18 12:42:31 2011
@@ -166,6 +166,10 @@ Changes in runtime behavior
 * LUCENE-2010: Segments with 100% deleted documents are now removed on
   IndexReader or IndexWriter commit.   (Uwe Schindler, Mike McCandless)
   
+* LUCENE-2960: Allow some changes to IndexWriterConfig to take effect
+  "live" (after an IW is instantiated), via
+  IndexWriter.getConfig().setXXX(...) (Shay Banon, Mike McCandless)
+
 API Changes
 
 * LUCENE-2076: Rename FSDirectory.getFile -> getDirectory.  (George

Modified: lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java?rev=1082893&r1=1082892&r2=1082893&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java Fri Mar 18 12:42:31 2011
@@ -258,17 +258,8 @@ final class DocumentsWriter {
 
   // How much RAM we can use before flushing.  This is 0 if
   // we are flushing by doc count instead.
-  private long ramBufferSize = (long) (IndexWriterConfig.DEFAULT_RAM_BUFFER_SIZE_MB*1024*1024);
-  private long waitQueuePauseBytes = (long) (ramBufferSize*0.1);
-  private long waitQueueResumeBytes = (long) (ramBufferSize*0.05);
-
-  // If we've allocated 5% over our RAM budget, we then
-  // free down to 95%
-  private long freeLevel = (long) (IndexWriterConfig.DEFAULT_RAM_BUFFER_SIZE_MB*1024*1024*0.95);
-
-  // Flush @ this number of docs.  If ramBufferSize is
-  // non-zero we will flush by RAM usage instead.
-  private int maxBufferedDocs = IndexWriterConfig.DEFAULT_MAX_BUFFERED_DOCS;
+
+  private final IndexWriterConfig config;
 
   private boolean closed;
   private final FieldInfos fieldInfos;
@@ -276,16 +267,17 @@ final class DocumentsWriter {
   private final BufferedDeletes bufferedDeletes;
   private final IndexWriter.FlushControl flushControl;
 
-  DocumentsWriter(Directory directory, IndexWriter writer, IndexingChain indexingChain, int maxThreadStates, FieldInfos fieldInfos, BufferedDeletes bufferedDeletes) throws IOException {
+  DocumentsWriter(IndexWriterConfig config, Directory directory, IndexWriter writer, FieldInfos fieldInfos, BufferedDeletes bufferedDeletes) throws IOException {
     this.directory = directory;
     this.writer = writer;
-    this.similarity = writer.getConfig().getSimilarity();
-    this.maxThreadStates = maxThreadStates;
+    this.similarity = config.getSimilarity();
+    this.maxThreadStates = config.getMaxThreadStates();
     this.fieldInfos = fieldInfos;
     this.bufferedDeletes = bufferedDeletes;
     flushControl = writer.flushControl;
 
-    consumer = indexingChain.getChain(this);
+    consumer = config.getIndexingChain().getChain(this);
+    this.config = config;
   }
 
   // Buffer a specific docID for deletion.  Currently only
@@ -366,38 +358,6 @@ final class DocumentsWriter {
     }
   }
 
-  /** Set how much RAM we can use before flushing. */
-  synchronized void setRAMBufferSizeMB(double mb) {
-    if (mb == IndexWriterConfig.DISABLE_AUTO_FLUSH) {
-      ramBufferSize = IndexWriterConfig.DISABLE_AUTO_FLUSH;
-      waitQueuePauseBytes = 4*1024*1024;
-      waitQueueResumeBytes = 2*1024*1024;
-    } else {
-      ramBufferSize = (long) (mb*1024*1024);
-      waitQueuePauseBytes = (long) (ramBufferSize*0.1);
-      waitQueueResumeBytes = (long) (ramBufferSize*0.05);
-      freeLevel = (long) (0.95 * ramBufferSize);
-    }
-  }
-
-  synchronized double getRAMBufferSizeMB() {
-    if (ramBufferSize == IndexWriterConfig.DISABLE_AUTO_FLUSH) {
-      return ramBufferSize;
-    } else {
-      return ramBufferSize/1024./1024.;
-    }
-  }
-
-  /** Set max buffered docs, which means we will flush by
-   *  doc count instead of by RAM usage. */
-  void setMaxBufferedDocs(int count) {
-    maxBufferedDocs = count;
-  }
-
-  int getMaxBufferedDocs() {
-    return maxBufferedDocs;
-  }
-
   /** Get current segment name we are writing. */
   synchronized String getSegment() {
     return segment;
@@ -1055,6 +1015,14 @@ final class DocumentsWriter {
 
     deletesRAMUsed = bufferedDeletes.bytesUsed();
 
+    final long ramBufferSize;
+    final double mb = config.getRAMBufferSizeMB();
+    if (mb == IndexWriterConfig.DISABLE_AUTO_FLUSH) {
+      ramBufferSize = IndexWriterConfig.DISABLE_AUTO_FLUSH;
+    } else {
+      ramBufferSize = (long) (mb*1024*1024);
+    }
+
     synchronized(this) {
       if (ramBufferSize == IndexWriterConfig.DISABLE_AUTO_FLUSH || bufferIsFull) {
         return;
@@ -1084,6 +1052,8 @@ final class DocumentsWriter {
 
       boolean any = true;
 
+      final long freeLevel = (long) (0.95 * ramBufferSize);
+
       while(bytesUsed()+deletesRAMUsed > freeLevel) {
       
         synchronized(this) {
@@ -1166,10 +1136,24 @@ final class DocumentsWriter {
     }
 
     synchronized boolean doResume() {
+      final double mb = config.getRAMBufferSizeMB();
+      final long waitQueueResumeBytes;
+      if (mb == IndexWriterConfig.DISABLE_AUTO_FLUSH) {
+        waitQueueResumeBytes = 2*1024*1024;
+      } else {
+        waitQueueResumeBytes = (long) (mb*1024*1024*0.05);
+      }
       return waitingBytes <= waitQueueResumeBytes;
     }
 
     synchronized boolean doPause() {
+      final double mb = config.getRAMBufferSizeMB();
+      final long waitQueuePauseBytes;
+      if (mb == IndexWriterConfig.DISABLE_AUTO_FLUSH) {
+        waitQueuePauseBytes = 4*1024*1024;
+      } else {
+        waitQueuePauseBytes = (long) (mb*1024*1024*0.1);
+      }
       return waitingBytes > waitQueuePauseBytes;
     }
 

Modified: lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/IndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/IndexWriter.java?rev=1082893&r1=1082892&r2=1082893&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/IndexWriter.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/IndexWriter.java Fri Mar 18 12:42:31 2011
@@ -289,9 +289,6 @@ public class IndexWriter implements Clos
 
   private Lock writeLock;
 
-  // TODO 4.0: this should be made final once the setter is out
-  private /*final*/int termIndexInterval;
-
   private boolean closed;
   private boolean closing;
 
@@ -873,9 +870,6 @@ public class IndexWriter implements Clos
   @Deprecated
   public void setTermIndexInterval(int interval) {
     ensureOpen();
-    this.termIndexInterval = interval;
-    // Required so config.getTermIndexInterval returns the right value. But this
-    // will go away together with the method in 4.0.
     config.setTermIndexInterval(interval);
   }
 
@@ -888,7 +882,7 @@ public class IndexWriter implements Clos
   public int getTermIndexInterval() {
     // We pass false because this method is called by SegmentMerger while we are in the process of closing
     ensureOpen(false);
-    return termIndexInterval;
+    return config.getTermIndexInterval();
   }
 
   /**
@@ -1050,10 +1044,9 @@ public class IndexWriter implements Clos
 
   /**
    * Constructs a new IndexWriter per the settings given in <code>conf</code>.
-   * Note that the passed in {@link IndexWriterConfig} is cloned and thus making
-   * changes to it after IndexWriter has been instantiated will not affect
-   * IndexWriter. Additionally, calling {@link #getConfig()} and changing the
-   * parameters does not affect that IndexWriter instance.
+   * Note that the passed in {@link IndexWriterConfig} is
+   * privately cloned; if you need to make subsequent "live"
+   * changes to the configuration use {@link #getConfig}.
    * <p>
    * 
    * @param d
@@ -1079,13 +1072,11 @@ public class IndexWriter implements Clos
     directory = d;
     analyzer = conf.getAnalyzer();
     infoStream = defaultInfoStream;
-    termIndexInterval = conf.getTermIndexInterval();
     writeLockTimeout = conf.getWriteLockTimeout();
     similarity = conf.getSimilarity();
     mergePolicy = conf.getMergePolicy();
     mergePolicy.setIndexWriter(this);
     mergeScheduler = conf.getMergeScheduler();
-    mergedSegmentWarmer = conf.getMergedSegmentWarmer();
     bufferedDeletes = new BufferedDeletes(messageID);
     bufferedDeletes.setInfoStream(infoStream);
     poolReaders = conf.getReaderPooling();
@@ -1155,7 +1146,7 @@ public class IndexWriter implements Clos
 
       setRollbackSegmentInfos(segmentInfos);
 
-      docWriter = new DocumentsWriter(directory, this, conf.getIndexingChain(), conf.getMaxThreadStates(), getCurrentFieldInfos(), bufferedDeletes);
+      docWriter = new DocumentsWriter(config, directory, this, getCurrentFieldInfos(), bufferedDeletes);
       docWriter.setInfoStream(infoStream);
       docWriter.setMaxFieldLength(maxFieldLength);
 
@@ -1174,10 +1165,6 @@ public class IndexWriter implements Clos
         segmentInfos.changed();
       }
 
-      docWriter.setRAMBufferSizeMB(conf.getRAMBufferSizeMB());
-      docWriter.setMaxBufferedDocs(conf.getMaxBufferedDocs());
-      pushMaxBufferedDocs();
-
       if (infoStream != null) {
         messageState();
       }
@@ -1245,13 +1232,15 @@ public class IndexWriter implements Clos
   }
 
   /**
-   * Returns the {@link IndexWriterConfig} that was passed to
-   * {@link #IndexWriter(Directory, IndexWriterConfig)}. This allows querying
-   * IndexWriter's settings.
+   * Returns the private {@link IndexWriterConfig}, cloned
+   * from the {@link IndexWriterConfig} passed to
+   * {@link #IndexWriter(Directory, IndexWriterConfig)}.
    * <p>
-   * <b>NOTE:</b> setting any parameter on the returned instance has not effect
-   * on the IndexWriter instance. If you need to change those settings after
-   * IndexWriter has been created, you need to instantiate a new IndexWriter.
+   * <b>NOTE:</b> some settings may be changed on the
+   * returned {@link IndexWriterConfig}, and will take
+   * effect in the current IndexWriter instance.  See the
+   * javadocs for the specific setters in {@link
+   * IndexWriterConfig} for details.
    */
   public IndexWriterConfig getConfig() {
     return config;
@@ -1458,17 +1447,10 @@ public class IndexWriter implements Clos
   @Deprecated
   public void setMaxBufferedDocs(int maxBufferedDocs) {
     ensureOpen();
-    if (maxBufferedDocs != DISABLE_AUTO_FLUSH && maxBufferedDocs < 2)
-      throw new IllegalArgumentException(
-          "maxBufferedDocs must at least be 2 when enabled");
-    if (maxBufferedDocs == DISABLE_AUTO_FLUSH
-        && getRAMBufferSizeMB() == DISABLE_AUTO_FLUSH)
-      throw new IllegalArgumentException(
-          "at least one of ramBufferSize and maxBufferedDocs must be enabled");
-    docWriter.setMaxBufferedDocs(maxBufferedDocs);
     pushMaxBufferedDocs();
-    if (infoStream != null)
+    if (infoStream != null) {
       message("setMaxBufferedDocs " + maxBufferedDocs);
+    }
     // Required so config.getMaxBufferedDocs returns the right value. But this
     // will go away together with the method in 4.0.
     config.setMaxBufferedDocs(maxBufferedDocs);
@@ -1480,11 +1462,11 @@ public class IndexWriter implements Clos
    * as its minMergeDocs, to keep backwards compatibility.
    */
   private void pushMaxBufferedDocs() {
-    if (docWriter.getMaxBufferedDocs() != DISABLE_AUTO_FLUSH) {
+    if (config.getMaxBufferedDocs() != DISABLE_AUTO_FLUSH) {
       final MergePolicy mp = mergePolicy;
       if (mp instanceof LogDocMergePolicy) {
         LogDocMergePolicy lmp = (LogDocMergePolicy) mp;
-        final int maxBufferedDocs = docWriter.getMaxBufferedDocs();
+        final int maxBufferedDocs = config.getMaxBufferedDocs();
         if (lmp.getMinMergeDocs() != maxBufferedDocs) {
           if (infoStream != null)
             message("now push maxBufferedDocs " + maxBufferedDocs + " to LogDocMergePolicy");
@@ -1503,7 +1485,7 @@ public class IndexWriter implements Clos
   @Deprecated
   public int getMaxBufferedDocs() {
     ensureOpen();
-    return docWriter.getMaxBufferedDocs();
+    return config.getMaxBufferedDocs();
   }
 
   /** Determines the amount of RAM that may be used for
@@ -1547,18 +1529,9 @@ public class IndexWriter implements Clos
    */
   @Deprecated
   public void setRAMBufferSizeMB(double mb) {
-    if (mb > 2048.0) {
-      throw new IllegalArgumentException("ramBufferSize " + mb + " is too large; should be comfortably less than 2048");
-    }
-    if (mb != DISABLE_AUTO_FLUSH && mb <= 0.0)
-      throw new IllegalArgumentException(
-          "ramBufferSize should be > 0.0 MB when enabled");
-    if (mb == DISABLE_AUTO_FLUSH && getMaxBufferedDocs() == DISABLE_AUTO_FLUSH)
-      throw new IllegalArgumentException(
-          "at least one of ramBufferSize and maxBufferedDocs must be enabled");
-    docWriter.setRAMBufferSizeMB(mb);
-    if (infoStream != null)
+    if (infoStream != null) {
       message("setRAMBufferSizeMB " + mb);
+    }
     // Required so config.getRAMBufferSizeMB returns the right value. But this
     // will go away together with the method in 4.0.
     config.setRAMBufferSizeMB(mb);
@@ -1570,7 +1543,7 @@ public class IndexWriter implements Clos
    */
   @Deprecated
   public double getRAMBufferSizeMB() {
-    return docWriter.getRAMBufferSizeMB();
+    return config.getRAMBufferSizeMB();
   }
 
   /**
@@ -1589,10 +1562,6 @@ public class IndexWriter implements Clos
   @Deprecated
   public void setMaxBufferedDeleteTerms(int maxBufferedDeleteTerms) {
     ensureOpen();
-    if (maxBufferedDeleteTerms != DISABLE_AUTO_FLUSH
-        && maxBufferedDeleteTerms < 1)
-      throw new IllegalArgumentException(
-          "maxBufferedDeleteTerms must at least be 1 when enabled");
     if (infoStream != null)
       message("setMaxBufferedDeleteTerms " + maxBufferedDeleteTerms);
     // Required so config.getMaxBufferedDeleteTerms returns the right value. But
@@ -2282,8 +2251,8 @@ public class IndexWriter implements Clos
 
   /** If non-null, information about merges will be printed to this.
    */
-  private PrintStream infoStream = null;
-  private static PrintStream defaultInfoStream = null;
+  private PrintStream infoStream;
+  private static PrintStream defaultInfoStream;
 
   /**
    * Requests an "optimize" operation on an index, priming the index
@@ -2945,7 +2914,7 @@ public class IndexWriter implements Clos
 
     try {
       String mergedName = newSegmentName();
-      SegmentMerger merger = new SegmentMerger(directory, termIndexInterval,
+      SegmentMerger merger = new SegmentMerger(directory, config.getTermIndexInterval(),
                                                mergedName, null, payloadProcessorProvider,
                                                ((FieldInfos) docWriter.getFieldInfos().clone()));
       
@@ -3923,7 +3892,7 @@ public class IndexWriter implements Clos
     SegmentInfos sourceSegments = merge.segments;
     final int numSegments = sourceSegments.size();
 
-    SegmentMerger merger = new SegmentMerger(directory, termIndexInterval, mergedName, merge,
+    SegmentMerger merger = new SegmentMerger(directory, config.getTermIndexInterval(), mergedName, merge,
                                              payloadProcessorProvider,
                                              ((FieldInfos) docWriter.getFieldInfos().clone()));
 
@@ -4042,6 +4011,8 @@ public class IndexWriter implements Clos
         merge.info.setUseCompoundFile(true);
       }
 
+      final IndexReaderWarmer mergedSegmentWarmer = config.getMergedSegmentWarmer();
+
       final int termsIndexDivisor;
       final boolean loadDocStores;
 
@@ -4377,8 +4348,6 @@ public class IndexWriter implements Clos
     public abstract void warm(IndexReader reader) throws IOException;
   }
 
-  private IndexReaderWarmer mergedSegmentWarmer;
-
   /**
    * Set the merged segment warmer. See {@link IndexReaderWarmer}.
    * 
@@ -4388,10 +4357,7 @@ public class IndexWriter implements Clos
    */
   @Deprecated
   public void setMergedSegmentWarmer(IndexReaderWarmer warmer) {
-    mergedSegmentWarmer = warmer;
-    // Required so config.getMergedSegmentWarmer returns the right value. But
-    // this will go away together with the method in 4.0.
-    config.setMergedSegmentWarmer(mergedSegmentWarmer);
+    config.setMergedSegmentWarmer(warmer);
   }
 
   /**
@@ -4401,7 +4367,7 @@ public class IndexWriter implements Clos
    */
   @Deprecated
   public IndexReaderWarmer getMergedSegmentWarmer() {
-    return mergedSegmentWarmer;
+    return config.getMergedSegmentWarmer();
   }
 
   private void handleOOM(OutOfMemoryError oom, String location) {

Modified: lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/IndexWriterConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/IndexWriterConfig.java?rev=1082893&r1=1082892&r2=1082893&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/IndexWriterConfig.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/index/IndexWriterConfig.java Fri Mar 18 12:42:31 2011
@@ -24,12 +24,16 @@ import org.apache.lucene.search.Similari
 import org.apache.lucene.util.Version;
 
 /**
- * Holds all the configuration of {@link IndexWriter}. This object is only used
- * while constructing a new IndexWriter. Those settings cannot be changed
- * afterwards, except instantiating a new IndexWriter.
+ * Holds all the configuration of {@link IndexWriter}.  You
+ * should instantiate this class, call the setters to set
+ * your configuration, then pass it to {@link IndexWriter}.
+ * Note that {@link IndexWriter} makes a private clone; if
+ * you need to subsequently change settings use {@link
+ * IndexWriter#getConfig}.
+ *
  * <p>
  * All setter methods return {@link IndexWriterConfig} to allow chaining
- * settings conveniently. Thus someone can do:
+ * settings conveniently, for example:
  * 
  * <pre>
  * IndexWriterConfig conf = new IndexWriterConfig(analyzer);
@@ -106,25 +110,24 @@ public final class IndexWriterConfig imp
     return WRITE_LOCK_TIMEOUT;
   }
 
-  private Analyzer analyzer;
-  private IndexDeletionPolicy delPolicy;
-  private IndexCommit commit;
-  private OpenMode openMode;
-  private Similarity similarity;
-  private int termIndexInterval;
-  private MergeScheduler mergeScheduler;
-  private long writeLockTimeout;
-  private int maxBufferedDeleteTerms;
-  private double ramBufferSizeMB;
-  private int maxBufferedDocs;
-  private IndexingChain indexingChain;
-  private IndexReaderWarmer mergedSegmentWarmer;
-  private MergePolicy mergePolicy;
-  private int maxThreadStates;
-  private boolean readerPooling;
-  private int readerTermsIndexDivisor;
+  private final Analyzer analyzer;
+  private volatile IndexDeletionPolicy delPolicy;
+  private volatile IndexCommit commit;
+  private volatile OpenMode openMode;
+  private volatile Similarity similarity;
+  private volatile int termIndexInterval;
+  private volatile MergeScheduler mergeScheduler;
+  private volatile long writeLockTimeout;
+  private volatile int maxBufferedDeleteTerms;
+  private volatile double ramBufferSizeMB;
+  private volatile int maxBufferedDocs;
+  private volatile IndexingChain indexingChain;
+  private volatile IndexReaderWarmer mergedSegmentWarmer;
+  private volatile MergePolicy mergePolicy;
+  private volatile int maxThreadStates;
+  private volatile boolean readerPooling;
+  private volatile int readerTermsIndexDivisor;
   
-  // required for clone
   private Version matchVersion;
 
   /**
@@ -158,7 +161,7 @@ public final class IndexWriterConfig imp
   @Override
   public Object clone() {
     // Shallow clone is the only thing that's possible, since parameters like
-    // analyzer, index commit etc. do not implemnt Cloneable.
+    // analyzer, index commit etc. do not implement Cloneable.
     try {
       return super.clone();
     } catch (CloneNotSupportedException e) {
@@ -172,7 +175,9 @@ public final class IndexWriterConfig imp
     return analyzer;
   }
 
-  /** Specifies {@link OpenMode} of that index. */
+  /** Specifies {@link OpenMode} of the index.
+   * 
+   * <p>Only takes effect when IndexWriter is first created. */
   public IndexWriterConfig setOpenMode(OpenMode openMode) {
     this.openMode = openMode;
     return this;
@@ -197,6 +202,8 @@ public final class IndexWriterConfig imp
    * <p>
    * <b>NOTE:</b> the deletion policy cannot be null. If <code>null</code> is
    * passed, the deletion policy will be set to the default.
+   *
+   * <p>Only takes effect when IndexWriter is first created. 
    */
   public IndexWriterConfig setIndexDeletionPolicy(IndexDeletionPolicy delPolicy) {
     this.delPolicy = delPolicy == null ? new KeepOnlyLastCommitDeletionPolicy() : delPolicy;
@@ -215,7 +222,8 @@ public final class IndexWriterConfig imp
   /**
    * Expert: allows to open a certain commit point. The default is null which
    * opens the latest commit point.
-   */
+   *
+   * <p>Only takes effect when IndexWriter is first created. */
   public IndexWriterConfig setIndexCommit(IndexCommit commit) {
     this.commit = commit;
     return this;
@@ -237,7 +245,8 @@ public final class IndexWriterConfig imp
    * the similarity will be set to the default.
    * 
    * @see Similarity#setDefault(Similarity)
-   */
+   *
+   * <p>Only takes effect when IndexWriter is first created. */
   public IndexWriterConfig setSimilarity(Similarity similarity) {
     this.similarity = similarity == null ? Similarity.getDefault() : similarity;
     return this;
@@ -273,7 +282,9 @@ public final class IndexWriterConfig imp
    * must be scanned for each random term access.
    * 
    * @see #DEFAULT_TERM_INDEX_INTERVAL
-   */
+   *
+   * <p>Takes effect immediately, but only applies to newly
+   *  flushed/merged segments. */
   public IndexWriterConfig setTermIndexInterval(int interval) {
     this.termIndexInterval = interval;
     return this;
@@ -294,7 +305,8 @@ public final class IndexWriterConfig imp
    * <p>
    * <b>NOTE:</b> the merge scheduler cannot be null. If <code>null</code> is
    * passed, the merge scheduler will be set to the default.
-   */
+   *
+   * <p>Only takes effect when IndexWriter is first created. */
   public IndexWriterConfig setMergeScheduler(MergeScheduler mergeScheduler) {
     this.mergeScheduler = mergeScheduler == null ? new ConcurrentMergeScheduler() : mergeScheduler;
     return this;
@@ -312,7 +324,8 @@ public final class IndexWriterConfig imp
    * Sets the maximum time to wait for a write lock (in milliseconds) for this
    * instance. You can change the default value for all instances by calling
    * {@link #setDefaultWriteLockTimeout(long)}.
-   */
+   *
+   * <p>Only takes effect when IndexWriter is first created. */
   public IndexWriterConfig setWriteLockTimeout(long writeLockTimeout) {
     this.writeLockTimeout = writeLockTimeout;
     return this;
@@ -338,6 +351,9 @@ public final class IndexWriterConfig imp
    * @throws IllegalArgumentException if maxBufferedDeleteTerms
    * is enabled but smaller than 1
    * @see #setRAMBufferSizeMB
+   *
+   * <p>Takes effect immediately, but only the next time a
+   * document is added, updated or deleted.
    */
   public IndexWriterConfig setMaxBufferedDeleteTerms(int maxBufferedDeleteTerms) {
     if (maxBufferedDeleteTerms != DISABLE_AUTO_FLUSH
@@ -390,6 +406,9 @@ public final class IndexWriterConfig imp
    * <p>
    * The default value is {@link #DEFAULT_RAM_BUFFER_SIZE_MB}.
    * 
+   * <p>Takes effect immediately, but only the next time a
+   * document is added, updated or deleted.
+   *
    * @throws IllegalArgumentException
    *           if ramBufferSize is enabled but non-positive, or it disables
    *           ramBufferSize when maxBufferedDocs is already disabled
@@ -429,6 +448,9 @@ public final class IndexWriterConfig imp
    * <p>
    * Disabled by default (writer flushes by RAM usage).
    * 
+   * <p>Takes effect immediately, but only the next time a
+   * document is added, updated or deleted.
+   *
    * @see #setRAMBufferSizeMB(double)
    * 
    * @throws IllegalArgumentException
@@ -457,7 +479,9 @@ public final class IndexWriterConfig imp
     return maxBufferedDocs;
   }
 
-  /** Set the merged segment warmer. See {@link IndexReaderWarmer}. */
+  /** Set the merged segment warmer. See {@link IndexReaderWarmer}.
+   *
+   * <p>Takes effect on the next merge. */
   public IndexWriterConfig setMergedSegmentWarmer(IndexReaderWarmer mergeSegmentWarmer) {
     this.mergedSegmentWarmer = mergeSegmentWarmer;
     return this;
@@ -474,7 +498,8 @@ public final class IndexWriterConfig imp
    * and return a {@link MergePolicy.MergeSpecification} describing the merges.
    * It also selects merges to do for optimize(). (The default is
    * {@link LogByteSizeMergePolicy}.
-   */
+   *
+   * <p>Only takes effect when IndexWriter is first created. */
   public IndexWriterConfig setMergePolicy(MergePolicy mergePolicy) {
     this.mergePolicy = mergePolicy == null ? new LogByteSizeMergePolicy() : mergePolicy;
     return this;
@@ -494,7 +519,8 @@ public final class IndexWriterConfig imp
    * at once in IndexWriter. Values &lt; 1 are invalid and if passed
    * <code>maxThreadStates</code> will be set to
    * {@link #DEFAULT_MAX_THREAD_STATES}.
-   */
+   *
+   * <p>Only takes effect when IndexWriter is first created. */
   public IndexWriterConfig setMaxThreadStates(int maxThreadStates) {
     this.maxThreadStates = maxThreadStates < 1 ? DEFAULT_MAX_THREAD_STATES : maxThreadStates;
     return this;
@@ -513,7 +539,9 @@ public final class IndexWriterConfig imp
    *  This method lets you enable pooling without getting a
    *  near-real-time reader.  NOTE: if you set this to
    *  false, IndexWriter will still pool readers once
-   *  {@link IndexWriter#getReader} is called. */
+   *  {@link IndexWriter#getReader} is called.
+   *
+   * <p>Only takes effect when IndexWriter is first created. */
   public IndexWriterConfig setReaderPooling(boolean readerPooling) {
     this.readerPooling = readerPooling;
     return this;
@@ -525,7 +553,9 @@ public final class IndexWriterConfig imp
     return readerPooling;
   }
 
-  /** Expert: sets the {@link DocConsumer} chain to be used to process documents. */
+  /** Expert: sets the {@link DocConsumer} chain to be used to process documents.
+   *
+   * <p>Only takes effect when IndexWriter is first created. */
   IndexWriterConfig setIndexingChain(IndexingChain indexingChain) {
     this.indexingChain = indexingChain == null ? DocumentsWriter.defaultIndexingChain : indexingChain;
     return this;
@@ -542,7 +572,10 @@ public final class IndexWriterConfig imp
    *  IndexWriter#getReader}. If you pass -1, the terms index 
    *  won't be loaded by the readers. This is only useful in 
    *  advanced situations when you will only .next() through 
-   *  all terms; attempts to seek will hit an exception. */
+   *  all terms; attempts to seek will hit an exception.
+   *
+   * <p>Takes effect immediately, but only applies to
+   * readers opened after this call */
   public IndexWriterConfig setReaderTermsIndexDivisor(int divisor) {
     if (divisor <= 0 && divisor != -1) {
       throw new IllegalArgumentException("divisor must be >= 1, or -1 (got " + divisor + ")");

Modified: lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexWriter.java?rev=1082893&r1=1082892&r2=1082893&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexWriter.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/test/org/apache/lucene/index/TestIndexWriter.java Fri Mar 18 12:42:31 2011
@@ -844,6 +844,126 @@ public class TestIndexWriter extends Luc
       dir.close();
     }
 
+    // Make sure it's OK to change RAM buffer size and
+    // maxBufferedDocs in a write session, using IW.getConfig()
+    public void testChangingRAMBufferWithIWC() throws IOException {
+      MockDirectoryWrapper dir = newDirectory();      
+      IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(
+        TEST_VERSION_CURRENT, new WhitespaceAnalyzer(TEST_VERSION_CURRENT)).setMaxBufferedDocs(10).setRAMBufferSizeMB(
+        IndexWriterConfig.DISABLE_AUTO_FLUSH));
+      writer.getConfig().setMaxBufferedDocs(10);
+      writer.getConfig().setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+
+      int lastFlushCount = -1;
+      for(int j=1;j<52;j++) {
+        Document doc = new Document();
+        doc.add(new Field("field", "aaa" + j, Field.Store.YES, Field.Index.ANALYZED));
+        writer.addDocument(doc);
+        _TestUtil.syncConcurrentMerges(writer);
+        int flushCount = writer.getFlushCount();
+        if (j == 1)
+          lastFlushCount = flushCount;
+        else if (j < 10)
+          // No new files should be created
+          assertEquals(flushCount, lastFlushCount);
+        else if (10 == j) {
+          assertTrue(flushCount > lastFlushCount);
+          lastFlushCount = flushCount;
+          writer.getConfig().setRAMBufferSizeMB(0.000001);
+          writer.getConfig().setMaxBufferedDocs(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+        } else if (j < 20) {
+          assertTrue(flushCount > lastFlushCount);
+          lastFlushCount = flushCount;
+        } else if (20 == j) {
+          writer.getConfig().setRAMBufferSizeMB(16);
+          writer.getConfig().setMaxBufferedDocs(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+          lastFlushCount = flushCount;
+        } else if (j < 30) {
+          assertEquals(flushCount, lastFlushCount);
+        } else if (30 == j) {
+          writer.getConfig().setRAMBufferSizeMB(0.000001);
+          writer.getConfig().setMaxBufferedDocs(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+        } else if (j < 40) {
+          assertTrue(flushCount> lastFlushCount);
+          lastFlushCount = flushCount;
+        } else if (40 == j) {
+          writer.getConfig().setMaxBufferedDocs(10);
+          writer.getConfig().setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+          lastFlushCount = flushCount;
+        } else if (j < 50) {
+          assertEquals(flushCount, lastFlushCount);
+          writer.getConfig().setMaxBufferedDocs(10);
+          writer.getConfig().setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+        } else if (50 == j) {
+          assertTrue(flushCount > lastFlushCount);
+        }
+      }
+      writer.close();
+      dir.close();
+    }
+
+    public void testChangingRAMBuffer2WithIWC() throws IOException {
+      MockDirectoryWrapper dir = newDirectory();      
+      IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(
+        TEST_VERSION_CURRENT, new WhitespaceAnalyzer(TEST_VERSION_CURRENT)).setMaxBufferedDocs(10).setMaxBufferedDeleteTerms(
+        10).setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH));
+      writer.getConfig().setMaxBufferedDocs(10);
+      writer.getConfig().setMaxBufferedDeleteTerms(10);
+      writer.getConfig().setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+
+      for(int j=1;j<52;j++) {
+        Document doc = new Document();
+        doc.add(new Field("field", "aaa" + j, Field.Store.YES, Field.Index.ANALYZED));
+        writer.addDocument(doc);
+      }
+      
+      int lastFlushCount = -1;
+      for(int j=1;j<52;j++) {
+        writer.deleteDocuments(new Term("field", "aaa" + j));
+        _TestUtil.syncConcurrentMerges(writer);
+        int flushCount = writer.getFlushCount();
+        if (j == 1)
+          lastFlushCount = flushCount;
+        else if (j < 10) {
+          // No new files should be created
+          assertEquals(flushCount, lastFlushCount);
+        } else if (10 == j) {
+          assertTrue(flushCount > lastFlushCount);
+          lastFlushCount = flushCount;
+          writer.getConfig().setRAMBufferSizeMB(0.000001);
+          writer.getConfig().setMaxBufferedDeleteTerms(1);
+        } else if (j < 20) {
+          assertTrue(flushCount > lastFlushCount);
+          lastFlushCount = flushCount;
+        } else if (20 == j) {
+          writer.getConfig().setRAMBufferSizeMB(16);
+          writer.getConfig().setMaxBufferedDeleteTerms(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+          lastFlushCount = flushCount;
+        } else if (j < 30) {
+          assertEquals(flushCount, lastFlushCount);
+        } else if (30 == j) {
+          writer.getConfig().setRAMBufferSizeMB(0.000001);
+          writer.getConfig().setMaxBufferedDeleteTerms(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+          writer.getConfig().setMaxBufferedDeleteTerms(1);
+        } else if (j < 40) {
+          assertTrue(flushCount> lastFlushCount);
+          lastFlushCount = flushCount;
+        } else if (40 == j) {
+          writer.getConfig().setMaxBufferedDeleteTerms(10);
+          writer.getConfig().setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+          lastFlushCount = flushCount;
+        } else if (j < 50) {
+          assertEquals(flushCount, lastFlushCount);
+          writer.getConfig().setMaxBufferedDeleteTerms(10);
+          writer.getConfig().setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH);
+        } else if (50 == j) {
+          assertTrue(flushCount > lastFlushCount);
+        }
+      }
+      writer.close();
+      dir.close();
+    }
+
     public void testDiverseDocs() throws IOException {
       MockDirectoryWrapper dir = newDirectory();      
       IndexWriter writer  = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new WhitespaceAnalyzer(TEST_VERSION_CURRENT)).setRAMBufferSizeMB(0.5));