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/01/25 22:56:51 UTC

svn commit: r1235969 [4/9] - in /lucene/dev/branches/lucene2858: ./ dev-tools/eclipse/ dev-tools/idea/lucene/contrib/ dev-tools/maven/ lucene/ lucene/contrib/ lucene/contrib/sandbox/src/test/org/apache/lucene/sandbox/queries/regex/ lucene/src/java/org/...

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java Wed Jan 25 21:56:44 2012
@@ -31,6 +31,7 @@ import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.CharsRef;
 import org.apache.lucene.util.ReaderUtil;
 import org.apache.lucene.util.UnicodeUtil;
+import org.apache.solr.client.solrj.util.ClientUtils;
 import org.apache.solr.cloud.CloudDescriptor;
 import org.apache.solr.cloud.ZkController;
 import org.apache.solr.common.SolrDocument;
@@ -38,6 +39,7 @@ import org.apache.solr.common.SolrDocume
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.cloud.CloudState;
 import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.ZkCoreNodeProps;
 import org.apache.solr.common.cloud.ZkNodeProps;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.params.*;
@@ -206,7 +208,8 @@ public class QueryComponent extends Sear
     SolrQueryRequest req = rb.req;
     SolrParams params = req.getParams();
 
-    rb.isDistrib = params.getBool("distrib",false);
+    rb.isDistrib = params.getBool("distrib", req.getCore().getCoreDescriptor()
+        .getCoreContainer().isZooKeeperAware());
     String shards = params.get(ShardParams.SHARDS);
 
     // for back compat, a shards param with URLs like localhost:8983/solr will mean that this
@@ -244,11 +247,36 @@ public class QueryComponent extends Sear
 
         cloudState =  zkController.getCloudState();
 
-        // TODO: check "collection" for which collection(s) to search.. but for now, just default
-        // to the collection for this core.
         // This can be more efficient... we only record the name, even though we have the
         // shard info we need in the next step of mapping slice->shards
-        slices = cloudState.getSlices(cloudDescriptor.getCollectionName());
+        
+        // Stores the comma-separated list of specified collections.
+        // Eg: "collection1,collection2,collection3"
+        String collections = params.get("collection");
+        if (collections != null) {
+          // If there were one or more collections specified in the query, split
+          // each parameter and store as a seperate member of a List.
+          List<String> collectionList = StrUtils.splitSmart(collections, ",",
+              true);
+          
+          // First create an empty HashMap to add the slice info to.
+          slices = new HashMap<String,Slice>();
+          
+          // In turn, retrieve the slices that cover each collection from the
+          // cloud state and add them to the Map 'slices'.
+          for (int i = 0; i < collectionList.size(); i++) {
+            String collection = collectionList.get(i);
+            ClientUtils.appendMap(collection, slices, cloudState.getSlices(collection));
+          }
+        } else {
+          // If no collections were specified, default to the collection for
+          // this core.
+          slices = cloudState.getSlices(cloudDescriptor.getCollectionName());
+        }
+        
+        // Store the logical slices in the ResponseBuilder and create a new
+        // String array to hold the physical shards (which will be mapped
+        // later).
         rb.slices = slices.keySet().toArray(new String[slices.size()]);
         rb.shards = new String[rb.slices.length];
 
