/* (non-Javadoc)
   * @see com.wwm.attrs.search.Search#getNextResults(int)
   */
  @Override
  public ArrayList<NextItem> getNextResults(int limit) {
    NanoTimer timer = new NanoTimer();
    ArrayList<NextItem> results = new ArrayList<NextItem>();
    while (results.size() < limit) {

      // If the result q is empty, expand a node, if no nodes either, end search
      if (resultsQ.isEmpty()) {
        // need to expand some nodes
        if (workQ.isEmpty()) {
          logResults(timer, results, storage);
          return results; // run out of items
        }
        //				System.out.println("** Expanding node: " + workQ.best() + ", " +
        // workQ.best().getNode() );
        workQ.expand();
      }

      // If both result q and work q have items, pop the q with the best priority
      else if (!workQ.isEmpty()) {
        if (resultsQ.best().compareTo(workQ.best()) > 0) {
          results.add(resultsQ.pop());
        } else {
          //					System.out.println("** Expanding node: " + workQ.best() + ", " +
          // workQ.best().getNode() );
          workQ.expand();
        }
      } else { // result q has items, work q is empty
        results.add(resultsQ.pop());
      }
    }
    logResults(timer, results, storage);

    return results;
  }
 /* (non-Javadoc)
  * @see com.wwm.attrs.search.Search#isMoreResults()
  */
 @Override
 public boolean isMoreResults() {
   while (resultsQ.isEmpty()) {
     if (workQ.isEmpty()) {
       return false;
     }
     workQ.expand();
   }
   return true;
 }
  /**
   * Begin a new search - use the helper Index.NewSearch()
   *
   * @param spec
   * @param nominee
   */
  public OrderedSearch(
      SearchSpecImpl spec,
      IScoreConfiguration config,
      boolean nominee,
      NodeStorageManager storage) {
    super();
    this.spec = spec;
    this.storage = storage;
    this.nominee = nominee;

    resultsQ =
        new ResultsQ(spec.getMaxNonMatches(), spec.getScoreThreshold(), spec.getTargetNumResults());

    workQ = new WorkQ(this, resultsQ, config);
    workQ.add(
        new NextNode(new NodeScore(), getNextSeq(), storage.getRootNode())); // FIXME: NodeScore

    if (log.isInfoEnabled()) {
      log.info(
          "New Search: threshold = "
              + spec.getScoreThreshold()
              + ", targetNumResults = "
              + spec.getTargetNumResults()
              + ", searchType = "
              + spec.getScorerConfig());
    }

    //		log.info( "Index dump: ");
    //		storage.getRootNode().dumpNode(System.out, 0, storage);
  }
 @SuppressWarnings("unused")
 private int getBranchNodesExpanded() {
   return workQ.getBranchNodesExpanded();
 }
 private int getLeafNodesExpanded() {
   return workQ.getLeafNodesExpanded();
 }