Beispiel #1
0
results::WordsVector Searches::advance(
    std::string query,
    std::string lang,
    int size,
    int offset
) {
    SearchResults resultIds = SearchEngine::get_instance()->search(
        query,
        lang,
        size,
        offset
    );
    
    results::WordsVector wordsVector(resultIds.size());

    models::Words wordsModel;

    int resultSize = resultIds.size();
    for (int i = 0; i < resultSize; ++i) {
        wordsVector[i] = wordsModel.get_word_with_id(
            resultIds[i]
        );
    }
    wordsVector.offset = offset;
    wordsVector.maxsize = resultIds.maxsize;
    return wordsVector;
}
Beispiel #2
0
inline void gatherResultstoProcZero(MPI_Comm comm, SearchResults& boxIdPairResults)
{
    int procId=-1;
    MPI_Comm_rank(comm, &procId);

    int numProc=-1;
    MPI_Comm_size(comm, &numProc);

    int procIdDestination = 0;
    stk::CommAll gather(comm);
    for (int phase=0; phase<2; ++phase)
    {
        if ( procId != procIdDestination )
        {
            for (size_t j=0;j<boxIdPairResults.size();++j)
            {
                gather.send_buffer(procIdDestination).pack< std::pair<Ident, Ident> >(boxIdPairResults[j]);
            }
        }

        if (phase == 0) { //allocation phase
          gather.allocate_buffers( numProc / 4 );
        }
        else { // communication phase
          gather.communicate();
        }
    }

    if ( procId == procIdDestination )
    {
        for ( int p = 0 ; p < numProc ; ++p )
        {
            stk::CommBuffer &buf = gather.recv_buffer( p );
            while ( buf.remaining() )
            {
                std::pair<Ident, Ident> temp;
                buf.unpack< std::pair<Ident, Ident> >( temp );
                boxIdPairResults.push_back(temp);
            }
        }
    }
}
Beispiel #3
0
yaml::Mapping CyclopsMaster::reduce(const PendingRequest& results) {
  // for getPoint, we should get errors from all the dataset parts except the one that
  // actually contained it
  if (results.request["method"] == "getPoint") {
    for (int i=0; i<results.replies.size(); i++) {
      if (results.replies[i].contains("result")) {
        return results.replies[i];
      }
    }
  }

  // for getPoints, we need to get all the datasets we got back (if any), and merge
  // them together before returning the result. If the total number of points is different
  // from the number of points we asked, we need to get which are the missing ones and return
  // an error message with that
  if (results.request["method"] == "getPoints") {
    // enclose all of this inside a try/catch block, so that if any error occurs (such as
    // invalid arguments) we just fall through to the normal reduce/sendReply which will
    // send the correct error message back to the client
    // FIXME: this is just a temporary hack, a correct solution would imply a more in-depth
    //        refactoring of how arguments are checked
    try {
      if (results.request["params"].sequence().size() < 2) throw InvalidParams();
      return reduceGetPoints(results.replies, results.request["params"][1].sequence());
    }
    catch (...) {}
    /*
    DataSet resultds;
    for (int i=0; i<results.replies.size(); i++) {
      // all replies should contain result, even if only an empty dataset
      DataSet ds;
      ds.fromBase64(results.replies[i]["result"].scalar().toAscii());
      resultds.appendDataSet(&ds);
    }
    if (resultds.size() == results.request["params"][1].sequence().size()) {
      yaml::Mapping result(results.replies[0]);
      result["result"] = resultds.toBase64();
      return result;
    }

    // need to find the missing points
    QSet<QString> asked;
    foreach (const yaml::Node& n, results.request["params"][1].sequence()) asked << n.scalar();
    QSet<QString> found = QSet<QString>::fromList(resultds.pointNames());
    QStringList notfound = (asked - found).toList();

    yaml::Mapping result;
    result.insert("id", results.request["id"]);
    result.insert("error", QString("Following points could not be found: ") + notfound.join(", "));
    return result;
    */
  }

  // first check there has been no errors, otherwise return that as a common answer
  for (int i=0; i<results.replies.size(); i++) {
    if (results.replies[i].contains("error")) {
      return results.replies[i];
    }
  }

  // for size queries, we need to sum up the size of all parts
  if (results.request["method"] == "size") {
    int total = 0;
    for (int i=0; i<results.replies.size(); i++) {
      total += results.replies[i]["result"].scalar().toInt();
    }

    yaml::Mapping result;
    result.insert("id", results.request["id"]);
    result.insert("result", QString::number(total));

    return result;
  }

  // for chainedSearch queries, we need to merge the results now, only keeping the best ones
  if (results.request["method"] == "chainedSearch") {
    /*
    SearchResults allResults;
    for (int i=0; i<results.replies.size(); i++) {
      const yaml::Sequence& result = results.replies[i]["result"].sequence();
      for (int j=0; j<result.size(); j++) {
        allResults << Result(result[j][0].scalar(), result[j][1].scalar().toFloat());
      }
    }

    sort(allResults.begin(), allResults.end(), cmpSearchResults);
    */
    CyclopsResults allResults;

    for (int i=0; i<results.replies.size(); i++) {
      const yaml::Sequence& result = results.replies[i]["result"]["results"].sequence();
      const yaml::Sequence& values = results.replies[i]["result"]["values"].sequence();

      for (int j=0; j<result.size(); j++) {
        QList<QVariant> vals;
        int vsize = values[j].sequence().size();
        for (int k=0; k<vsize; k++) vals << values[j][k].scalar();

        allResults.append(Result(result[j][0].scalar(), result[j][1].scalar().toFloat()),
                          vals);
      }
    }
    allResults.sort();

    int nresults = results.request["params"][2].scalar().toInt();
    int offset   = results.request["params"][3].scalar().toInt();
    allResults.mid(offset, qMin(allResults.size()-offset, nresults));

    yaml::Mapping result = results.replies[0];
    result["result"] = toYaml(allResults);
    // add the header only now, to avoid a conversion yaml -> QVariant -> yaml
    result["result"]["header"] = results.replies[0]["result"]["header"];

    return result;
  }

  // for nnSearch queries, we need to merge the results now, only keeping the best ones
  if (results.request["method"].scalar().startsWith("nnSearch")) {
    SearchResults allResults;
    for (int i=0; i<results.replies.size(); i++) {
      const yaml::Sequence& result = results.replies[i]["result"].sequence();
      for (int j=0; j<result.size(); j++) {
        allResults << Result(result[j][0].scalar(), result[j][1].scalar().toFloat());
      }
    }

    sort(allResults.begin(), allResults.end(), cmpSearchResults);
    int npos = 3;
    if (results.request["method"].scalar().endsWith("Filter")) npos = 4;
    int nresults = results.request["params"][npos].scalar().toInt();
    allResults = allResults.mid(0, qMin(allResults.size(), nresults));

    yaml::Mapping result = results.replies[0];
    result["result"] = toYaml(allResults);

    return result;
  }

  // for queries that return None, we can return the first one
  // for datasetNames, distanceNames and layout, we assume all results are the same and return the first one
  return results.replies[0];

}