Expose Lucene Index Writers for plug-ins

By allowing other packages to reach the Lucene Index Writer,
Gerrit plug-ins can now be written to allow runtime
reconfiguration of various Lucene performance related
parameters.

All IndexWriters are now also AutoCommitWriters. This will
allow a plug-in to temporarily turn on auto-committing in
situations where it makes sense enforcing all changes to
be written to disk ASAP.

In our case, this allows us building a hot swap mechanism for
two Gerrit servers to be used within a continuous deployment
setup, without needing to sacrifice the daily performance of
the production systems (which a permanent index.name.commitWithin
= 0 configuration would have done).

Change-Id: Iacba1f5acd4b59c77e6b1619d1438a69fe0c77d0
diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/AutoCommitWriter.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/AutoCommitWriter.java
index 27ded17..4e47bca 100644
--- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/AutoCommitWriter.java
+++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/AutoCommitWriter.java
@@ -25,13 +25,28 @@
 import java.io.IOException;
 
 /** Writer that optionally flushes/commits after every write. */
-class AutoCommitWriter extends IndexWriter {
+public class AutoCommitWriter extends IndexWriter {
   private boolean autoCommit;
 
+  AutoCommitWriter(Directory dir, IndexWriterConfig config)
+      throws IOException {
+    this(dir, config, false);
+  }
+
   AutoCommitWriter(Directory dir, IndexWriterConfig config, boolean autoCommit)
       throws IOException {
     super(dir, config);
-    this.autoCommit = autoCommit;
+    setAutoCommit(autoCommit);
+  }
+
+  /**
+   * This method will override Gerrit configuration index.name.commitWithin
+   * until next Gerrit restart (or reconfiguration through this method).
+   *
+   * @param enable auto commit
+   */
+  public void setAutoCommit(boolean enable) {
+    this.autoCommit = enable;
   }
 
   @Override
@@ -99,7 +114,7 @@
     }
   }
 
-  private void autoFlush() throws IOException {
+  public void autoFlush() throws IOException {
     if (autoCommit) {
       manualFlush();
     }
diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java
index 55ed22d..99003ee 100644
--- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java
+++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java
@@ -386,6 +386,14 @@
     }
   }
 
+  public SubIndex getOpenChangesIndex() {
+    return openIndex;
+  }
+
+  public SubIndex getClosedChangesIndex() {
+    return closedIndex;
+  }
+
   private class QuerySource implements ChangeDataSource {
     private final List<SubIndex> indexes;
     private final Query query;
diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/SubIndex.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/SubIndex.java
index 5778008..bb69533bf 100644
--- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/SubIndex.java
+++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/SubIndex.java
@@ -47,7 +47,7 @@
 import java.util.concurrent.TimeoutException;
 
 /** Piece of the change index that is implemented as a separate Lucene index. */
-class SubIndex {
+public class SubIndex {
   private static final Logger log = LoggerFactory.getLogger(SubIndex.class);
 
   private final Directory dir;
@@ -70,13 +70,13 @@
     long commitPeriod = writerConfig.getCommitWithinMs();
 
     if (commitPeriod < 0) {
-      delegateWriter = new IndexWriter(dir, writerConfig.getLuceneConfig());
+      delegateWriter = new AutoCommitWriter(dir, writerConfig.getLuceneConfig());
     } else if (commitPeriod == 0) {
       delegateWriter =
           new AutoCommitWriter(dir, writerConfig.getLuceneConfig(), true);
     } else {
       final AutoCommitWriter autoCommitWriter =
-          new AutoCommitWriter(dir, writerConfig.getLuceneConfig(), false);
+          new AutoCommitWriter(dir, writerConfig.getLuceneConfig());
       delegateWriter = autoCommitWriter;
 
       new ScheduledThreadPoolExecutor(1, new ThreadFactoryBuilder()
@@ -191,6 +191,10 @@
     writer.deleteAll();
   }
 
+  public TrackingIndexWriter getWriter() {
+    return writer;
+  }
+
   IndexSearcher acquire() throws IOException {
     return searcherManager.acquire();
   }