@@ -289,14 +317,16 @@ public class QueryComponent extends Sear
             StringBuilder sliceShardsStr = new StringBuilder();
             boolean first = true;
             for (ZkNodeProps nodeProps : sliceShards.values()) {
-              if (!liveNodes.contains(nodeProps.get(ZkStateReader.NODE_NAME)))
-                continue;
+              ZkCoreNodeProps coreNodeProps = new ZkCoreNodeProps(nodeProps);
+              if (!liveNodes.contains(coreNodeProps.getNodeName())
+                  || !coreNodeProps.getState().equals(
+                      ZkStateReader.ACTIVE)) continue;
               if (first) {
                 first = false;
               } else {
                 sliceShardsStr.append('|');
               }
-              String url = nodeProps.get("url");
+              String url = coreNodeProps.getCoreUrl();
               if (url.startsWith("http://"))
                 url = url.substring(7);
               sliceShardsStr.append(url);

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java Wed Jan 25 21:56:44 2012
@@ -38,8 +38,11 @@ import org.apache.solr.schema.SchemaFiel
 import org.apache.solr.search.ReturnFields;
 import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.update.DocumentBuilder;
+import org.apache.solr.update.PeerSync;
 import org.apache.solr.update.UpdateLog;
 import org.apache.solr.util.RefCounted;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.xml.transform.Transformer;
 import java.io.IOException;
@@ -47,14 +50,10 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * TODO!
- * 
- *
- * @since solr 1.3
- */
+
 public class RealTimeGetComponent extends SearchComponent
 {
+  public static Logger log = LoggerFactory.getLogger(UpdateLog.class);
   public static final String COMPONENT_NAME = "get";
 
   @Override
@@ -76,6 +75,18 @@ public class RealTimeGetComponent extend
       return;
     }
 
+    String val = params.get("getVersions");
+    if (val != null) {
+      processGetVersions(rb);
+      return;
+    }
+
+    val = params.get("getUpdates");
+    if (val != null) {
+      processGetUpdates(rb);
+      return;
+    }
+
     String id[] = params.getParams("id");
     String ids[] = params.getParams("ids");
 
@@ -142,7 +153,7 @@ public class RealTimeGetComponent extend
 
        // didn't find it in the update log, so it should be in the newest searcher opened
        if (searcher == null) {
-         searcherHolder =  req.getCore().getNewestSearcher(false);
+         searcherHolder = req.getCore().getRealtimeSearcher();
          searcher = searcherHolder.get();
        }
 
@@ -247,4 +258,112 @@ public class RealTimeGetComponent extend
   public URL[] getDocs() {
     return null;
   }
+
+
+
+  ///////////////////////////////////////////////////////////////////////////////////
+  // Returns last versions added to index
+  ///////////////////////////////////////////////////////////////////////////////////
+
+
+  public void processGetVersions(ResponseBuilder rb) throws IOException
+  {
+    SolrQueryRequest req = rb.req;
+    SolrQueryResponse rsp = rb.rsp;
+    SolrParams params = req.getParams();
+
+    if (!params.getBool(COMPONENT_NAME, true)) {
+      return;
+    }
+
+    int nVersions = params.getInt("getVersions", -1);
+    if (nVersions == -1) return;
+
+    String sync = params.get("sync");
+    if (sync != null) {
+      processSync(rb, nVersions, sync);
+      return;
+    }
+
+    UpdateLog ulog = req.getCore().getUpdateHandler().getUpdateLog();
+    if (ulog == null) return;
+
+    UpdateLog.RecentUpdates recentUpdates = ulog.getRecentUpdates();
+    try {
+      rb.rsp.add("versions", recentUpdates.getVersions(nVersions));
+    } finally {
+      recentUpdates.close();  // cache this somehow?
+    }
+  }
+
+  
+  public void processSync(ResponseBuilder rb, int nVersions, String sync) {
+    List<String> replicas = StrUtils.splitSmart(sync, ",", true);
+    
+    
+    PeerSync peerSync = new PeerSync(rb.req.getCore(), replicas, nVersions);
+    boolean success = peerSync.sync();
+    
+    // TODO: more complex response?
+    rb.rsp.add("sync", success);
+  }
+  
+
+  public void processGetUpdates(ResponseBuilder rb) throws IOException
+  {
+    SolrQueryRequest req = rb.req;
+    SolrQueryResponse rsp = rb.rsp;
+    SolrParams params = req.getParams();
+
+    if (!params.getBool(COMPONENT_NAME, true)) {
+      return;
+    }
+
+    String versionsStr = params.get("getUpdates");
+    if (versionsStr == null) return;
+
+    UpdateLog ulog = req.getCore().getUpdateHandler().getUpdateLog();
+    if (ulog == null) return;
+
+    List<String> versions = StrUtils.splitSmart(versionsStr, ",", true);
+
+    // TODO: get this from cache instead of rebuilding?
+    UpdateLog.RecentUpdates recentUpdates = ulog.getRecentUpdates();
+
+    List<Object> updates = new ArrayList<Object>(versions.size());
+
+    long minVersion = Long.MAX_VALUE;
+    
+    try {
+      for (String versionStr : versions) {
+        long version = Long.parseLong(versionStr);
+        try {
+          Object o = recentUpdates.lookup(version);
+          if (o == null) continue;
+
+          if (version > 0) {
+            minVersion = Math.min(minVersion, version);
+          }
+          
+          // TODO: do any kind of validation here?
+          updates.add(o);
+
+        } catch (SolrException e) {
+          log.warn("Exception reading log for updates", e);
+        } catch (ClassCastException e) {
+          log.warn("Exception reading log for updates", e);
+        }
+      }
+
+      // Must return all delete-by-query commands that occur after the first add requested
+      // since they may apply.
+      updates.addAll( recentUpdates.getDeleteByQuery(minVersion));
+
+      rb.rsp.add("updates", updates);
+
+    } finally {
+      recentUpdates.close();  // cache this somehow?
+    }
+  }
+
 }

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java Wed Jan 25 21:56:44 2012
@@ -23,6 +23,7 @@ import org.apache.solr.common.params.Com
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.ShardParams;
 import org.apache.solr.common.util.RTimer;
+import org.apache.solr.core.CloseHook;
 import org.apache.solr.core.PluginInfo;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.handler.RequestHandlerBase;
@@ -133,11 +134,19 @@ public class SearchHandler extends Reque
       log.info("Adding  debug component:" + dbgCmp);
     }
     if(shfInfo ==null) {
-      Map m = new HashMap();
-      m.put("class",HttpShardHandlerFactory.class.getName());
-      shfInfo = new PluginInfo("shardHandlerFactory", m,null,Collections.<PluginInfo>emptyList());
+      shardHandlerFactory = core.getCoreDescriptor().getCoreContainer().getShardHandlerFactory();
+    } else {
+      shardHandlerFactory = core.createInitInstance(shfInfo, ShardHandlerFactory.class, null, null);
     }
