content: /**
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.solr.handler.component;
  
  import org.apache.lucene.search.Query;
  import org.apache.lucene.search.grouping.SearchGroup;
  import org.apache.lucene.search.grouping.TopGroups;
  import org.apache.lucene.util.BytesRef;
  import org.apache.solr.common.SolrDocument;
  import org.apache.solr.common.SolrDocumentList;
  import org.apache.solr.common.util.NamedList;
  import org.apache.solr.common.util.RTimer;
  import org.apache.solr.common.util.SimpleOrderedMap;
  import org.apache.solr.request.SolrQueryRequest;
  import org.apache.solr.request.mdrill.FacetComponent;
  import org.apache.solr.request.mdrill.MdrillUtils;
  import org.apache.solr.response.SolrQueryResponse;
  import org.apache.solr.search.DocListAndSet;
  import org.apache.solr.search.QParser;
  import org.apache.solr.search.SortSpec;
  import org.apache.solr.search.SolrIndexSearcher;
  import org.apache.solr.search.grouping.GroupingSpecification;
  import org.apache.solr.search.grouping.distributed.command.QueryCommandResult;
  
  import java.util.Collection;
  import java.util.HashMap;
  import java.util.LinkedHashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.concurrent.ConcurrentHashMap;
  
  /**
   * This class is experimental and will be changing in the future.
   *
   * @version $Id: ResponseBuilder.java 1171968 2011-09-17 12:46:06Z mvg $
   * @since solr 1.3
   */
  public class ResponseBuilder
  {
    public SolrQueryRequest req;
    public SolrQueryResponse rsp;
    public boolean doHighlights;
    public boolean doFacets;
    public boolean doStats;
    public boolean doTerms;
    public Map<String,String> timetaken=new LinkedHashMap<String,String>();
  	public Map<Long,String> crcvalue=new HashMap<Long,String>();
  
  
    private boolean needDocList = false;
    private boolean needDocSet = false;
    private int fieldFlags = 0;
    private boolean debug = false;
  
    private QParser qparser = null;
    private String queryString = null;
    private Query query = null;
    private List<Query> filters = null;
    private SortSpec sortSpec = null;
    private GroupingSpecification groupingSpec;
  
    private DocListAndSet results = null;
    private NamedList<Object> debugInfo = null;
    private RTimer timer = null;
  
    private Query highlightQuery = null;
  
    public List<SearchComponent> components;
  
    //////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////
    //// Distributed Search section
    //////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////
  
    public static final String FIELD_SORT_VALUES = "fsv";
    public static final String SHARDS = "shards";
    public static final String IDS = "ids";
  
    /***
    public static final String NUMDOCS = "nd";
    public static final String DOCFREQS = "tdf";
    public static final String TERMS = "terms";
    public static final String EXTRACT_QUERY_TERMS = "eqt";
    public static final String LOCAL_SHARD = "local";
    public static final String DOC_QUERY = "dq";
    ***/
  
    public static int STAGE_START           = 0;
    public static int STAGE_PARSE_QUERY     = 1000;
    public static int STAGE_TOP_GROUPS = 1500;
    public static int STAGE_EXECUTE_QUERY   = 2000;
    public static int STAGE_GET_FIELDS      = 3000;
    public static int STAGE_DONE            = Integer.MAX_VALUE;
  
    public int stage;  // What stage is this current request at?
  
    
    public static enum RequestLockType{
  	  none,multy,singlehosts,shards
    }
    //The address of the Shard
    
    public static class ScheduleInfo{
  	  public boolean hasSubShards=false;
  	  public String[] shards;
  	  public String[] subShards;
  	  public String[] partions;
    }
    
  //  public RequestLockType lockType=RequestLockType.none;//0,none,1,multy,2,singlehosts,3,shards
  
    public int shards_rows = -1;
    public int shards_start = -1;
    public List<ShardRequest> outgoing;  // requests to be sent
    public List<ShardRequest> finished;  // requests that have received responses from all shards
  
  
    public void addRequest(SearchComponent me, ShardRequest sreq) {
  //    outgoing.add(sreq);
    }
  
    public GlobalCollectionStat globalCollectionStat;
  
    public Map<Object, ShardDoc> resultIds;
    // Maps uniqueKeyValue to ShardDoc, which may be used to
    // determine order of the doc or uniqueKey in the final
    // returned sequence.
    // Only valid after STAGE_EXECUTE_QUERY has completed.
  
  
    public FacetComponent.FacetInfo _facetInfo;
    /* private... components that don't own these shouldn't use them */
    SolrDocumentList _responseDocs;
    StatsInfo _statsInfo;
  //  TermsComponent.TermsHelper _termsHelper;
  
    // Context fields for grouping
    public final Map<String, Collection<SearchGroup<String>>> mergedSearchGroups = new HashMap<String, Collection<SearchGroup<String>>>();
    public final Map<String, Map<SearchGroup<String>, String>> searchGroupToShard = new HashMap<String, Map<SearchGroup<String>, String>>();
    public final Map<String, TopGroups<String>> mergedTopGroups = new HashMap<String, TopGroups<String>>();
    public final Map<String, QueryCommandResult> mergedQueryCommandResults = new HashMap<String, QueryCommandResult>();
    public final Map<Object, SolrDocument> retrievedDocuments = new HashMap<Object, SolrDocument>();
  
    /**
     * Utility function to add debugging info.  This will make sure a valid
     * debugInfo exists before adding to it.
     */
    public void addDebugInfo( String name, Object val )
    {
      if( debugInfo == null ) {
        debugInfo = new SimpleOrderedMap<Object>();
      }
      debugInfo.add( name, val );
    }
  
    //-------------------------------------------------------------------------
    //-------------------------------------------------------------------------
  
    public boolean isDebug() {
      return debug;
    }
  
    public void setDebug(boolean debug) {
      this.debug = debug;
    }
  
    public NamedList<Object> getDebugInfo() {
      return debugInfo;
    }
  
    public void setDebugInfo(NamedList<Object> debugInfo) {
      this.debugInfo = debugInfo;
    }
  
    public int getFieldFlags() {
      return fieldFlags;
    }
  
    public void setFieldFlags(int fieldFlags) {
      this.fieldFlags = fieldFlags;
    }
  
    public List<Query> getFilters() {
      return filters;
    }
  
    public void setFilters(List<Query> filters) {
      this.filters = filters;
    }
  
    public Query getHighlightQuery() {
      return highlightQuery;
    }
  
    public void setHighlightQuery(Query highlightQuery) {
      this.highlightQuery = highlightQuery;
    }
  
    public boolean isNeedDocList() {
      return needDocList;
    }
  
    public void setNeedDocList(boolean needDocList) {
      this.needDocList = needDocList;
    }
  
    public boolean isNeedDocSet() {
      return needDocSet;
    }
  
    public void setNeedDocSet(boolean needDocSet) {
      this.needDocSet = needDocSet;
    }
  
    public QParser getQparser() {
      return qparser;
    }
  
    public void setQparser(QParser qparser) {
      this.qparser = qparser;
    }
  
    public String getQueryString() {
      return queryString;
    }
  
    public void setQueryString(String qstr) {
      this.queryString = qstr;
    }
  
    public Query getQuery() {
      return query;
    }
  
    public void setQuery(Query query) {
      this.query = query;
    }
  
    public DocListAndSet getResults() {
      return results;
    }
  
    public void setResults(DocListAndSet results) {
      this.results = results;
    }
  
    public SortSpec getSortSpec() {
      return sortSpec;
    }
  
    public void setSortSpec(SortSpec sort) {
      this.sortSpec = sort;
    }
  
    public GroupingSpecification getGroupingSpec() {
      return groupingSpec;
    }
  
    public void setGroupingSpec(GroupingSpecification groupingSpec) {
      this.groupingSpec = groupingSpec;
    }
  
    public boolean grouping() {
      return groupingSpec != null;
    }
  
    public RTimer getTimer() {
      return timer;
    }
  
    public void setTimer(RTimer timer) {
      this.timer = timer;
    }
  
  
    public static class GlobalCollectionStat {
      public final long numDocs;
  
      public final Map<String, Long> dfMap;
  
      public GlobalCollectionStat(int numDocs, Map<String, Long> dfMap) {
        this.numDocs = numDocs;
        this.dfMap = dfMap;
      }
    }
  
    /**
     * Creates a SolrIndexSearcher.QueryCommand from this
     * ResponseBuilder.  TimeAllowed is left unset.
     */
    public SolrIndexSearcher.QueryCommand getQueryCommand() {
      SolrIndexSearcher.QueryCommand cmd = new SolrIndexSearcher.QueryCommand();
      cmd.setQuery( getQuery() )
        .setFilterList( getFilters() )
        .setSort( getSortSpec().getSort() )
        .setOffset( getSortSpec().getOffset() )
        .setLen( getSortSpec().getCount() )
        .setFlags( getFieldFlags() )
        .setNeedDocSet( isNeedDocSet() );
      return cmd;
    }
  
    /**
     * Sets results from a SolrIndexSearcher.QueryResult.
     */
    public void setResult( SolrIndexSearcher.QueryResult result ) {
      setResults( result.getDocListAndSet() );
      if( result.isPartialResults() ) {
        rsp.getResponseHeader().add( "partialResults", Boolean.TRUE );
      }
    }
  }
  