You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2012/08/15 13:23:07 UTC

svn commit: r1373337 [3/3] - in /lucene/dev/branches/lucene3312: ./ lucene/ lucene/analysis/ lucene/analysis/common/ lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/ lucene/analysis/common/src/test/org/apache/lucene/analysis/core/ l...

Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java Wed Aug 15 11:23:02 2012
@@ -31,7 +31,7 @@ import org.apache.solr.client.solrj.requ
 import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.common.cloud.SafeStopThread;
+import org.apache.solr.common.cloud.ClosableThread;
 import org.apache.solr.common.cloud.ZkCoreNodeProps;
 import org.apache.solr.common.cloud.ZkNodeProps;
 import org.apache.solr.common.cloud.ZkStateReader;
@@ -56,7 +56,7 @@ import org.apache.zookeeper.KeeperExcept
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class RecoveryStrategy extends Thread implements SafeStopThread {
+public class RecoveryStrategy extends Thread implements ClosableThread {
   private static final int MAX_RETRIES = 500;
   private static final int INTERRUPTED = MAX_RETRIES + 1;
   private static final int STARTING_RECOVERY_DELAY = 1000;
@@ -139,7 +139,7 @@ public class RecoveryStrategy extends Th
       solrParams.set(ReplicationHandler.MASTER_URL, leaderUrl);
       
       if (isClosed()) retries = INTERRUPTED;
-      boolean success = replicationHandler.doFetch(solrParams, true); // TODO: look into making sure force=true does not download files we already have
+      boolean success = replicationHandler.doFetch(solrParams, true); // TODO: look into making force=true not download files we already have?
 
       if (!success) {
         throw new SolrException(ErrorCode.SERVER_ERROR, "Replication for recovery failed.");
@@ -292,9 +292,6 @@ public class RecoveryStrategy extends Th
 
     while (!successfulRecovery && !isClosed() && !isInterrupted()) { // don't use interruption or it will close channels though
       try {
-        // first thing we just try to sync
-        zkController.publish(core.getCoreDescriptor(), ZkStateReader.RECOVERING);
-
         CloudDescriptor cloudDesc = core.getCoreDescriptor()
             .getCloudDescriptor();
         ZkNodeProps leaderprops = zkStateReader.getLeaderProps(
@@ -305,6 +302,19 @@ public class RecoveryStrategy extends Th
 
         String leaderUrl = ZkCoreNodeProps.getCoreUrl(leaderBaseUrl, leaderCoreName);
 
+        String ourUrl = ZkCoreNodeProps.getCoreUrl(baseUrl, coreName);
+
+        boolean isLeader = leaderUrl.equals(ourUrl);
+        if (isLeader) {
+          // we are now the leader - no one else must have been suitable
+          log.warn("We have not yet recovered - but we are now the leader! core=" + coreName);
+          log.info("Finished recovery process. core=" + coreName);
+          zkController.publish(core.getCoreDescriptor(), ZkStateReader.ACTIVE);
+          return;
+        }
+        
+        zkController.publish(core.getCoreDescriptor(), ZkStateReader.RECOVERING);
+        
         sendPrepRecoveryCmd(leaderBaseUrl, leaderCoreName);
 
 
@@ -358,7 +368,19 @@ public class RecoveryStrategy extends Th
         log.info("Begin buffering updates. core=" + coreName);
         ulog.bufferUpdates();
         replayed = false;
-
+        
+//        // open a new IndexWriter - we don't want any background merges ongoing
+//        // also ensures something like NRTCachingDirectory is flushed
+//        boolean forceNewIndexDir = false;
+//        try {
+//          core.getUpdateHandler().newIndexWriter(false);
+//        } catch (Throwable t) {
+//          SolrException.log(log, "Could not read the current index - replicating to a new directory", t);
+//          // something is wrong with the index
+//          // we need to force using a new index directory
+//          forceNewIndexDir = true;
+//        }
+//        
         try {
 
           replicate(zkController.getNodeName(), core,
@@ -377,7 +399,7 @@ public class RecoveryStrategy extends Th
           log.warn("Recovery was interrupted", e);
           retries = INTERRUPTED;
         } catch (Throwable t) {
-          log.error("Error while trying to recover", t);
+          SolrException.log(log, "Error while trying to recover", t);
         } finally {
           if (!replayed) {
             try {
@@ -390,7 +412,7 @@ public class RecoveryStrategy extends Th
         }
 
       } catch (Throwable t) {
-        log.error("Error while trying to recover. core=" + coreName, t);
+        SolrException.log(log, "Error while trying to recover. core=" + coreName, t);
       }
 
       if (!successfulRecovery) {
@@ -405,7 +427,7 @@ public class RecoveryStrategy extends Th
             if (retries == INTERRUPTED) {
 
             } else {
-              log.error("Recovery failed - max retries exceeded. core=" + coreName);
+              SolrException.log(log, "Recovery failed - max retries exceeded. core=" + coreName);
               recoveryFailed(core, zkController, baseUrl, coreZkNodeName,
                   core.getCoreDescriptor());
             }
@@ -413,7 +435,7 @@ public class RecoveryStrategy extends Th
           }
 
         } catch (Exception e) {
-          log.error("core=" + coreName, e);
+          SolrException.log(log, "core=" + coreName, e);
         }
 
         try {

Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ZkController.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ZkController.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ZkController.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ZkController.java Wed Aug 15 11:23:02 2012
@@ -247,15 +247,7 @@ public final class ZkController {
     } catch(Throwable t) {
       log.error("Error closing overseer", t);
     }
-    try {
-      zkClient.close();
-    } catch (InterruptedException e) {
-      // Restore the interrupted status
-      Thread.currentThread().interrupt();
-      log.warn("", e);
-      throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
-          "", e);
-    }
+    zkClient.close();
   }
 
   /**

Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/CachingDirectoryFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/CachingDirectoryFactory.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/CachingDirectoryFactory.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/CachingDirectoryFactory.java Wed Aug 15 11:23:02 2012
@@ -105,7 +105,11 @@ public abstract class CachingDirectoryFa
   public void close() throws IOException {
     synchronized (this) {
       for (CacheValue val : byDirectoryCache.values()) {
-        val.directory.close();
+        try {
+          val.directory.close();
+        } catch (Throwable t) {
+          SolrException.log(log, "Error closing directory", t);
+        }
       }
       byDirectoryCache.clear();
       byPathCache.clear();

Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java Wed Aug 15 11:23:02 2012
@@ -283,7 +283,7 @@ public class ReplicationHandler extends 
 
   private volatile SnapPuller tempSnapPuller;
 
-  public boolean doFetch(SolrParams solrParams, boolean force) {
+  public boolean doFetch(SolrParams solrParams, boolean forceReplication) {
     String masterUrl = solrParams == null ? null : solrParams.get(MASTER_URL);
     if (!snapPullLock.tryLock())
       return false;
@@ -294,7 +294,7 @@ public class ReplicationHandler extends 
         nl.remove(SnapPuller.POLL_INTERVAL);
         tempSnapPuller = new SnapPuller(nl, this, core);
       }
-      return tempSnapPuller.fetchLatestIndex(core, force);
+      return tempSnapPuller.fetchLatestIndex(core, forceReplication);
     } catch (Exception e) {
       SolrException.log(LOG, "SnapPull failed ", e);
     } finally {

Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/SnapPuller.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/SnapPuller.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/SnapPuller.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/SnapPuller.java Wed Aug 15 11:23:02 2012
@@ -243,12 +243,11 @@ public class SnapPuller {
    * downloaded. It also downloads the conf files (if they are modified).
    *
    * @param core the SolrCore
-   * @param force force a replication in all cases 
+   * @param forceReplication force a replication in all cases 
    * @return true on success, false if slave is already in sync
    * @throws IOException if an exception occurs
    */
-  @SuppressWarnings("unchecked")
-  boolean fetchLatestIndex(SolrCore core, boolean force) throws IOException, InterruptedException {
+  boolean fetchLatestIndex(SolrCore core, boolean forceReplication) throws IOException, InterruptedException {
     successfulInstall = false;
     replicationStartTime = System.currentTimeMillis();
     try {
@@ -278,7 +277,7 @@ public class SnapPuller {
       }
       
       if (latestVersion == 0L) {
-        if (force && commit.getGeneration() != 0) {
+        if (forceReplication && commit.getGeneration() != 0) {
           // since we won't get the files for an empty index,
           // we just clear ours and commit
           RefCounted<IndexWriter> iw = core.getUpdateHandler().getSolrCoreState().getIndexWriter(core);
@@ -297,7 +296,7 @@ public class SnapPuller {
         return true;
       }
       
-      if (!force && IndexDeletionPolicyWrapper.getCommitTimestamp(commit) == latestVersion) {
+      if (!forceReplication && IndexDeletionPolicyWrapper.getCommitTimestamp(commit) == latestVersion) {
         //master and slave are already in sync just return
         LOG.info("Slave in sync with master.");
         successfulInstall = true;
@@ -318,10 +317,11 @@ public class SnapPuller {
       filesDownloaded = Collections.synchronizedList(new ArrayList<Map<String, Object>>());
       // if the generateion of master is older than that of the slave , it means they are not compatible to be copied
       // then a new index direcory to be created and all the files need to be copied
-      boolean isFullCopyNeeded = IndexDeletionPolicyWrapper.getCommitTimestamp(commit) >= latestVersion || force;
+      boolean isFullCopyNeeded = IndexDeletionPolicyWrapper.getCommitTimestamp(commit) >= latestVersion || forceReplication;
       File tmpIndexDir = createTempindexDir(core);
-      if (isIndexStale())
+      if (isIndexStale()) {
         isFullCopyNeeded = true;
+      }
       LOG.info("Starting download to " + tmpIndexDir + " fullCopy=" + isFullCopyNeeded);
       successfulInstall = false;
       boolean deleteTmpIdxDir = true;

Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java Wed Aug 15 11:23:02 2012
@@ -31,6 +31,7 @@ import org.apache.lucene.document.Field;
 import org.apache.lucene.index.*;
 import org.apache.lucene.index.FieldInfo.IndexOptions;
 import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.similarities.Similarity;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.CharsRef;
@@ -425,6 +426,7 @@ public class LukeRequestHandler extends 
       field.add("className", ft.getClass().getName());
       field.add("indexAnalyzer", getAnalyzerInfo(ft.getAnalyzer()));
       field.add("queryAnalyzer", getAnalyzerInfo(ft.getQueryAnalyzer()));
+      field.add("similarity", getSimilarityInfo(ft.getSimilarity()));
       types.add( ft.getTypeName(), field );
     }
 
@@ -450,6 +452,14 @@ public class LukeRequestHandler extends 
     return finfo;
   }
 
+  private static SimpleOrderedMap<Object> getSimilarityInfo(Similarity similarity) {
+    SimpleOrderedMap<Object> toReturn = new SimpleOrderedMap<Object>();
+    if (similarity != null) {
+      toReturn.add("className", similarity.getClass().getName());
+      toReturn.add("details", similarity.toString());
+    }
+    return toReturn;
+  }
 
   private static SimpleOrderedMap<Object> getAnalyzerInfo(Analyzer analyzer) {
     SimpleOrderedMap<Object> aninfo = new SimpleOrderedMap<Object>();
@@ -544,7 +554,7 @@ public class LukeRequestHandler extends 
     indexInfo.add("maxDoc", reader.maxDoc());
 
     indexInfo.add("version", reader.getVersion());  // TODO? Is this different then: IndexReader.getCurrentVersion( dir )?
-    indexInfo.add("segmentCount", reader.getTopReaderContext().leaves().size());
+    indexInfo.add("segmentCount", reader.leaves().size());
     indexInfo.add("current", reader.isCurrent() );
     indexInfo.add("hasDeletions", reader.hasDeletions() );
     indexInfo.add("directory", dir );

Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java Wed Aug 15 11:23:02 2012
@@ -679,7 +679,7 @@ public class SpellCheckComponent extends
         if (buildOnCommit)  {
           buildSpellIndex(newSearcher);
         } else if (buildOnOptimize) {
-          if (newSearcher.getIndexReader().getSequentialSubReaders().size() == 1)  {
+          if (newSearcher.getIndexReader().leaves().size() == 1)  {
             buildSpellIndex(newSearcher);
           } else  {
             LOG.info("Index is not optimized therefore skipping building spell check index for: " + checker.getDictionaryName());

Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java Wed Aug 15 11:23:02 2012
@@ -63,7 +63,7 @@ public class ValueSourceAugmenter extend
   public void setContext( TransformContext context ) {
     try {
       IndexReader reader = qparser.getReq().getSearcher().getIndexReader();
-      readerContexts = reader.getTopReaderContext().leaves();
+      readerContexts = reader.leaves();
       docValuesArr = new FunctionValues[readerContexts.size()];
 
       searcher = qparser.getReq().getSearcher();

Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/servlet/ZookeeperInfoServlet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/servlet/ZookeeperInfoServlet.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/servlet/ZookeeperInfoServlet.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/servlet/ZookeeperInfoServlet.java Wed Aug 15 11:23:02 2012
@@ -17,6 +17,16 @@
 
 package org.apache.solr.servlet;
 
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URLEncoder;
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.lucene.util.BytesRef;
 import org.apache.noggit.CharArr;
 import org.apache.noggit.JSONWriter;
@@ -28,16 +38,6 @@ import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.URLEncoder;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
 
 /**
  * Zookeeper Info
@@ -148,13 +148,7 @@ public final class ZookeeperInfoServlet 
       try {
         zkClient = new SolrZkClient(addr, 10000);
         doClose = true;
-      } catch (TimeoutException e) {
-        writeError(503, "Could not connect to zookeeper at '" + addr + "'\"");
-        zkClient = null;
-        return;
-      } catch (InterruptedException e) {
-        // Restore the interrupted status
-        Thread.currentThread().interrupt();
+      } catch (Exception e) {
         writeError(503, "Could not connect to zookeeper at '" + addr + "'\"");
         zkClient = null;
         return;
@@ -163,12 +157,8 @@ public final class ZookeeperInfoServlet 
     }
 
     public void close() {
-      try {
-        if (doClose) {
-          zkClient.close();
-        }
-      } catch (InterruptedException e) {
-        // ignore exception on close
+      if (doClose) {
+        zkClient.close();
       }
     }
 

Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java Wed Aug 15 11:23:02 2012
@@ -97,12 +97,14 @@ public final class DefaultSolrCoreState 
 
   @Override
   public synchronized void newIndexWriter(SolrCore core, boolean rollback) throws IOException {
-    
+    log.info("Creating new IndexWriter...");
+    String coreName = core.getName();
     synchronized (writerPauseLock) {
       // we need to wait for the Writer to fall out of use
       // first lets stop it from being lent out
       pauseWriter = true;
       // then lets wait until its out of use
+      log.info("Waiting until IndexWriter is unused... core=" + coreName);
       while (!writerFree) {
         try {
           writerPauseLock.wait();
@@ -112,14 +114,15 @@ public final class DefaultSolrCoreState 
       try {
         if (indexWriter != null) {
           try {
+            log.info("Closing old IndexWriter... core=" + coreName);
             indexWriter.close();
           } catch (Throwable t) {
-            SolrException.log(log, "Error closing old IndexWriter", t);
+            SolrException.log(log, "Error closing old IndexWriter. core=" + coreName, t);
           }
         }
-        
         indexWriter = createMainIndexWriter(core, "DirectUpdateHandler2",
             false, true);
+        log.info("New IndexWriter is ready to be used.");
         // we need to null this so it picks up the new writer next get call
         refCntWriter = null;
       } finally {
@@ -136,6 +139,7 @@ public final class DefaultSolrCoreState 
       refCnt--;
       if (refCnt == 0) {
         try {
+          log.info("SolrCoreState ref count has reached 0 - closing IndexWriter");
           if (closer != null) {
             closer.closeWriter(indexWriter);
           } else if (indexWriter != null) {

Modified: lucene/dev/branches/lucene3312/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml Wed Aug 15 11:23:02 2012
@@ -231,6 +231,12 @@
     </processor>
   </updateRequestProcessorChain>
 
+  <updateRequestProcessorChain name="count">
+    <processor class="solr.CountFieldValuesUpdateProcessorFactory">
+      <str name="fieldName">count_field</str>
+    </processor>
+  </updateRequestProcessorChain>
+
   <updateRequestProcessorChain name="ignore-not-in-schema">
     <processor class="solr.IgnoreFieldUpdateProcessorFactory" />
   </updateRequestProcessorChain>
@@ -344,6 +350,20 @@
     </processor>
   </updateRequestProcessorChain>
 
+  <updateRequestProcessorChain name="clone-then-count">
+    <processor class="solr.CloneFieldUpdateProcessorFactory">
+      <str name="source">category</str>
+      <str name="dest">category_count</str>
+    </processor>
+    <processor class="solr.CountFieldValuesUpdateProcessorFactory">
+      <str name="fieldName">category_count</str>
+    </processor>
+    <processor class="solr.DefaultValueUpdateProcessorFactory">
+      <str name="fieldName">category_count</str>
+      <int name="value">0</int>
+    </processor>
+  </updateRequestProcessorChain>
+
   <updateRequestProcessorChain name="regex-replace">
     <processor class="solr.RegexReplaceProcessorFactory">
       <str name="fieldName">content</str>

Modified: lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java Wed Aug 15 11:23:02 2012
@@ -42,7 +42,7 @@ import org.slf4j.LoggerFactory;
 public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase {
   public static Logger log = LoggerFactory.getLogger(ChaosMonkeyNothingIsSafeTest.class);
   
-  private static final int BASE_RUN_LENGTH = 180000;
+  private static final int BASE_RUN_LENGTH = 45000;
 
   @BeforeClass
   public static void beforeSuperClass() {
@@ -71,8 +71,8 @@ public class ChaosMonkeyNothingIsSafeTes
   
   public ChaosMonkeyNothingIsSafeTest() {
     super();
-    sliceCount = 2;
-    shardCount = 6;
+    sliceCount = 3;
+    shardCount = 12;
   }
   
   @Override
@@ -105,6 +105,7 @@ public class ChaosMonkeyNothingIsSafeTes
         searchThread.start();
       }
       
+      // TODO: only do this randomly - if we don't do it, compare against control below
       FullThrottleStopableIndexingThread ftIndexThread = new FullThrottleStopableIndexingThread(
           clients, i * 50000, true);
       threads.add(ftIndexThread);
@@ -137,7 +138,7 @@ public class ChaosMonkeyNothingIsSafeTes
       Thread.sleep(2000);
       
       // wait until there are no recoveries...
-      waitForThingsToLevelOut(Math.round((runLength / 1000.0f / 5.0f)));
+      waitForThingsToLevelOut(Integer.MAX_VALUE);//Math.round((runLength / 1000.0f / 3.0f)));
       
       // make sure we again have leaders for each shard
       for (int j = 1; j < sliceCount; j++) {
@@ -151,6 +152,8 @@ public class ChaosMonkeyNothingIsSafeTes
       zkStateReader.updateClusterState(true);
       assertTrue(zkStateReader.getClusterState().getLiveNodes().size() > 0);
       
+      // we dont't current check vs control because the full throttle thread can
+      // have request fails
       checkShardConsistency(false, true);
       
       // ensure we have added more than 0 docs

Modified: lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java Wed Aug 15 11:23:02 2012
@@ -69,8 +69,8 @@ public class ChaosMonkeySafeLeaderTest e
   
   public ChaosMonkeySafeLeaderTest() {
     super();
-    sliceCount = atLeast(2);
-    shardCount = atLeast(sliceCount*2);
+    sliceCount = 3;//atLeast(2);
+    shardCount = 12;//atLeast(sliceCount*2);
   }
   
   @Override
@@ -114,7 +114,7 @@ public class ChaosMonkeySafeLeaderTest e
     
     // try and wait for any replications and what not to finish...
     
-    waitForThingsToLevelOut(Math.round((runLength / 1000.0f / 5.0f)));
+    waitForThingsToLevelOut(Integer.MAX_VALUE);//Math.round((runLength / 1000.0f / 3.0f)));
 
     checkShardConsistency(true, true);
     

Modified: lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/LeaderElectionTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/LeaderElectionTest.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/LeaderElectionTest.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/LeaderElectionTest.java Wed Aug 15 11:23:02 2012
@@ -124,9 +124,21 @@ public class LeaderElectionTest extends 
       try {
         setupOnConnect();
       } catch (InterruptedException e) {
+        log.error("setup failed", e);
+        
+        if (this.zkClient != null) {
+          this.zkClient.close();
+        }
+
         return;
       } catch (Throwable e) {
-        // e.printStackTrace();
+        log.error("setup failed", e);
+        
+        if (this.zkClient != null) {
+          this.zkClient.close();
+        }
+        
+        return;
       }
         
       while (!stop) {
@@ -221,76 +233,77 @@ public class LeaderElectionTest extends 
     
     for (int i = 0; i < 15; i++) {
       ClientThread thread = new ClientThread(i);
-      
       threads.add(thread);
     }
-    
-    for (Thread thread : threads) {
-      thread.start();
-    }
-    
-    
-    while(true) { //wait for election to complete
-      int doneCount = 0;
-      for (ClientThread thread : threads) {
-        if(thread.electionDone) {
-          doneCount++;
+    try {
+      for (Thread thread : threads) {
+        thread.start();
+      }
+      
+      while (true) { // wait for election to complete
+        int doneCount = 0;
+        for (ClientThread thread : threads) {
+          if (thread.electionDone) {
+            doneCount++;
+          }
         }
+        if (doneCount == 15) {
+          break;
+        }
+        Thread.sleep(100);
       }
-      if(doneCount==15) {
-        break;
+      
+      int leaderThread = getLeaderThread();
+      
+      // whoever the leader is, should be the n_0 seq
+      assertEquals(0, threads.get(leaderThread).seq);
+      
+      // kill n_0, 1, 3 and 4
+      ((ClientThread) seqToThread.get(0)).close();
+      
+      waitForLeader(threads, 1);
+      
+      leaderThread = getLeaderThread();
+      
+      // whoever the leader is, should be the n_1 seq
+      
+      assertEquals(1, threads.get(leaderThread).seq);
+      
+      ((ClientThread) seqToThread.get(4)).close();
+      ((ClientThread) seqToThread.get(1)).close();
+      ((ClientThread) seqToThread.get(3)).close();
+      
+      // whoever the leader is, should be the n_2 seq
+      
+      waitForLeader(threads, 2);
+      
+      leaderThread = getLeaderThread();
+      assertEquals(2, threads.get(leaderThread).seq);
+      
+      // kill n_5, 2, 6, 7, and 8
+      ((ClientThread) seqToThread.get(5)).close();
+      ((ClientThread) seqToThread.get(2)).close();
+      ((ClientThread) seqToThread.get(6)).close();
+      ((ClientThread) seqToThread.get(7)).close();
+      ((ClientThread) seqToThread.get(8)).close();
+      
+      waitForLeader(threads, 9);
+      leaderThread = getLeaderThread();
+      
+      // whoever the leader is, should be the n_9 seq
+      assertEquals(9, threads.get(leaderThread).seq);
+      
+    } finally {
+      // cleanup any threads still running
+      for (ClientThread thread : threads) {
+        thread.close();
+        thread.interrupt();
+        
+      }
+      
+      for (Thread thread : threads) {
+        thread.join();
       }
-      Thread.sleep(100);
-    }
-    
-    int leaderThread = getLeaderThread();
-    
-    // whoever the leader is, should be the n_0 seq
-    assertEquals(0, threads.get(leaderThread).seq);
-    
-    // kill n_0, 1, 3 and 4
-    ((ClientThread) seqToThread.get(0)).close();
-    
-    waitForLeader(threads, 1);
-    
-    leaderThread = getLeaderThread();
-    
-    // whoever the leader is, should be the n_1 seq
-    
-    assertEquals(1, threads.get(leaderThread).seq);
-    
-    ((ClientThread) seqToThread.get(4)).close();
-    ((ClientThread) seqToThread.get(1)).close();
-    ((ClientThread) seqToThread.get(3)).close();
-    
-    // whoever the leader is, should be the n_2 seq
-    
-    waitForLeader(threads, 2);
-    
-    leaderThread = getLeaderThread();
-    assertEquals(2, threads.get(leaderThread).seq);
-    
-    // kill n_5, 2, 6, 7, and 8
-    ((ClientThread) seqToThread.get(5)).close();
-    ((ClientThread) seqToThread.get(2)).close();
-    ((ClientThread) seqToThread.get(6)).close();
-    ((ClientThread) seqToThread.get(7)).close();
-    ((ClientThread) seqToThread.get(8)).close();
-    
-    waitForLeader(threads, 9);
-    leaderThread = getLeaderThread();
-    
-    // whoever the leader is, should be the n_9 seq
-    assertEquals(9, threads.get(leaderThread).seq);
-    
-    // cleanup any threads still running
-    for (ClientThread thread : threads) {
-      thread.close();
-      thread.interrupt();
-    }
-    
-    for (Thread thread : threads) {
-      thread.join();
     }
     
   }

Modified: lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java Wed Aug 15 11:23:02 2012
@@ -95,13 +95,9 @@ public class OverseerTest extends SolrTe
       }
     }
 
-    public void close(){
-      try {
-        deleteNode(ZkStateReader.LIVE_NODES_ZKNODE + "/" + nodeName);
-        zkClient.close();
-      } catch (InterruptedException e) {
-        //e.printStackTrace();
-      }
+    public void close() {
+      deleteNode(ZkStateReader.LIVE_NODES_ZKNODE + "/" + nodeName);
+      zkClient.close();
     }
     
     public void publishState(String coreName, String stateName, int numShards)

Modified: lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/search/TestDocSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/search/TestDocSet.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/search/TestDocSet.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/search/TestDocSet.java Wed Aug 15 11:23:02 2012
@@ -455,7 +455,7 @@ public class TestDocSet extends LuceneTe
   }
 
   public void doFilterTest(IndexReader reader) throws IOException {
-    IndexReaderContext topLevelContext = reader.getTopReaderContext();
+    IndexReaderContext topLevelContext = reader.getContext();
     OpenBitSet bs = getRandomSet(reader.maxDoc(), rand.nextInt(reader.maxDoc()+1));
     DocSet a = new BitDocSet(bs);
     DocSet b = getIntDocSet(bs);

Modified: lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/search/TestSort.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/search/TestSort.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/search/TestSort.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/search/TestSort.java Wed Aug 15 11:23:02 2012
@@ -198,7 +198,7 @@ public class TestSort extends SolrTestCa
       DirectoryReader reader = DirectoryReader.open(dir);
       IndexSearcher searcher = new IndexSearcher(reader);
       // System.out.println("segments="+searcher.getIndexReader().getSequentialSubReaders().length);
-      assertTrue(reader.getSequentialSubReaders().size() > 1);
+      assertTrue(reader.leaves().size() > 1);
 
       for (int i=0; i<qiter; i++) {
         Filter filt = new Filter() {

Modified: lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/update/processor/FieldMutatingUpdateProcessorTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/update/processor/FieldMutatingUpdateProcessorTest.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/update/processor/FieldMutatingUpdateProcessorTest.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/test/org/apache/solr/update/processor/FieldMutatingUpdateProcessorTest.java Wed Aug 15 11:23:02 2012
@@ -721,6 +721,58 @@ public class FieldMutatingUpdateProcesso
 
   } 
 
+  public void testCountValues() throws Exception {
+
+    SolrInputDocument d = null;
+
+    // trivial 
+    d = processAdd("count",       
+                   doc(f("id", "1111"),
+                       f("count_field", "aaa", "bbb", "ccc")));
+
+    assertNotNull(d);
+    assertEquals(3, d.getFieldValue("count_field"));
+
+    // edge case: no values to count, means no count 
+    // (use default if you want one)
+    d = processAdd("count",       
+                   doc(f("id", "1111")));
+
+    assertNotNull(d);
+    assertFalse(d.containsKey("count_field"));
+
+    // typical usecase: clone and count 
+    d = processAdd("clone-then-count",       
+                   doc(f("id", "1111"),
+                       f("category", "scifi", "war", "space"),
+                       f("editors", "John W. Campbell"),
+                       f("list_price", 1000)));
+    assertNotNull(d);
+    assertEquals(Arrays.asList("scifi", "war", "space"),
+                 d.getFieldValues("category"));
+    assertEquals(3,
+                 d.getFieldValue("category_count"));
+    assertEquals(Arrays.asList("John W. Campbell"),
+                 d.getFieldValues("editors"));
+    assertEquals(1000,d.getFieldValue("list_price"));
+
+    // typical usecase: clone and count demonstrating default
+    d = processAdd("clone-then-count",       
+                   doc(f("id", "1111"),
+                       f("editors", "Anonymous"),
+                       f("list_price", 1000)));
+    assertNotNull(d);
+    assertEquals(0,
+                 d.getFieldValue("category_count"));
+    assertEquals(Arrays.asList("Anonymous"),
+                 d.getFieldValues("editors"));
+    assertEquals(1000,d.getFieldValue("list_price"));
+
+    
+
+
+  } 
+
   public void testCloneCombinations() throws Exception {
 
     SolrInputDocument d = null;

Modified: lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java (original)
+++ lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java Wed Aug 15 11:23:02 2012
@@ -71,7 +71,9 @@ class ConnectionManager implements Watch
           + " path:" + event.getPath() + " type:" + event.getType());
     }
     
-    checkClosed();
+    if (isClosed) {
+      return;
+    }
 
     state = event.getState();
     if (state == KeeperState.SyncConnected) {
@@ -85,18 +87,32 @@ class ConnectionManager implements Watch
         connectionStrategy.reconnect(zkServerAddress, zkClientTimeout, this,
             new ZkClientConnectionStrategy.ZkUpdate() {
               @Override
-              public void update(SolrZooKeeper keeper) throws TimeoutException {
+              public void update(SolrZooKeeper keeper) {
+                // if keeper does not replace oldKeeper we must be sure to close it
                 synchronized (connectionStrategy) {
-                  checkClosed();
                   try {
                     waitForConnected(SolrZkClient.DEFAULT_CLIENT_CONNECT_TIMEOUT);
-                    checkClosed();
+                  } catch (InterruptedException e1) {
+                    closeKeeper(keeper);
+                    Thread.currentThread().interrupt();
+                    throw new RuntimeException("Giving up on connecting - we were interrupted", e1);
+                  } catch (Exception e1) {
+                    closeKeeper(keeper);
+                    throw new RuntimeException(e1);
+                  }
+                  
+                  try {
                     client.updateKeeper(keeper);
                   } catch (InterruptedException e) {
+                    closeKeeper(keeper);
+                    Thread.currentThread().interrupt();
                     // we must have been asked to stop
-                    throw new RuntimeException("Giving up on connecting - we were interrupted");
+                    throw new RuntimeException(e);
+                  } catch(Throwable t) {
+                    closeKeeper(keeper);
+                    throw new RuntimeException(t);
                   }
-                  checkClosed();
+      
                   if (onReconnect != null) {
                     onReconnect.command();
                   }
@@ -137,23 +153,18 @@ class ConnectionManager implements Watch
   public synchronized void waitForConnected(long waitForConnection)
       throws InterruptedException, TimeoutException {
     long expire = System.currentTimeMillis() + waitForConnection;
-    long left = waitForConnection;
+    long left = 1;
     while (!connected && left > 0) {
-      wait(left);
-      checkClosed();
+      if (isClosed) {
+        break;
+      }
+      wait(500);
       left = expire - System.currentTimeMillis();
     }
     if (!connected) {
       throw new TimeoutException("Could not connect to ZooKeeper " + zkServerAddress + " within " + waitForConnection + " ms");
     }
   }
-  
-  private synchronized void checkClosed() {
-    if (isClosed) {
-      log.info("Not acting because I am closed");
-      return;
-    }
-  }
 
   public synchronized void waitForDisconnected(long timeout)
       throws InterruptedException, TimeoutException {
@@ -167,4 +178,16 @@ class ConnectionManager implements Watch
       throw new TimeoutException("Did not disconnect");
     }
   }
+
+  private void closeKeeper(SolrZooKeeper keeper) {
+    try {
+      keeper.close();
+    } catch (InterruptedException e) {
+      // Restore the interrupted status
+      Thread.currentThread().interrupt();
+      log.error("", e);
+      throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
+          "", e);
+    }
+  }
 }

Modified: lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java (original)
+++ lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java Wed Aug 15 11:23:02 2012
@@ -82,11 +82,11 @@ public class SolrZkClient {
    * @throws TimeoutException
    * @throws IOException
    */
-  public SolrZkClient(String zkServerAddress, int zkClientTimeout) throws InterruptedException, TimeoutException, IOException {
+  public SolrZkClient(String zkServerAddress, int zkClientTimeout) {
     this(zkServerAddress, zkClientTimeout, new DefaultConnectionStrategy(), null);
   }
   
-  public SolrZkClient(String zkServerAddress, int zkClientTimeout, int zkClientConnectTimeout, OnReconnect onReonnect) throws InterruptedException, TimeoutException, IOException {
+  public SolrZkClient(String zkServerAddress, int zkClientTimeout, int zkClientConnectTimeout, OnReconnect onReonnect) {
     this(zkServerAddress, zkClientTimeout, new DefaultConnectionStrategy(), onReonnect, zkClientConnectTimeout);
   }
 
@@ -100,8 +100,7 @@ public class SolrZkClient {
    * @throws IOException
    */
   public SolrZkClient(String zkServerAddress, int zkClientTimeout,
-      ZkClientConnectionStrategy strat, final OnReconnect onReconnect) throws InterruptedException,
-      TimeoutException, IOException {
+      ZkClientConnectionStrategy strat, final OnReconnect onReconnect) {
     this(zkServerAddress, zkClientTimeout, strat, onReconnect, DEFAULT_CLIENT_CONNECT_TIMEOUT);
   }
 
@@ -116,30 +115,46 @@ public class SolrZkClient {
    * @throws IOException
    */
   public SolrZkClient(String zkServerAddress, int zkClientTimeout,
-      ZkClientConnectionStrategy strat, final OnReconnect onReconnect, int clientConnectTimeout) throws InterruptedException,
-      TimeoutException, IOException {
+      ZkClientConnectionStrategy strat, final OnReconnect onReconnect, int clientConnectTimeout) {
     connManager = new ConnectionManager("ZooKeeperConnection Watcher:"
         + zkServerAddress, this, zkServerAddress, zkClientTimeout, strat, onReconnect);
-    strat.connect(zkServerAddress, zkClientTimeout, connManager,
-        new ZkUpdate() {
-          @Override
-          public void update(SolrZooKeeper zooKeeper) {
-            SolrZooKeeper oldKeeper = keeper;
-            keeper = zooKeeper;
-            if (oldKeeper != null) {
+    try {
+      strat.connect(zkServerAddress, zkClientTimeout, connManager,
+          new ZkUpdate() {
+            @Override
+            public void update(SolrZooKeeper zooKeeper) {
+              SolrZooKeeper oldKeeper = keeper;
+              keeper = zooKeeper;
               try {
-                oldKeeper.close();
-              } catch (InterruptedException e) {
-                // Restore the interrupted status
-                Thread.currentThread().interrupt();
-                log.error("", e);
-                throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
-                    "", e);
+                closeKeeper(oldKeeper);
+              } finally {
+                if (isClosed) {
+                  // we may have been closed
+                  closeKeeper(SolrZkClient.this.keeper);
+                }
               }
             }
-          }
-        });
-    connManager.waitForConnected(clientConnectTimeout);
+          });
+    } catch (IOException e) {
+      connManager.close();
+      throw new RuntimeException();
+    } catch (InterruptedException e) {
+      connManager.close();
+      throw new RuntimeException();
+    } catch (TimeoutException e) {
+      connManager.close();
+      throw new RuntimeException();
+    }
+    try {
+      connManager.waitForConnected(clientConnectTimeout);
+    } catch (InterruptedException e) {
+      Thread.currentThread().interrupt();
+      connManager.close();
+      throw new RuntimeException();
+    } catch (TimeoutException e) {
+      connManager.close();
+      throw new RuntimeException();
+    }
     numOpens.incrementAndGet();
   }
 
@@ -651,11 +666,11 @@ public class SolrZkClient {
   /**
    * @throws InterruptedException
    */
-  public void close() throws InterruptedException {
+  public void close() {
     if (isClosed) return; // it's okay if we over close - same as solrcore
     isClosed = true;
     try {
-      keeper.close();
+      closeKeeper(keeper);
     } finally {
       connManager.close();
     }
@@ -678,11 +693,27 @@ public class SolrZkClient {
    if (oldKeeper != null) {
      oldKeeper.close();
    }
+   // we might have been closed already
+   if (isClosed) this.keeper.close();
   }
   
   public SolrZooKeeper getSolrZooKeeper() {
     return keeper;
   }
+  
+  private void closeKeeper(SolrZooKeeper keeper) {
+    if (keeper != null) {
+      try {
+        keeper.close();
+      } catch (InterruptedException e) {
+        // Restore the interrupted status
+        Thread.currentThread().interrupt();
+        log.error("", e);
+        throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "",
+            e);
+      }
+    }
+  }
 
   // yeah, it's recursive :(
   public void clean(String path) throws InterruptedException, KeeperException {

Modified: lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java (original)
+++ lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java Wed Aug 15 11:23:02 2012
@@ -73,9 +73,9 @@ public class ZkCmdExecutor {
           Thread.currentThread().interrupt();
           throw new InterruptedException();
         }
-        if (Thread.currentThread() instanceof SafeStopThread) {
-          if (((SafeStopThread) Thread.currentThread()).isClosed()) {
-            throw new RuntimeException("Interrupted");
+        if (Thread.currentThread() instanceof ClosableThread) {
+          if (((ClosableThread) Thread.currentThread()).isClosed()) {
+            throw exception;
           }
         }
         retryDelay(i);

Modified: lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java (original)
+++ lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java Wed Aug 15 11:23:02 2012
@@ -373,15 +373,7 @@ public class ZkStateReader {
 
   public void close() {
     if (closeClient) {
-      try {
-        zkClient.close();
-      } catch (InterruptedException e) {
-        // Restore the interrupted status
-        Thread.currentThread().interrupt();
-        log.error("", e);
-        throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "",
-            e);
-      }
+      zkClient.close();
     }
   }
   

Modified: lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/zookeeper/SolrZooKeeper.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/zookeeper/SolrZooKeeper.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/zookeeper/SolrZooKeeper.java (original)
+++ lucene/dev/branches/lucene3312/solr/solrj/src/java/org/apache/zookeeper/SolrZooKeeper.java Wed Aug 15 11:23:02 2012
@@ -19,16 +19,23 @@ package org.apache.zookeeper;
 
 import java.io.IOException;
 import java.nio.channels.SocketChannel;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 // we use this class to expose nasty stuff for tests
 public class SolrZooKeeper extends ZooKeeper {
   List<Thread> spawnedThreads = new CopyOnWriteArrayList<Thread>();
+  
+  // for test debug
+  //static Map<SolrZooKeeper,Exception> clients = new ConcurrentHashMap<SolrZooKeeper,Exception>();
 
   public SolrZooKeeper(String connectString, int sessionTimeout,
       Watcher watcher) throws IOException {
     super(connectString, sessionTimeout, watcher);
+    //clients.put(this, new RuntimeException());
   }
   
   public ClientCnxn getConnection() {
@@ -64,9 +71,20 @@ public class SolrZooKeeper extends ZooKe
 
   @Override
   public synchronized void close() throws InterruptedException {
+    //clients.remove(this);
     for (Thread t : spawnedThreads) {
       t.interrupt();
     }
     super.close();
   }
+  
+//  public static void assertCloses() {
+//    if (clients.size() > 0) {
+//      Iterator<Exception> stacktraces = clients.values().iterator();
+//      Exception cause = null;
+//      cause = stacktraces.next();
+//      throw new RuntimeException("Found a bad one!", cause);
+//    }
+//  }
+  
 }

Modified: lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/AbstractDistribZkTestBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/AbstractDistribZkTestBase.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/AbstractDistribZkTestBase.java (original)
+++ lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/AbstractDistribZkTestBase.java Wed Aug 15 11:23:02 2012
@@ -203,6 +203,8 @@ public abstract class AbstractDistribZkT
     System.clearProperty("solr.test.sys.prop2");
     resetExceptionIgnores();
     super.tearDown();
+    
+    JettySolrRunner.assertStoppedJetties();
   }
   
   protected void printLayout() throws Exception {

Modified: lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java (original)
+++ lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java Wed Aug 15 11:23:02 2012
@@ -31,9 +31,7 @@ import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.http.params.CoreConnectionPNames;
-import org.apache.lucene.util.LuceneTestCase.BadApple;
 import org.apache.lucene.util.LuceneTestCase.Slow;
-import org.apache.lucene.util.LuceneTestCase.AwaitsFix;
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.SolrServer;
 import org.apache.solr.client.solrj.SolrServerException;
@@ -42,7 +40,6 @@ import org.apache.solr.client.solrj.impl
 import org.apache.solr.client.solrj.impl.HttpSolrServer;
 import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
-import org.apache.solr.cloud.ChaosMonkey;
 import org.apache.solr.common.SolrDocument;
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.SolrException;
@@ -65,8 +62,6 @@ import org.slf4j.LoggerFactory;
  * what we test now - the default update chain
  */
 @Slow
-@BadApple
-@AwaitsFix(bugUrl = "SOLR-3727 (leak threads)") 
 public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTestBase {
   static Logger log = LoggerFactory.getLogger(AbstractFullDistribZkTestBase.class);
   

Modified: lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java (original)
+++ lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java Wed Aug 15 11:23:02 2012
@@ -68,6 +68,8 @@ public class ChaosMonkey {
   private boolean aggressivelyKillLeaders;
   private Map<String,CloudJettyRunner> shardToLeaderJetty;
   private long startTime;
+
+  private Thread monkeyThread;
   
   public ChaosMonkey(ZkTestServer zkServer, ZkStateReader zkStateReader,
       String collection, Map<String,List<CloudJettyRunner>> shardToJetty,
@@ -355,7 +357,7 @@ public class ChaosMonkey {
     // TODO: when kill leaders is on, lets kill a higher percentage of leaders
     
     stop = false;
-    new Thread() {
+    monkeyThread = new Thread() {
       private List<CloudJettyRunner> deadPool = new ArrayList<CloudJettyRunner>();
 
       @Override
@@ -413,7 +415,8 @@ public class ChaosMonkey {
             + ". I also expired " + expires.get() + " and caused " + connloss
             + " connection losses");
       }
-    }.start();
+    };
+    monkeyThread.start();
   }
   
   public static void monkeyLog(String msg) {
@@ -422,6 +425,11 @@ public class ChaosMonkey {
   
   public void stopTheMonkey() {
     stop = true;
+    try {
+      monkeyThread.join();
+    } catch (InterruptedException e) {
+      Thread.currentThread().interrupt();
+    }
   }
 
   public int getStarts() {
@@ -435,17 +443,18 @@ public class ChaosMonkey {
   public static boolean start(JettySolrRunner jetty) throws Exception {
     try {
       jetty.start();
-    } catch (BindException e) {
+    } catch (Exception e) {
       jetty.stop();
       Thread.sleep(2000);
       try {
         jetty.start();
-      } catch (BindException e2) {
+      } catch (Exception e2) {
         jetty.stop();
         Thread.sleep(5000);
         try {
           jetty.start();
-        } catch (BindException e3) {
+        } catch (Exception e3) {
+          log.error("", e3);
           // we coud not get the port
           jetty.stop();
           return false;

Modified: lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/ZkTestServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/ZkTestServer.java?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/ZkTestServer.java (original)
+++ lucene/dev/branches/lucene3312/solr/test-framework/src/java/org/apache/solr/cloud/ZkTestServer.java Wed Aug 15 11:23:02 2012
@@ -240,6 +240,7 @@ public class ZkTestServer {
       }
       cnt++;
     }
+    log.info("start zk server on port:" + port);
   }
 
   @SuppressWarnings("deprecation")

Modified: lucene/dev/branches/lucene3312/solr/testlogging.properties
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/testlogging.properties?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/testlogging.properties (original)
+++ lucene/dev/branches/lucene3312/solr/testlogging.properties Wed Aug 15 11:23:02 2012
@@ -11,6 +11,8 @@ java.util.logging.ConsoleHandler.formatt
 #org.apache.solr.update.processor.DistributedUpdateProcessor=FINEST
 #org.apache.solr.update.PeerSync.level=FINEST
 #org.apache.solr.cloud.RecoveryStrategy.level=FINEST
+#org.apache.solr.cloud.SyncStrategy.level=FINEST
+#org.apache.solr.update.DefaultSolrCoreState.level=FINEST
 #org.apache.solr.update.UpdateLog.level=FINE
 #org.apache.solr.update.TransactionLog.level=FINEST
 

Modified: lucene/dev/branches/lucene3312/solr/webapp/web/js/scripts/schema-browser.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/webapp/web/js/scripts/schema-browser.js?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/webapp/web/js/scripts/schema-browser.js (original)
+++ lucene/dev/branches/lucene3312/solr/webapp/web/js/scripts/schema-browser.js Wed Aug 15 11:23:02 2012
@@ -871,7 +871,7 @@ sammy.get
         var pig_element = $( 'dt.position-increment-gap', options_element );
         if( is_f && schema_browser_data.fields[field] && schema_browser_data.fields[field].positionIncrementGap )
         {
-          $( 'dt.position-increment-gap', options_element )
+          $( 'dd.position-increment-gap', options_element )
             .remove();
 
           pig_element
@@ -883,7 +883,18 @@ sammy.get
           $( '.position-increment-gap', options_element )
             .hide();
         }
-                
+
+        var similarity_element = $( 'dt.similarity', options_element );
+        if ( is_t && schema_browser_data.types[field] && schema_browser_data.types[field].similarity ) {
+            var similarity = schema_browser_data.types[field].similarity
+            $( 'dd.similarity', options_element ).remove();
+            similarity_element
+                .show()
+                .after(['<dd class="similarity">', similarity.details.esc(), ' (', similarity.className.esc(), ') </dd>'].join(""));
+        } else {
+            $( '.similarity', options_element ).hide();
+        }
+
         var analyzer_element = $( '.analyzer', data_element );
         var analyzer_data = null;
 
@@ -1190,4 +1201,4 @@ sammy.get
       trigger_params
     );
   }
-);
\ No newline at end of file
+);

Modified: lucene/dev/branches/lucene3312/solr/webapp/web/tpl/schema-browser.html
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/webapp/web/tpl/schema-browser.html?rev=1373337&r1=1373336&r2=1373337&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/webapp/web/tpl/schema-browser.html (original)
+++ lucene/dev/branches/lucene3312/solr/webapp/web/tpl/schema-browser.html Wed Aug 15 11:23:02 2012
@@ -35,6 +35,8 @@ limitations under the License.
 
             <dt class="field-type">Field-Type:</dt>
 
+            <dt class="similarity">Similarity:</dt>
+
             <dt class="properties">Properties:</dt>
 
             <dt class="schema">Schema:</dt>