X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Ffilter_multi.cpp;h=a8d472550bef896f07cc34e02b96ac1df081725b;hb=4c42fcd314fe52e0a896b08ed9d818bf6f323fe7;hp=03916ba60099ab7f0ea175d1c86e135e2b594bf4;hpb=d6af36a9a92973976dfcfd906529567265c4fe80;p=metaproxy-moved-to-github.git diff --git a/src/filter_multi.cpp b/src/filter_multi.cpp index 03916ba..a8d4725 100644 --- a/src/filter_multi.cpp +++ b/src/filter_multi.cpp @@ -1,5 +1,5 @@ -/* $Id: filter_multi.cpp,v 1.10 2006-01-18 14:36:15 adam Exp $ - Copyright (c) 2005, Index Data. +/* $Id: filter_multi.cpp,v 1.16 2006-05-15 11:40:26 adam Exp $ + Copyright (c) 2005-2006, Index Data. %LICENSE% */ @@ -26,9 +26,10 @@ #include #include -namespace yf = yp2::filter; +namespace mp = metaproxy_1; +namespace yf = mp::filter; -namespace yp2 { +namespace metaproxy_1 { namespace filter { struct Multi::BackendSet { @@ -92,23 +93,20 @@ namespace yp2 { }; class Multi::Rep { friend class Multi; - friend class Frontend; + friend struct Frontend; FrontendPtr get_frontend(Package &package); void release_frontend(Package &package); private: - boost::mutex m_sessions_mutex; std::mapm_maps; std::map m_target_route; boost::mutex m_mutex; boost::condition m_cond_session_ready; - std::map m_clients; + std::map m_clients; }; } } -using namespace yp2; - bool yf::Multi::BackendSet::operator < (const BackendSet &k) const { return m_count < k.m_count; @@ -128,7 +126,7 @@ yf::Multi::FrontendPtr yf::Multi::Rep::get_frontend(Package &package) { boost::mutex::scoped_lock lock(m_mutex); - std::map::iterator it; + std::map::iterator it; while(true) { @@ -152,7 +150,7 @@ yf::Multi::FrontendPtr yf::Multi::Rep::get_frontend(Package &package) void yf::Multi::Rep::release_frontend(Package &package) { boost::mutex::scoped_lock lock(m_mutex); - std::map::iterator it; + std::map::iterator it; it = m_clients.find(package.session()); if (it != m_clients.end()) @@ -240,14 +238,9 @@ void yf::Multi::Frontend::multi_move(std::list &blist) g.join_all(); } - void yf::Multi::FrontendSet::round_robin(int start, int number, std::list &jobs) { - int fetched = 0; - int p = 1; - bool eof = true; - std::list pos; std::list inside_pos; std::list::const_iterator bsit; @@ -257,39 +250,84 @@ void yf::Multi::FrontendSet::round_robin(int start, int number, inside_pos.push_back(0); } - std::list::iterator psit = pos.begin(); - std::list::iterator esit = inside_pos.begin(); - bsit = m_backend_sets.begin(); - while (fetched < number) + int p = 1; +#if 1 + // optimization step! + int omin = 0; + while(true) { - if (bsit == m_backend_sets.end()) + int min = 0; + int no_left = 0; + // find min count for each set which is > omin + for (bsit = m_backend_sets.begin(); bsit != m_backend_sets.end(); bsit++) { - psit = pos.begin(); - esit = inside_pos.begin(); - bsit = m_backend_sets.begin(); - if (eof) - break; - eof = true; + if (bsit->m_count > omin) + { + if (no_left == 0 || bsit->m_count < min) + min = bsit->m_count; + no_left++; + } } - if (*psit <= bsit->m_count) + if (no_left == 0) // if nothing greater than omin, bail out. + break; + int skip = no_left * min; + if (p + skip > start) // step gets us "into" present range? { - if (p >= start) + // Yes. skip until start.. Rounding off is deliberate! + min = (start-p) / no_left; + p += no_left * min; + + // update positions in each set.. + std::list::iterator psit = pos.begin(); + for (psit = pos.begin(); psit != pos.end(); psit++) + *psit += min; + break; + } + // skip on each set.. before "present range".. + p = p + skip; + + std::cout << "\nSKIP min=" << min << " no_left=" << no_left << "\n\n"; + + std::list::iterator psit = pos.begin(); + for (psit = pos.begin(); psit != pos.end(); psit++) + *psit += min; + + omin = min; // update so we consider next class (with higher count) + } +#endif + int fetched = 0; + bool more = true; + while (more) + { + more = false; + std::list::iterator psit = pos.begin(); + std::list::iterator esit = inside_pos.begin(); + bsit = m_backend_sets.begin(); + + for (; bsit != m_backend_sets.end(); psit++,esit++,bsit++) + { + if (fetched >= number) + { + more = false; + break; + } + if (*psit <= bsit->m_count) { - PresentJob job; - job.m_backend = bsit->m_backend; - job.m_pos = *psit; - job.m_inside_pos = *esit; - jobs.push_back(job); - (*esit)++; - fetched++; + if (p >= start) + { + PresentJob job; + job.m_backend = bsit->m_backend; + job.m_pos = *psit; + job.m_inside_pos = *esit; + jobs.push_back(job); + (*esit)++; + fetched++; + } + (*psit)++; + p++; + more = true; } - (*psit)++; - p++; - eof = false; } - psit++; - esit++; - bsit++; } } @@ -299,7 +337,7 @@ void yf::Multi::Frontend::init(Package &package, Z_GDU *gdu) std::list targets; - yp2::util::get_vhost_otherinfo(&req->otherInfo, false, targets); + mp::util::get_vhost_otherinfo(&req->otherInfo, false, targets); if (targets.size() < 1) { @@ -326,13 +364,13 @@ void yf::Multi::Frontend::init(Package &package, Z_GDU *gdu) std::list::const_iterator bit; for (bit = m_backend_list.begin(); bit != m_backend_list.end(); bit++) { - yp2::odr odr; + mp::odr odr; BackendPtr b = *bit; Z_APDU *init_apdu = zget_APDU(odr, Z_APDU_initRequest); std::listvhost_one; vhost_one.push_back(b->m_vhost); - yp2::util::set_vhost_otherinfo(&init_apdu->u.initRequest->otherInfo, + mp::util::set_vhost_otherinfo(&init_apdu->u.initRequest->otherInfo, odr, vhost_one); Z_InitRequest *req = init_apdu->u.initRequest; @@ -353,7 +391,7 @@ void yf::Multi::Frontend::init(Package &package, Z_GDU *gdu) multi_move(m_backend_list); // create the frontend init response based on each backend init response - yp2::odr odr; + mp::odr odr; Z_APDU *f_apdu = odr.create_initResponse(gdu->u.z3950, 0, 0); Z_InitResponse *f_resp = f_apdu->u.initResponse; @@ -427,9 +465,9 @@ void yf::Multi::Frontend::search(Package &package, Z_APDU *apdu_req) for (bit = m_backend_list.begin(); bit != m_backend_list.end(); bit++) { PackagePtr p = (*bit)->m_package; - yp2::odr odr; + mp::odr odr; - if (!yp2::util::set_databases_from_zurl(odr, (*bit)->m_vhost, + if (!mp::util::set_databases_from_zurl(odr, (*bit)->m_vhost, &req->num_databaseNames, &req->databaseNames)) { @@ -482,7 +520,7 @@ void yf::Multi::Frontend::search(Package &package, Z_APDU *apdu_req) } } - yp2::odr odr; + mp::odr odr; Z_APDU *f_apdu = odr.create_searchResponse(apdu_req, 0, 0); Z_SearchResponse *f_resp = f_apdu->u.searchResponse; @@ -498,7 +536,7 @@ void yf::Multi::Frontend::search(Package &package, Z_APDU *apdu_req) m_sets[resultSet.m_setname] = resultSet; int number; - yp2::util::piggyback(smallSetUpperBound, + mp::util::piggyback(smallSetUpperBound, largeSetLowerBound, mediumSetPresentNumber, result_set_size, @@ -548,7 +586,7 @@ void yf::Multi::Frontend::present(Package &package, Z_APDU *apdu_req) it = m_sets.find(std::string(req->resultSetId)); if (it == m_sets.end()) { - yp2::odr odr; + mp::odr odr; Z_APDU *apdu = odr.create_presentResponse( apdu_req, @@ -631,7 +669,7 @@ void yf::Multi::Frontend::present(Package &package, Z_APDU *apdu_req) } } - yp2::odr odr; + mp::odr odr; Z_APDU *f_apdu = odr.create_presentResponse(apdu_req, 0, 0); Z_PresentResponse *f_resp = f_apdu->u.presentResponse; @@ -676,7 +714,7 @@ void yf::Multi::Frontend::scan1(Package &package, Z_APDU *apdu_req) { if (m_backend_list.size() > 1) { - yp2::odr odr; + mp::odr odr; Z_APDU *f_apdu = odr.create_scanResponse( apdu_req, YAZ_BIB1_COMBI_OF_SPECIFIED_DATABASES_UNSUPP, 0); @@ -692,9 +730,9 @@ void yf::Multi::Frontend::scan1(Package &package, Z_APDU *apdu_req) for (bit = m_backend_list.begin(); bit != m_backend_list.end(); bit++) { PackagePtr p = (*bit)->m_package; - yp2::odr odr; + mp::odr odr; - if (!yp2::util::set_databases_from_zurl(odr, (*bit)->m_vhost, + if (!mp::util::set_databases_from_zurl(odr, (*bit)->m_vhost, &req->num_databaseNames, &req->databaseNames)) { @@ -766,7 +804,6 @@ Z_Entry *yf::Multi::ScanTermInfo::get_entry(ODR odr) void yf::Multi::Frontend::scan2(Package &package, Z_APDU *apdu_req) { Z_ScanRequest *req = apdu_req->u.scanRequest; - int no_targets = 0; int default_num_db = req->num_databaseNames; char **default_db = req->databaseNames; @@ -775,9 +812,9 @@ void yf::Multi::Frontend::scan2(Package &package, Z_APDU *apdu_req) for (bit = m_backend_list.begin(); bit != m_backend_list.end(); bit++) { PackagePtr p = (*bit)->m_package; - yp2::odr odr; + mp::odr odr; - if (!yp2::util::set_databases_from_zurl(odr, (*bit)->m_vhost, + if (!mp::util::set_databases_from_zurl(odr, (*bit)->m_vhost, &req->num_databaseNames, &req->databaseNames)) { @@ -786,7 +823,6 @@ void yf::Multi::Frontend::scan2(Package &package, Z_APDU *apdu_req) } p->request() = apdu_req; p->copy_filter(package); - no_targets++; } multi_move(m_backend_list); @@ -811,7 +847,7 @@ void yf::Multi::Frontend::scan2(Package &package, Z_APDU *apdu_req) if (res->entries && res->entries->nonsurrogateDiagnostics) { // failure - yp2::odr odr; + mp::odr odr; Z_APDU *f_apdu = odr.create_scanResponse(apdu_req, 1, 0); Z_ScanResponse *f_res = f_apdu->u.scanResponse; @@ -873,7 +909,11 @@ void yf::Multi::Frontend::scan2(Package &package, Z_APDU *apdu_req) } } // after - for (i = position-1; iu.scanResponse; int number_returned = *req->numberOfTermsRequested; int position_returned = *req->preferredPositionInResponse; - resp->positionOfTerm = odr_intdup(odr, position_returned); - resp->numberOfEntriesReturned = odr_intdup(odr, number_returned); - resp->entries->num_entries = number_returned; resp->entries->entries = (Z_Entry**) odr_malloc(odr, sizeof(Z_Entry*) * number_returned); int i; - + + int lbefore = entries_before.size(); + if (lbefore < position_returned-1) + position_returned = lbefore+1; + ScanTermInfoList::iterator it = entries_before.begin(); - for (i = 0; ientries->entries[i] = it->get_entry(odr); + resp->entries->entries[position_returned-2-i] = it->get_entry(odr); } + it = entries_after.begin(); - for (i = position_returned-1; ientries->entries[i] = it->get_entry(odr); } + + number_returned = i; + + resp->positionOfTerm = odr_intdup(odr, position_returned); + resp->numberOfEntriesReturned = odr_intdup(odr, number_returned); + resp->entries->num_entries = number_returned; + package.response() = f_apdu; } } @@ -994,7 +1047,7 @@ void yf::Multi::process(Package &package) const Z_APDU *apdu = gdu->u.z3950; if (apdu->which == Z_APDU_initRequest) { - yp2::odr odr; + mp::odr odr; package.response() = odr.create_close( apdu, @@ -1017,7 +1070,7 @@ void yf::Multi::process(Package &package) const } else { - yp2::odr odr; + mp::odr odr; package.response() = odr.create_close( apdu, Z_Close_protocolError, @@ -1029,7 +1082,7 @@ void yf::Multi::process(Package &package) const m_p->release_frontend(package); } -void yp2::filter::Multi::configure(const xmlNode * ptr) +void mp::filter::Multi::configure(const xmlNode * ptr) { for (ptr = ptr->children; ptr; ptr = ptr->next) { @@ -1037,8 +1090,8 @@ void yp2::filter::Multi::configure(const xmlNode * ptr) continue; if (!strcmp((const char *) ptr->name, "target")) { - std::string route = yp2::xml::get_route(ptr); - std::string target = yp2::xml::get_text(ptr); + std::string route = mp::xml::get_route(ptr); + std::string target = mp::xml::get_text(ptr); std::cout << "route=" << route << " target=" << target << "\n"; m_p->m_target_route[target] = route; } @@ -1052,18 +1105,18 @@ void yp2::filter::Multi::configure(const xmlNode * ptr) if (v_node->type != XML_ELEMENT_NODE) continue; - if (yp2::xml::is_element_yp2(v_node, "vhost")) - vhost = yp2::xml::get_text(v_node); - else if (yp2::xml::is_element_yp2(v_node, "target")) - targets.push_back(yp2::xml::get_text(v_node)); + if (mp::xml::is_element_yp2(v_node, "vhost")) + vhost = mp::xml::get_text(v_node); + else if (mp::xml::is_element_yp2(v_node, "target")) + targets.push_back(mp::xml::get_text(v_node)); else - throw yp2::filter::FilterException + throw mp::filter::FilterException ("Bad element " + std::string((const char *) v_node->name) + " in virtual section" ); } - std::string route = yp2::xml::get_route(ptr); + std::string route = mp::xml::get_route(ptr); add_map_host2hosts(vhost, targets, route); std::list::const_iterator it; for (it = targets.begin(); it != targets.end(); it++) @@ -1074,7 +1127,7 @@ void yp2::filter::Multi::configure(const xmlNode * ptr) } else { - throw yp2::filter::FilterException + throw mp::filter::FilterException ("Bad element " + std::string((const char *) ptr->name) + " in virt_db filter"); @@ -1082,13 +1135,13 @@ void yp2::filter::Multi::configure(const xmlNode * ptr) } } -static yp2::filter::Base* filter_creator() +static mp::filter::Base* filter_creator() { - return new yp2::filter::Multi; + return new mp::filter::Multi; } extern "C" { - struct yp2_filter_struct yp2_filter_multi = { + struct metaproxy_1_filter_struct metaproxy_1_filter_multi = { 0, "multi", filter_creator