X-Git-Url: http://lists.indexdata.com/cgi-bin?a=blobdiff_plain;f=src%2Ffilter_multi.cpp;h=b412bb4b59e7ec760f02b9628ae37acee4d68e14;hb=872baf038ffe10f670ba45082c6911201e2ac4cb;hp=a339959e920023138dff6146983cdc24f4f0cdc2;hpb=992092493a6c094605d83cd6c5823614f384a779;p=metaproxy-moved-to-github.git diff --git a/src/filter_multi.cpp b/src/filter_multi.cpp index a339959..b412bb4 100644 --- a/src/filter_multi.cpp +++ b/src/filter_multi.cpp @@ -1,4 +1,4 @@ -/* $Id: filter_multi.cpp,v 1.9 2006-01-18 14:10:47 adam Exp $ +/* $Id: filter_multi.cpp,v 1.14 2006-02-02 11:33:46 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -92,7 +92,7 @@ namespace yp2 { }; class Multi::Rep { friend class Multi; - friend class Frontend; + friend struct Frontend; FrontendPtr get_frontend(Package &package); void release_frontend(Package &package); @@ -240,14 +240,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 +252,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) { - PresentJob job; - job.m_backend = bsit->m_backend; - job.m_pos = *psit; - job.m_inside_pos = *esit; - jobs.push_back(job); - (*esit)++; - fetched++; + more = false; + break; + } + if (*psit <= bsit->m_count) + { + 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++; } } @@ -766,7 +806,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; @@ -786,7 +825,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); @@ -807,6 +845,23 @@ void yf::Multi::Frontend::scan2(Package &package, Z_APDU *apdu_req) Z_APDU_scanResponse) { Z_ScanResponse *res = gdu->u.z3950->u.scanResponse; + + if (res->entries && res->entries->nonsurrogateDiagnostics) + { + // failure + yp2::odr odr; + Z_APDU *f_apdu = odr.create_scanResponse(apdu_req, 1, 0); + Z_ScanResponse *f_res = f_apdu->u.scanResponse; + + f_res->entries->nonsurrogateDiagnostics = + res->entries->nonsurrogateDiagnostics; + f_res->entries->num_nonsurrogateDiagnostics = + res->entries->num_nonsurrogateDiagnostics; + + package.response() = f_apdu; + return; + } + if (res->entries && res->entries->entries) { Z_Entry **entries = res->entries->entries; @@ -856,7 +911,11 @@ void yf::Multi::Frontend::scan2(Package &package, Z_APDU *apdu_req) } } // after - for (i = position-1; inumberOfTermsRequested; 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; } }