-    shardHandlerFactory = core.createInitInstance(shfInfo, ShardHandlerFactory.class, null, null);
+    core.addCloseHook(new CloseHook() {
+      @Override
+      public void preClose(SolrCore core) {
+        shardHandlerFactory.close();
+      }
+      @Override
+      public void postClose(SolrCore core) {
+      }
+    });
   }
 
   public List<SearchComponent> getComponents() {
@@ -247,7 +256,7 @@ public class SearchHandler extends Reque
             for (String shard : sreq.actualShards) {
               ModifiableSolrParams params = new ModifiableSolrParams(sreq.params);
               params.remove(ShardParams.SHARDS);      // not a top-level request
-              params.remove("distrib");               // not a top-level request
+              params.set("distrib", "false");               // not a top-level request
               params.remove("indent");
               params.remove(CommonParams.HEADER_ECHO_PARAMS);
               params.set(ShardParams.IS_SHARD, true);  // a sub (shard) request

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/ShardHandlerFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/ShardHandlerFactory.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/ShardHandlerFactory.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/handler/component/ShardHandlerFactory.java Wed Jan 25 21:56:44 2012
@@ -20,4 +20,6 @@ package org.apache.solr.handler.componen
 public abstract class ShardHandlerFactory {
 
   public abstract ShardHandler getShardHandler();
+
+  public abstract void close();
 }

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/request/SimpleFacets.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/request/SimpleFacets.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/request/SimpleFacets.java Wed Jan 25 21:56:44 2012
@@ -39,6 +39,7 @@ import org.apache.solr.schema.*;
 import org.apache.solr.search.*;
 import org.apache.solr.util.BoundedTreeSet;
 import org.apache.solr.util.DateMathParser;
+import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.apache.solr.handler.component.ResponseBuilder;
 import org.apache.solr.util.LongPriorityQueue;
 
@@ -327,6 +328,7 @@ public class SimpleFacets {
           Integer.MAX_VALUE,
           10, TimeUnit.SECONDS, // terminate idle threads after 10 sec
           new SynchronousQueue<Runnable>()  // directly hand off tasks
+          , new DefaultSolrThreadFactory("facetExectutor")
   );
   
   /**

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/search/FunctionRangeQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/search/FunctionRangeQParserPlugin.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/search/FunctionRangeQParserPlugin.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/search/FunctionRangeQParserPlugin.java Wed Jan 25 21:56:44 2012
@@ -80,43 +80,3 @@ public class FunctionRangeQParserPlugin 
 
 }
 
-// This class works as either a normal constant score query, or as a PostFilter using a collector
-class FunctionRangeQuery extends SolrConstantScoreQuery implements PostFilter {
-  final ValueSourceRangeFilter rangeFilt;
-
-  public FunctionRangeQuery(ValueSourceRangeFilter filter) {
-    super(filter);
-    this.rangeFilt = filter;
-  }
-
-  @Override
-  public DelegatingCollector getFilterCollector(IndexSearcher searcher) {
-    Map fcontext = ValueSource.newContext(searcher);
-    return new FunctionRangeCollector(fcontext);
-  }
-
-  class FunctionRangeCollector extends DelegatingCollector {
-    final Map fcontext;
-    ValueSourceScorer scorer;
-    int maxdoc;
-
-    public FunctionRangeCollector(Map fcontext) {
-      this.fcontext = fcontext;
-    }
-
-    @Override
-    public void collect(int doc) throws IOException {
-      if (doc<maxdoc && scorer.matches(doc)) {
-        delegate.collect(doc);
-      }
-    }
-
-    @Override
-    public void setNextReader(IndexReader.AtomicReaderContext context) throws IOException {
-      maxdoc = context.reader.maxDoc();
-      FunctionValues dv = rangeFilt.getValueSource().getValues(fcontext, context);
-      scorer = dv.getRangeScorer(context.reader, rangeFilt.getLowerVal(), rangeFilt.getUpperVal(), rangeFilt.isIncludeLower(), rangeFilt.isIncludeUpper());
-      super.setNextReader(context);
-    }
-  }
-}

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java Wed Jan 25 21:56:44 2012
@@ -108,7 +108,7 @@ public class SolrIndexSearcher extends I
   private final Collection<String> fieldNames;
   private Collection<String> storedHighlightFieldNames;
   private DirectoryFactory directoryFactory;
-  
+
   public SolrIndexSearcher(SolrCore core, String path, IndexSchema schema, SolrIndexConfig config, String name, boolean enableCache, DirectoryFactory directoryFactory) throws IOException {
     // we don't need to reserve the directory because we get it from the factory
     this(core, schema,name, core.getIndexReaderFactory().newReader(directoryFactory.get(path, config.lockType)), true, enableCache, false, directoryFactory);
@@ -133,6 +133,8 @@ public class SolrIndexSearcher extends I
     if (dir instanceof FSDirectory) {
       FSDirectory fsDirectory = (FSDirectory) dir;
       indexDir = fsDirectory.getDirectory().getAbsolutePath();
+    } else {
+      log.warn("WARNING: Directory impl does not support setting indexDir: " + dir.getClass().getName());
     }
 
     this.closeReader = closeReader;
@@ -569,6 +571,37 @@ public class SolrIndexSearcher extends I
     return id == DocIdSetIterator.NO_MORE_DOCS ? -1 : id;
   }
 
+  /** lookup the docid by the unique key field, and return the id *within* the leaf reader in the low 32 bits, and the index of the leaf reader in the high 32 bits.
+   * -1 is returned if not found.
+   * @lucene.internal
+   */
+  public long lookupId(BytesRef idBytes) throws IOException {
+    String field = schema.getUniqueKeyField().getName();
+    final AtomicReaderContext[] leaves = leafContexts;
+
+
+    for (int i=0; i<leaves.length; i++) {
+      final AtomicReaderContext leaf = leaves[i];
+      final IndexReader reader = leaf.reader;
+
+      final Fields fields = reader.fields();
+      if (fields == null) continue;
+
+      final Bits liveDocs = reader.getLiveDocs();
+      
+      final DocsEnum docs = reader.termDocsEnum(liveDocs, field, idBytes, false);
+
+      if (docs == null) continue;
+      int id = docs.nextDoc();
+      if (id == DocIdSetIterator.NO_MORE_DOCS) continue;
+      assert docs.nextDoc() == DocIdSetIterator.NO_MORE_DOCS;
+
+      return (((long)i) << 32) | id;
+    }
+
+    return -1;
+  }
+
 
   /**
    * Compute and cache the DocSet that matches a query.

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java Wed Jan 25 21:56:44 2012
@@ -62,10 +62,10 @@ public class SolrDispatchFilter implemen
 {
   final Logger log = LoggerFactory.getLogger(SolrDispatchFilter.class);
 
-  protected CoreContainer cores;
+  protected volatile CoreContainer cores;
+
   protected String pathPrefix = null; // strip this from the beginning of a path
   protected String abortErrorMessage = null;
-  protected String solrConfigFilename = null;
   protected final Map<SolrConfig, SolrRequestParsers> parsers = new WeakHashMap<SolrConfig, SolrRequestParsers>();
   protected final SolrRequestParsers adminRequestParser;
   
@@ -100,6 +100,10 @@ public class SolrDispatchFilter implemen
 
     log.info("SolrDispatchFilter.init() done");
   }
+  
+  public CoreContainer getCores() {
+    return cores;
+  }
 
   /** Method to override to change how CoreContainer initialization is performed. */
   protected CoreContainer.Initializer createInitializer() {
@@ -118,7 +122,13 @@ public class SolrDispatchFilter implemen
       ((HttpServletResponse)response).sendError( 500, abortErrorMessage );
       return;
     }
-
+    
+    if (this.cores == null) {
+      ((HttpServletResponse)response).sendError( 403, "Server is shutting down" );
+      return;
+    }
+    CoreContainer cores = this.cores;
+    
     if( request instanceof HttpServletRequest) {
       HttpServletRequest req = (HttpServletRequest)request;
       HttpServletResponse resp = (HttpServletResponse)response;

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java Wed Jan 25 21:56:44 2012
@@ -45,13 +45,20 @@ public class AddUpdateCommand extends Up
    public int commitWithin = -1;
    
    public AddUpdateCommand(SolrQueryRequest req) {
-     super("add", req);
+     super(req);
    }
 
+  @Override
+  public String name() {
+    return "add";
+  }
+
    /** Reset state to reuse this object with a different document in the same request */
    public void clear() {
      solrDoc = null;
      indexedId = null;
+     updateTerm = null;
+     version = 0;
    }
 
    public SolrInputDocument getSolrInputDocument() {
@@ -91,6 +98,10 @@ public class AddUpdateCommand extends Up
      return indexedId;
    }
 
+   public void setIndexedId(BytesRef indexedId) {
+     this.indexedId = indexedId;
+   }
+
    public String getPrintableId() {
      IndexSchema schema = req.getSchema();
      SchemaField sf = schema.getUniqueKeyField();
@@ -105,10 +116,11 @@ public class AddUpdateCommand extends Up
 
    @Override
   public String toString() {
-     StringBuilder sb = new StringBuilder(commandName);
-     sb.append(':');
-     if (indexedId !=null) sb.append("id=").append(indexedId);
+     StringBuilder sb = new StringBuilder(super.toString());
+     if (indexedId != null) sb.append(",id=").append(indexedId);
      if (!overwrite) sb.append(",overwrite=").append(overwrite);
+     if (commitWithin != -1) sb.append(",commitWithin=").append(commitWithin);
+     sb.append('}');
      return sb.toString();
    }
  }

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/CommitTracker.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/CommitTracker.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/CommitTracker.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/CommitTracker.java Wed Jan 25 21:56:44 2012
@@ -91,6 +91,14 @@ final class CommitTracker implements Run
   public void scheduleCommitWithin(long commitMaxTime) {
     _scheduleCommitWithin(commitMaxTime);
   }
+  
+  private void _scheduleCommitWithinIfNeeded(long commitWithin) {
+    long ctime = (commitWithin > 0) ? commitWithin : timeUpperBound;
+
+    if (ctime > 0) {
+      _scheduleCommitWithin(ctime);
+    }
+  }
 
   private void _scheduleCommitWithin(long commitMaxTime) {
     if (commitMaxTime <= 0) return;
@@ -139,11 +147,14 @@ final class CommitTracker implements Run
     }
     
     // maxTime-triggered autoCommit
-    long ctime = (commitWithin > 0) ? commitWithin : timeUpperBound;
-
-    if (ctime > 0) {
-      _scheduleCommitWithin(ctime);
-    }
+    _scheduleCommitWithinIfNeeded(commitWithin);
+  }
+  
+  /** 
+   * Indicate that documents have been deleted
+   */
+  public void deletedDocument( int commitWithin ) {
+    _scheduleCommitWithinIfNeeded(commitWithin);
   }
   
   /** Inform tracker that a commit has occurred */

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/CommitUpdateCommand.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/CommitUpdateCommand.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/CommitUpdateCommand.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/CommitUpdateCommand.java Wed Jan 25 21:56:44 2012
@@ -37,16 +37,21 @@ public class CommitUpdateCommand extends
   public int maxOptimizeSegments = 1;
 
   public CommitUpdateCommand(SolrQueryRequest req, boolean optimize) {
-    super("commit", req);
+    super(req);
     this.optimize=optimize;
   }
+
+  @Override
+  public String name() {
+    return "commit";
+  }
+
   @Override
   public String toString() {
-    return prepareCommit ? "prepareCommit" :
-        ("commit(optimize="+optimize
+    return super.toString() + ",optimize="+optimize
             +",waitSearcher="+waitSearcher
             +",expungeDeletes="+expungeDeletes
             +",softCommit="+softCommit
-            +')');
+            +'}';
   }
 }

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java Wed Jan 25 21:56:44 2012
@@ -20,14 +20,21 @@ package org.apache.solr.update;
 import java.io.IOException;
 
 import org.apache.lucene.index.IndexWriter;
+import org.apache.solr.cloud.RecoveryStrategy;
 import org.apache.solr.core.DirectoryFactory;
 import org.apache.solr.core.SolrCore;
 
 public final class DefaultSolrCoreState extends SolrCoreState {
+ 
+  private final Object recoveryLock = new Object();
   private int refCnt = 1;
   private SolrIndexWriter indexWriter = null;
   private DirectoryFactory directoryFactory;
 
+  private boolean recoveryRunning;
+  private RecoveryStrategy recoveryStrat;
+  private boolean closed = false;
+  
   public DefaultSolrCoreState(DirectoryFactory directoryFactory) {
     this.directoryFactory = directoryFactory;
   }
@@ -50,14 +57,23 @@ public final class DefaultSolrCoreState 
   }
 
   @Override
-  public synchronized void decref() throws IOException {
-    refCnt--;
-    if (refCnt == 0) {
-      if (indexWriter != null) {
-        indexWriter.close();
+  public  void decref(IndexWriterCloser closer) throws IOException {
+    boolean cancelRecovery = false;
+    synchronized (this) {
+      refCnt--;
+      if (refCnt == 0) {
+        if (closer != null) {
+          closer.closeWriter(indexWriter);
+        } else if (indexWriter != null) {
+          indexWriter.close();
+        }
+        directoryFactory.close();
+        closed = true;
+        cancelRecovery = true;
       }
-      directoryFactory.close();
     }
+    // don't wait for this in the sync block
+    if (cancelRecovery) cancelRecovery();
   }
 
   @Override
@@ -85,5 +101,43 @@ public final class DefaultSolrCoreState 
   public DirectoryFactory getDirectoryFactory() {
     return directoryFactory;
   }
+
+  @Override
+  public void doRecovery(SolrCore core) {
+    cancelRecovery();
+    synchronized (recoveryLock) {
+      while (recoveryRunning) {
+        try {
+          recoveryLock.wait(1000);
+        } catch (InterruptedException e) {
+
+        }
+        if (closed) return;
+      }
+      
+      recoveryStrat = new RecoveryStrategy(core);
+      recoveryStrat.start();
+      recoveryRunning = true;
+    }
+    
+  }
+  
+  @Override
+  public void cancelRecovery() {
+    synchronized (recoveryLock) {
+      if (recoveryStrat != null) {
+        recoveryStrat.close();
+        
+        try {
+          recoveryStrat.join();
+        } catch (InterruptedException e) {
+          
+        }
+        
+        recoveryRunning = false;
+        recoveryLock.notifyAll();
+      }
+    }
+  }
   
 }

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DeleteUpdateCommand.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DeleteUpdateCommand.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DeleteUpdateCommand.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DeleteUpdateCommand.java Wed Jan 25 21:56:44 2012
@@ -18,6 +18,7 @@
 package org.apache.solr.update;
 
 import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.CharsRef;
 import org.apache.solr.common.SolrInputField;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.schema.IndexSchema;
@@ -29,17 +30,28 @@ import org.apache.solr.schema.SchemaFiel
 public class DeleteUpdateCommand extends UpdateCommand {
   public String id;    // external (printable) id, for delete-by-id
   public String query; // query string for delete-by-query
-  private BytesRef indexedId;
+  public BytesRef indexedId;
+  public int commitWithin = -1;
 
 
   public DeleteUpdateCommand(SolrQueryRequest req) {
-    super("delete", req);
+    super(req);
+  }
+
+  @Override
+  public String name() {
+    return "delete";
+  }
+
+  public boolean isDeleteById() {
+    return query == null;
   }
 
   public void clear() {
     id = null;
     query = null;
     indexedId = null;
+    version = 0;
   }
 
   /** Returns the indexed ID for this delete.  The returned BytesRef is retained across multiple calls, and should not be modified. */
@@ -55,13 +67,46 @@ public class DeleteUpdateCommand extends
     return indexedId;
   }
 
+  public String getId() {
+    if (id == null && indexedId != null) {
+      IndexSchema schema = req.getSchema();
+      SchemaField sf = schema.getUniqueKeyField();
+      if (sf != null) {
+        CharsRef ref = new CharsRef();
+        sf.getType().indexedToReadable(indexedId, ref);
+        id = ref.toString();
+      }
+    }
+    return id;
+  }
+
+  public String getQuery() {
+    return query;
+  }
+
+  public void setQuery(String query) {
+    this.query = query;
+  }
+
+  public void setIndexedId(BytesRef indexedId) {
+    this.indexedId = indexedId;
+    this.id = null;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+    this.indexedId = null;
+  }
 
   @Override
   public String toString() {
-    StringBuilder sb = new StringBuilder(commandName);
-    sb.append(':');
-    if (id!=null) sb.append("id=").append(id);
-    else sb.append("query=`").append(query).append('`');
-    return sb.toString();
+    StringBuilder sb = new StringBuilder(super.toString());
+    if (id!=null) sb.append(",id=").append(getId());
+    if (indexedId!=null) sb.append(",indexedId=").append(getId());
+    if (query != null) sb.append(",query=`").append(query).append('`');
+    sb.append(",commitWithin=").append(commitWithin);
+     sb.append('}');
+     return sb.toString();
   }
+
 }

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java Wed Jan 25 21:56:44 2012
@@ -32,6 +32,7 @@ import org.apache.lucene.document.Docume
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queryparser.classic.ParseException;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanClause.Occur;
@@ -45,8 +46,11 @@ import org.apache.solr.common.util.Named
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.core.SolrConfig.UpdateHandlerInfo;
 import org.apache.solr.core.SolrCore;
+import org.apache.solr.schema.SchemaField;
+import org.apache.solr.search.FunctionRangeQuery;
 import org.apache.solr.search.QParser;
-import org.apache.solr.search.SolrIndexSearcher;
+import org.apache.solr.search.QueryUtils;
+import org.apache.solr.search.function.ValueSourceRangeFilter;
 
 /**
  *  TODO: add soft commitWithin support
@@ -54,8 +58,8 @@ import org.apache.solr.search.SolrIndexS
  * <code>DirectUpdateHandler2</code> implements an UpdateHandler where documents are added
  * directly to the main Lucene index as opposed to adding to a separate smaller index.
  */
-public class DirectUpdateHandler2 extends UpdateHandler {
-  protected SolrCoreState solrCoreState;
+public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState.IndexWriterCloser {
+  protected final SolrCoreState solrCoreState;
   protected final Lock commitLock = new ReentrantLock();
 
   // stats
@@ -97,7 +101,7 @@ public class DirectUpdateHandler2 extend
   public DirectUpdateHandler2(SolrCore core, UpdateHandler updateHandler) throws IOException {
     super(core);
     if (updateHandler instanceof DirectUpdateHandler2) {
-      this.solrCoreState = ((DirectUpdateHandler2)updateHandler).solrCoreState;
+      this.solrCoreState = ((DirectUpdateHandler2) updateHandler).solrCoreState;
     } else {
       // the impl has changed, so we cannot use the old state - decref it
       updateHandler.decref();
@@ -115,7 +119,9 @@ public class DirectUpdateHandler2 extend
     softCommitTracker = new CommitTracker("Soft", core, softCommitDocsUpperBound, softCommitTimeUpperBound, true, true);
     
     this.ulog = updateHandler.getUpdateLog();
-    this.ulog.init(this, core);
+    if (this.ulog != null) {
+      this.ulog.init(this, core);
+    }
   }
 
   private void deleteAll() throws IOException {
@@ -170,14 +176,17 @@ public class DirectUpdateHandler2 extend
         // allow duplicates
         writer.addDocument(cmd.getLuceneDocument());
       }
+
       // Add to the transaction log *after* successfully adding to the index, if there was no error.
       // This ordering ensures that if we log it, it's definitely been added to the the index.
       // This also ensures that if a commit sneaks in-between, that we know everything in a particular
       // log version was definitely committed.
-      ulog.add(cmd);
+      if (ulog != null) ulog.add(cmd);
 
-      softCommitTracker.addedDocument( -1 ); // TODO: support commitWithin with soft update
-      commitTracker.addedDocument( cmd.commitWithin );
+      if ((cmd.getFlags() & UpdateCommand.IGNORE_AUTOCOMMIT) == 0) {
+        commitTracker.addedDocument( cmd.commitWithin );
+        softCommitTracker.addedDocument( -1 ); // TODO: support commitWithin with soft update
+      }
 
       rc = 1;
     } finally {
@@ -203,17 +212,20 @@ public class DirectUpdateHandler2 extend
     Term deleteTerm = new Term(idField.getName(), cmd.getIndexedId());
 
     // SolrCore.verbose("deleteDocuments",deleteTerm,writer);
+    commitTracker.deletedDocument( cmd.commitWithin );
     writer.deleteDocuments(deleteTerm);
     // SolrCore.verbose("deleteDocuments",deleteTerm,"DONE");
 
-    ulog.delete(cmd);
- 
-    if (commitTracker.getTimeUpperBound() > 0) {
-      commitTracker.scheduleCommitWithin(commitTracker.getTimeUpperBound());
-    } 
-    
-    if (softCommitTracker.getTimeUpperBound() > 0) {
-      softCommitTracker.scheduleCommitWithin(softCommitTracker.getTimeUpperBound());
+    if (ulog != null) ulog.delete(cmd);
+
+    if ((cmd.getFlags() & UpdateCommand.IGNORE_AUTOCOMMIT) == 0) {
+      if (commitTracker.getTimeUpperBound() > 0) {
+        commitTracker.scheduleCommitWithin(commitTracker.getTimeUpperBound());
+      }
+
+      if (softCommitTracker.getTimeUpperBound() > 0) {
+        softCommitTracker.scheduleCommitWithin(softCommitTracker.getTimeUpperBound());
+      }
     }
   }
 
@@ -226,21 +238,50 @@ public class DirectUpdateHandler2 extend
     try {
       Query q;
       try {
+        // TODO: move this higher in the stack?
         QParser parser = QParser.getParser(cmd.query, "lucene", cmd.req);
         q = parser.getQuery();
+        q = QueryUtils.makeQueryable(q);
+
+        // peer-sync can cause older deleteByQueries to be executed and could
+        // delete newer documents.  We prevent this by adding a clause restricting
+        // version.
+        if ((cmd.getFlags() & UpdateCommand.PEER_SYNC) != 0) {
+          BooleanQuery bq = new BooleanQuery();
+          bq.add(q, Occur.MUST);
+          SchemaField sf = core.getSchema().getField(VersionInfo.VERSION_FIELD);
+          ValueSource vs = sf.getType().getValueSource(sf, null);
+          ValueSourceRangeFilter filt = new ValueSourceRangeFilter(vs, null, Long.toString(Math.abs(cmd.version)), true, true);
+          FunctionRangeQuery range = new FunctionRangeQuery(filt);
+          bq.add(range, Occur.MUST);
+          q = bq;
+        }
+
+
+
       } catch (ParseException e) {
         throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
       }
       
       boolean delAll = MatchAllDocsQuery.class == q.getClass();
+
+      commitTracker.deletedDocument(cmd.commitWithin);
       
-      if (delAll) {
-        deleteAll();
-      } else {
-        solrCoreState.getIndexWriter(core).deleteDocuments(q);
-      }
+      //
+      // synchronized to prevent deleteByQuery from running during the "open new searcher"
+      // part of a commit.  DBQ needs to signal that a fresh reader will be needed for
+      // a realtime view of the index.  When a new searcher is opened after a DBQ, that
+      // flag can be cleared.  If those thing happen concurrently, it's not thread safe.
+      //
+      synchronized (this) {
+        if (delAll) {
+          deleteAll();
+        } else {
+          solrCoreState.getIndexWriter(core).deleteDocuments(q);
+        }
 
-      ulog.deleteByQuery(cmd);
+        if (ulog != null) ulog.deleteByQuery(cmd);
+      }
 
       madeIt = true;
       
@@ -342,7 +383,7 @@ public class DirectUpdateHandler2 extend
 
       if (!cmd.softCommit) {
         synchronized (this) { // sync is currently needed to prevent preCommit from being called between preSoft and postSoft... see postSoft comments.
-          ulog.preCommit(cmd);
+          if (ulog != null) ulog.preCommit(cmd);
         }
 
         // SolrCore.verbose("writer.commit() start writer=",writer);
@@ -360,23 +401,23 @@ public class DirectUpdateHandler2 extend
       }
 
 
-        if (cmd.softCommit) {
-          // ulog.preSoftCommit();
-          synchronized (this) {
-            ulog.preSoftCommit(cmd);
-            core.getSearcher(true,false,waitSearcher, true);
-            ulog.postSoftCommit(cmd);
-          }
-          // ulog.postSoftCommit();
-        } else {
-          synchronized (this) {
-            ulog.preSoftCommit(cmd);
-            core.getSearcher(true,false,waitSearcher);
-            ulog.postSoftCommit(cmd);
-          }
-          ulog.postCommit(cmd); // postCommit currently means new searcher has also been opened
+      if (cmd.softCommit) {
+        // ulog.preSoftCommit();
+        synchronized (this) {
+          if (ulog != null) ulog.preSoftCommit(cmd);
+          core.getSearcher(true, false, waitSearcher, true);
+          if (ulog != null) ulog.postSoftCommit(cmd);
         }
-
+        // ulog.postSoftCommit();
+      } else {
+        synchronized (this) {
+          if (ulog != null) ulog.preSoftCommit(cmd);
+          core.getSearcher(true, false, waitSearcher);
+          if (ulog != null) ulog.postSoftCommit(cmd);
+        }
+        if (ulog != null) ulog.postCommit(cmd); // postCommit currently means new searcher has
+                              // also been opened
+      }
 
       // reset commit tracking
 
@@ -415,25 +456,6 @@ public class DirectUpdateHandler2 extend
   }
 
   @Override
-  public SolrIndexSearcher reopenSearcher(SolrIndexSearcher previousSearcher) throws IOException {
-    
-    IndexReader currentReader = previousSearcher.getIndexReader();
-    IndexReader newReader;
-
-    IndexWriter writer = solrCoreState.getIndexWriter(core);
-    // SolrCore.verbose("start reopen from",previousSearcher,"writer=",writer);
-    newReader = IndexReader.openIfChanged(currentReader, writer, true);
-    // SolrCore.verbose("reopen result", newReader);
-    
-    if (newReader == null) {
-      currentReader.incRef();
-      newReader = currentReader;
-    }
-
-    return new SolrIndexSearcher(core, schema, "main", newReader, true, true, true, core.getDirectoryFactory());
-  }
-  
-  @Override
   public void newIndexWriter() throws IOException {
     solrCoreState.newIndexWriter(core);
   }
@@ -487,12 +509,44 @@ public class DirectUpdateHandler2 extend
 
     numDocsPending.set(0);
 
-    solrCoreState.decref();
-    
-    log.info("closed " + this);
+    solrCoreState.decref(this);
   }
 
 
+  public static boolean commitOnClose = true;  // TODO: make this a real config option?
+
+  // IndexWriterCloser interface method - called from solrCoreState.decref(this)
+  @Override
+  public void closeWriter(IndexWriter writer) throws IOException {
+    commitLock.lock();
+    try {
+      if (!commitOnClose) {
+        if (writer != null) {
+          writer.rollback();
+        }
+
+        // we shouldn't close the transaction logs either, but leaving them open
+        // means we can't delete them on windows.
+        if (ulog != null) ulog.close();
+
+        return;
+      }
+
+      if (writer != null) {
+        writer.close();
+      }
+
+      // if the writer hits an exception, it's OK (and perhaps desirable)
+      // to not close the ulog?
+
+      // Closing the log currently deletes the log file.
+      // If this changes, we should record this as a "commit".
+      if (ulog != null) ulog.close();
+    } finally {
+      commitLock.unlock();
+    }
+  }
+
   /////////////////////////////////////////////////////////////////////
   // SolrInfoMBean stuff: Statistics and Module Info
   /////////////////////////////////////////////////////////////////////
@@ -564,14 +618,15 @@ public class DirectUpdateHandler2 extend
     return "DirectUpdateHandler2" + getStatistics();
   }
   
-  public SolrCoreState getIndexWriterProvider() {
+  @Override
+  public SolrCoreState getSolrCoreState() {
     return solrCoreState;
   }
 
   @Override
   public void decref() {
     try {
-      solrCoreState.decref();
+      solrCoreState.decref(this);
     } catch (IOException e) {
       throw new SolrException(ErrorCode.SERVER_ERROR, "", e);
     }

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/MergeIndexesCommand.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/MergeIndexesCommand.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/MergeIndexesCommand.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/MergeIndexesCommand.java Wed Jan 25 21:56:44 2012
@@ -31,20 +31,25 @@ public class MergeIndexesCommand extends
   public IndexReader[] readers;
 
   public MergeIndexesCommand(IndexReader[] readers, SolrQueryRequest req) {
-    super("mergeIndexes", req);
+    super(req);
     this.readers = readers;
   }
 
   @Override
+  public String name() {
+    return "mergeIndexes";
+  }
+
+  @Override
   public String toString() {
-    StringBuilder sb = new StringBuilder(commandName);
-    sb.append(':');
+    StringBuilder sb = new StringBuilder(super.toString());
     if (readers != null && readers.length > 0) {
       sb.append(readers[0].directory());
       for (int i = 1; i < readers.length; i++) {
         sb.append(",").append(readers[i].directory());
       }
     }
+    sb.append('}');
     return sb.toString();
   }
 }

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/RollbackUpdateCommand.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/RollbackUpdateCommand.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/RollbackUpdateCommand.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/RollbackUpdateCommand.java Wed Jan 25 21:56:44 2012
@@ -26,7 +26,16 @@ import org.apache.solr.request.SolrQuery
 public class RollbackUpdateCommand extends UpdateCommand {
 
   public RollbackUpdateCommand(SolrQueryRequest req) {
-    super("rollback", req);
+    super(req);
   }
 
+  @Override
+  public String name() {
+    return "rollback";
+  }
+
+  @Override
+  public String toString() {
+    return super.toString() + '}';
+  }
 }

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/SolrCoreState.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/SolrCoreState.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/SolrCoreState.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/SolrCoreState.java Wed Jan 25 21:56:44 2012
@@ -49,11 +49,12 @@ public abstract class SolrCoreState {
   
   /**
    * Decrement the number of references to this state. When then number of
-   * references hits 0, the state will close.
+   * references hits 0, the state will close.  If an optional closer is
+   * passed, that will be used to close the writer.
    * 
    * @throws IOException
    */
-  public abstract void decref() throws IOException;
+  public abstract void decref(IndexWriterCloser closer) throws IOException;
   
   /**
    * Increment the number of references to this state.
@@ -73,5 +74,14 @@ public abstract class SolrCoreState {
    * @return the {@link DirectoryFactory} that should be used.
    */
   public abstract DirectoryFactory getDirectoryFactory();
+
+
+  public interface IndexWriterCloser {
+    public void closeWriter(IndexWriter writer) throws IOException;
+  }
+
+  public abstract void doRecovery(SolrCore core);
   
+  public abstract void cancelRecovery();
+
 }

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/UpdateCommand.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/UpdateCommand.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/UpdateCommand.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/UpdateCommand.java Wed Jan 25 21:56:44 2012
@@ -17,6 +17,7 @@
 
 package org.apache.solr.update;
 
+import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.request.SolrQueryRequest;
 
 
@@ -24,17 +25,56 @@ import org.apache.solr.request.SolrQuery
  *
  *
  */
-  public class UpdateCommand {
-    protected final SolrQueryRequest req;
-    protected final String commandName;
-
-    public UpdateCommand(String commandName, SolrQueryRequest req) {
-      this.req = req;
-      this.commandName = commandName;
-    }
+public abstract class UpdateCommand implements Cloneable {
+  protected SolrQueryRequest req;
+  protected long version;
+  protected int flags;
+
+  public static int BUFFERING = 0x00000001;    // update command is being buffered.
+  public static int REPLAY    = 0x00000002;    // update command is from replaying a log.
+  public static int PEER_SYNC    = 0x00000004; // update command is a missing update being provided by a peer.
+  public static int IGNORE_AUTOCOMMIT = 0x00000008; // this update should not count toward triggering of autocommits.
+
+  public UpdateCommand(SolrQueryRequest req) {
+    this.req = req;
+  }
+
+  public abstract String name();
+
+  @Override
+  public String toString() {
+    return name() + "{flags="+flags+",version="+version;
+  }
+
+  public long getVersion() {
+    return version;
+  }
+  public void setVersion(long version) {
+    this.version = version;
+  }
+
+  public void setFlags(int flags) {
+    this.flags = flags;
+  }
+
+  public int getFlags() {
+    return flags;
+  }
+
+  public SolrQueryRequest getReq() {
+    return req;
+  }
+
+  public void setReq(SolrQueryRequest req) {
+    this.req = req;
+  }
 
-    @Override
-    public String toString() {
-      return commandName;
+  @Override
+  public UpdateCommand clone() {
+    try {
+      return (UpdateCommand) super.clone();
+    } catch (CloneNotSupportedException e) {
+      return null;
     }
   }
+}

Modified: lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/UpdateHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/UpdateHandler.java?rev=1235969&r1=1235968&r2=1235969&view=diff
==============================================================================
--- lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/UpdateHandler.java (original)
+++ lucene/dev/branches/lucene2858/solr/core/src/java/org/apache/solr/update/UpdateHandler.java Wed Jan 25 21:56:44 2012
@@ -88,12 +88,11 @@ public abstract class UpdateHandler impl
   private void initLog() {
     PluginInfo ulogPluginInfo = core.getSolrConfig().getPluginInfo(UpdateLog.class.getName());
     if (ulogPluginInfo != null && ulogPluginInfo.isEnabled()) {
-      ulog = core.createInitInstance(ulogPluginInfo, UpdateLog.class, "update log", "solr.NullUpdateLog");
-    } else {
-      ulog = new NullUpdateLog();
-      ulog.init(null);
+      ulog = new UpdateLog();
+      ulog.init(ulogPluginInfo);
+      // ulog = core.createInitInstance(ulogPluginInfo, UpdateLog.class, "update log", "solr.NullUpdateLog");
+      ulog.init(this, core);
     }
-    ulog.init(this, core);
   }
 
 
@@ -123,16 +122,7 @@ public abstract class UpdateHandler impl
     parseEventListeners();
     initLog();
   }
-  
-  /**
-   * Allows the UpdateHandler to create the SolrIndexSearcher after it
-   * has issued a 'softCommit'. 
-   * 
-   * @param previousSearcher
-   * @throws IOException
-   */
-  public abstract SolrIndexSearcher reopenSearcher(SolrIndexSearcher previousSearcher) throws IOException;
-  
+
   /**
    * Called when the Writer should be opened again - eg when replication replaces
    * all of the index files.
@@ -141,7 +131,7 @@ public abstract class UpdateHandler impl
    */
   public abstract void newIndexWriter() throws IOException;
 
-  public abstract SolrCoreState getIndexWriterProvider();
+  public abstract SolrCoreState getSolrCoreState();
 
   public abstract int addDoc(AddUpdateCommand cmd) throws IOException;
   public abstract void delete(DeleteUpdateCommand cmd) throws IOException;