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; }
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); } } } }
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]; }