X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fyaz-proxy.cpp;h=aa385f88a98f835013e74b91683f87760ccd7a49;hb=5053dee0c4d74ee87d8068fc1230eb721262e786;hp=03b8228409e4b75726d732d026dd2b108d739e18;hpb=8c594d2cb1d5f9a3042883763fbdf846ba0eef70;p=yazpp-moved-to-github.git diff --git a/src/yaz-proxy.cpp b/src/yaz-proxy.cpp index 03b8228..aa385f8 100644 --- a/src/yaz-proxy.cpp +++ b/src/yaz-proxy.cpp @@ -2,7 +2,7 @@ * Copyright (c) 1998-2003, Index Data. * See the file LICENSE for details. * - * $Id: yaz-proxy.cpp,v 1.39 2003-06-09 22:20:39 adam Exp $ + * $Id: yaz-proxy.cpp,v 1.45 2003-07-25 08:57:01 adam Exp $ */ #include @@ -145,16 +145,17 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu) c->m_init_flag = 0; c->m_last_ok = 0; + c->m_cache.clear(); c->m_last_resultCount = 0; c->m_sr_transform = 0; c->m_waiting = 0; + c->m_resultSetStartPoint = 0; c->timeout(m_idletime); } c->m_seqno = parent->m_seqno; if (c->m_server && c->m_server != this) c->m_server->m_client = 0; c->m_server = this; - c->m_seqno = parent->m_seqno; (parent->m_seqno)++; yaz_log (LOG_DEBUG, "get_client 1 %p %p", this, c); return c; @@ -179,12 +180,14 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu) // found it in cache c = cc; + yaz_log (LOG_LOG, "Reuse session %d to %d %s", + c->m_seqno, parent->m_seqno, c->get_hostname()); + c->m_seqno = parent->m_seqno; assert(c->m_server == 0); c->m_server = this; - c->m_seqno = parent->m_seqno; + (parent->m_seqno)++; - yaz_log (LOG_LOG, "get_client 10 %p %p", this, c); return c; } } @@ -216,7 +219,8 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu) Yaz_ProxyClient *c_min = 0; int min_seq = -1; int no_of_clients = 0; - yaz_log (LOG_LOG, "Existing sessions"); + if (parent->m_clientPool) + yaz_log (LOG_LOG, "Existing sessions"); for (c = parent->m_clientPool; c; c = c->m_next) { yaz_log (LOG_LOG, " Session %-3d wait=%d %s", c->m_seqno, @@ -241,8 +245,8 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu) } else { - yaz_log (LOG_LOG, "Reuse session %d to %d", - c->m_seqno, parent->m_seqno); + yaz_log (LOG_LOG, "Move session %d to %d %s", + c->m_seqno, parent->m_seqno, c->get_hostname()); if (cookie) strcpy (c->m_cookie, cookie); else @@ -279,8 +283,10 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu) c->m_init_flag = 0; c->m_last_resultCount = 0; c->m_last_ok = 0; + c->m_cache.clear(); c->m_sr_transform = 0; c->m_waiting = 0; + c->m_resultSetStartPoint = 0; c->timeout(20); (parent->m_seqno)++; @@ -291,10 +297,43 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu) Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu) { - if (apdu->which != Z_APDU_searchRequest) - return apdu; if (*m_parent->m_optimize == '0') return apdu; // don't optimize result sets.. + if (apdu->which == Z_APDU_presentRequest) + { + Z_PresentRequest *pr = apdu->u.presentRequest; + Z_NamePlusRecordList *npr; + int toget = *pr->numberOfRecordsRequested; + int start = *pr->resultSetStartPoint; + + if (m_client->m_last_resultSetId && + !strcmp(m_client->m_last_resultSetId, pr->resultSetId)) + { + if (m_client->m_cache.lookup (odr_encode(), &npr, start, toget, + pr->preferredRecordSyntax, + pr->recordComposition)) + { + yaz_log (LOG_LOG, "Returned cache records for present request"); + Z_APDU *new_apdu = create_Z_PDU(Z_APDU_presentResponse); + new_apdu->u.presentResponse->referenceId = pr->referenceId; + + new_apdu->u.presentResponse->numberOfRecordsReturned + = odr_intdup(odr_encode(), toget); + + new_apdu->u.presentResponse->records = (Z_Records*) + odr_malloc(odr_encode(), sizeof(Z_Records)); + new_apdu->u.presentResponse->records->which = Z_Records_DBOSD; + new_apdu->u.presentResponse->records->u.databaseOrSurDiagnostics = npr; + new_apdu->u.presentResponse->nextResultSetPosition = + odr_intdup(odr_encode(), start+toget); + send_Z_PDU(new_apdu); + return 0; + } + } + } + + if (apdu->which != Z_APDU_searchRequest) + return apdu; Z_SearchRequest *sr = apdu->u.searchRequest; Yaz_Z_Query *this_query = new Yaz_Z_Query; Yaz_Z_Databases this_databases; @@ -313,27 +352,60 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu) if (m_client->m_last_resultCount > *sr->smallSetUpperBound && m_client->m_last_resultCount < *sr->largeSetLowerBound) { - // medium Set - // send present request (medium size) - yaz_log (LOG_LOG, "Optimizing search for medium set"); - Z_APDU *new_apdu = create_Z_PDU(Z_APDU_presentRequest); - Z_PresentRequest *pr = new_apdu->u.presentRequest; - pr->referenceId = sr->referenceId; - pr->resultSetId = sr->resultSetName; - pr->preferredRecordSyntax = sr->preferredRecordSyntax; - if (*sr->mediumSetPresentNumber < m_client->m_last_resultCount) - *pr->numberOfRecordsRequested = *sr->mediumSetPresentNumber; - else - *pr->numberOfRecordsRequested = m_client->m_last_resultCount; + Z_NamePlusRecordList *npr; + int toget = *sr->mediumSetPresentNumber; + Z_RecordComposition *comp = 0; + + if (toget > m_client->m_last_resultCount) + toget = m_client->m_last_resultCount; + if (sr->mediumSetElementSetNames) { - pr->recordComposition = (Z_RecordComposition *) + comp = (Z_RecordComposition *) odr_malloc(odr_encode(), sizeof(Z_RecordComposition)); - pr->recordComposition->which = Z_RecordComp_simple; - pr->recordComposition->u.simple = sr->mediumSetElementSetNames; + comp->which = Z_RecordComp_simple; + comp->u.simple = sr->mediumSetElementSetNames; + } + + if (m_client->m_cache.lookup (odr_encode(), &npr, 1, toget, + sr->preferredRecordSyntax, comp)) + { + yaz_log (LOG_LOG, "Returned cache records for medium set"); + Z_APDU *new_apdu = create_Z_PDU(Z_APDU_searchResponse); + new_apdu->u.searchResponse->referenceId = sr->referenceId; + new_apdu->u.searchResponse->resultCount = + &m_client->m_last_resultCount; + + new_apdu->u.searchResponse->numberOfRecordsReturned + = odr_intdup(odr_encode(), toget); + + new_apdu->u.searchResponse->presentStatus = + odr_intdup(odr_encode(), Z_PresentStatus_success); + new_apdu->u.searchResponse->records = (Z_Records*) + odr_malloc(odr_encode(), sizeof(Z_Records)); + new_apdu->u.searchResponse->records->which = Z_Records_DBOSD; + new_apdu->u.searchResponse->records->u.databaseOrSurDiagnostics = npr; + new_apdu->u.searchResponse->nextResultSetPosition = + odr_intdup(odr_encode(), toget+1); + send_Z_PDU(new_apdu); + return 0; + } + else + { + // medium Set + // send present request (medium size) + yaz_log (LOG_LOG, "Optimizing search for medium set"); + + Z_APDU *new_apdu = create_Z_PDU(Z_APDU_presentRequest); + Z_PresentRequest *pr = new_apdu->u.presentRequest; + pr->referenceId = sr->referenceId; + pr->resultSetId = sr->resultSetName; + pr->preferredRecordSyntax = sr->preferredRecordSyntax; + *pr->numberOfRecordsRequested = toget; + pr->recordComposition = comp; + m_client->m_sr_transform = 1; + return new_apdu; } - m_client->m_sr_transform = 1; - return new_apdu; } else if (m_client->m_last_resultCount >= *sr->largeSetLowerBound || m_client->m_last_resultCount <= 0) @@ -349,24 +421,56 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu) } else { + Z_NamePlusRecordList *npr; + int toget = m_client->m_last_resultCount; + Z_RecordComposition *comp = 0; // small set // send a present request (small set) - yaz_log (LOG_LOG, "Optimizing search for small set"); - Z_APDU *new_apdu = create_Z_PDU(Z_APDU_presentRequest); - Z_PresentRequest *pr = new_apdu->u.presentRequest; - pr->referenceId = sr->referenceId; - pr->resultSetId = sr->resultSetName; - pr->preferredRecordSyntax = sr->preferredRecordSyntax; - *pr->numberOfRecordsRequested = m_client->m_last_resultCount; + if (sr->smallSetElementSetNames) { - pr->recordComposition = (Z_RecordComposition *) + comp = (Z_RecordComposition *) odr_malloc(odr_encode(), sizeof(Z_RecordComposition)); - pr->recordComposition->which = Z_RecordComp_simple; - pr->recordComposition->u.simple = sr->smallSetElementSetNames; + comp->which = Z_RecordComp_simple; + comp->u.simple = sr->smallSetElementSetNames; + } + + if (m_client->m_cache.lookup (odr_encode(), &npr, 1, toget, + sr->preferredRecordSyntax, comp)) + { + yaz_log (LOG_LOG, "Returned cache records for small set"); + Z_APDU *new_apdu = create_Z_PDU(Z_APDU_searchResponse); + new_apdu->u.searchResponse->referenceId = sr->referenceId; + new_apdu->u.searchResponse->resultCount = + &m_client->m_last_resultCount; + + new_apdu->u.searchResponse->numberOfRecordsReturned + = odr_intdup(odr_encode(), toget); + + new_apdu->u.searchResponse->presentStatus = + odr_intdup(odr_encode(), Z_PresentStatus_success); + new_apdu->u.searchResponse->records = (Z_Records*) + odr_malloc(odr_encode(), sizeof(Z_Records)); + new_apdu->u.searchResponse->records->which = Z_Records_DBOSD; + new_apdu->u.searchResponse->records->u.databaseOrSurDiagnostics = npr; + new_apdu->u.searchResponse->nextResultSetPosition = + odr_intdup(odr_encode(), toget+1); + send_Z_PDU(new_apdu); + return 0; + } + else + { + yaz_log (LOG_LOG, "Optimizing search for small set"); + Z_APDU *new_apdu = create_Z_PDU(Z_APDU_presentRequest); + Z_PresentRequest *pr = new_apdu->u.presentRequest; + pr->referenceId = sr->referenceId; + pr->resultSetId = sr->resultSetName; + pr->preferredRecordSyntax = sr->preferredRecordSyntax; + *pr->numberOfRecordsRequested = toget; + pr->recordComposition = comp; + m_client->m_sr_transform = 1; + return new_apdu; } - m_client->m_sr_transform = 1; - return new_apdu; } } else @@ -374,6 +478,8 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu) delete m_client->m_last_query; m_client->m_last_query = this_query; m_client->m_last_ok = 0; + m_client->m_cache.clear(); + m_client->m_resultSetStartPoint = 0; xfree (m_client->m_last_resultSetId); m_client->m_last_resultSetId = xstrdup (sr->resultSetName); @@ -400,6 +506,24 @@ static const char *apdu_name(Z_APDU *apdu) return "presentRequest"; case Z_APDU_presentResponse: return "presentResponse"; + case Z_APDU_deleteResultSetRequest: + return "deleteResultSetRequest"; + case Z_APDU_deleteResultSetResponse: + return "deleteResultSetResponse"; + case Z_APDU_scanRequest: + return "scanRequest"; + case Z_APDU_scanResponse: + return "scanResponse"; + case Z_APDU_sortRequest: + return "sortRequest"; + case Z_APDU_sortResponse: + return "sortResponse"; + case Z_APDU_extendedServicesRequest: + return "extendedServicesRequest"; + case Z_APDU_extendedServicesResponse: + return "extendedServicesResponse"; + case Z_APDU_close: + return "close"; } return "other"; } @@ -422,7 +546,7 @@ void Yaz_Proxy::recv_Z_PDU(Z_APDU *apdu) { Z_APDU *apdu = m_client->m_initResponse; apdu->u.initResponse->otherInfo = 0; - if (m_client->m_cookie) + if (m_client->m_cookie && *m_client->m_cookie) set_otherInformationString(apdu, VAL_COOKIE, 1, m_client->m_cookie); send_Z_PDU(apdu); @@ -443,6 +567,15 @@ void Yaz_Proxy::recv_Z_PDU(Z_APDU *apdu) if (oi) *oi = 0; + if (apdu->which == Z_APDU_presentRequest && + m_client->m_resultSetStartPoint == 0) + { + Z_PresentRequest *pr = apdu->u.presentRequest; + m_client->m_resultSetStartPoint = *pr->resultSetStartPoint; + m_client->m_cache.copy_presentRequest(apdu->u.presentRequest); + } else { + m_client->m_resultSetStartPoint = 0; + } if (m_client->send_Z_PDU(apdu) < 0) { delete m_client; @@ -460,7 +593,7 @@ void Yaz_Proxy::connectNotify() void Yaz_Proxy::shutdown() { // only keep if keep_alive flag is set... - if (m_keepalive && m_client) + if (m_keepalive && m_client && m_client->m_waiting == 0) { yaz_log (LOG_LOG, "shutdown (client to proxy) keepalive %s", m_client->get_hostname()); @@ -557,6 +690,7 @@ Yaz_ProxyClient::Yaz_ProxyClient(IYaz_PDU_Observable *the_PDU_Observable) : m_waiting = 0; m_init_odr = odr_createmem (ODR_DECODE); m_initResponse = 0; + m_resultSetStartPoint = 0; } const char *Yaz_Proxy::option(const char *name, const char *value) @@ -586,25 +720,43 @@ void Yaz_ProxyClient::recv_Z_PDU(Z_APDU *apdu) } if (apdu->which == Z_APDU_searchResponse) { - m_last_resultCount = *apdu->u.searchResponse->resultCount; - int status = *apdu->u.searchResponse->searchStatus; - if (status && - (!apdu->u.searchResponse->records || - apdu->u.searchResponse->records->which == Z_Records_DBOSD)) + Z_SearchResponse *sr = apdu->u.searchResponse; + m_last_resultCount = *sr->resultCount; + int status = *sr->searchStatus; + if (status && (!sr->records || sr->records->which == Z_Records_DBOSD)) + { m_last_ok = 1; + + if (sr->records && sr->records->which == Z_Records_DBOSD) + { + m_cache.add(odr_decode(), + sr->records->u.databaseOrSurDiagnostics, 1, + *sr->resultCount); + } + } } - if (apdu->which == Z_APDU_presentResponse && m_sr_transform) + if (apdu->which == Z_APDU_presentResponse) { - m_sr_transform = 0; Z_PresentResponse *pr = apdu->u.presentResponse; - Z_APDU *new_apdu = create_Z_PDU(Z_APDU_searchResponse); - Z_SearchResponse *sr = new_apdu->u.searchResponse; - sr->referenceId = pr->referenceId; - *sr->resultCount = m_last_resultCount; - sr->records = pr->records; - sr->nextResultSetPosition = pr->nextResultSetPosition; - sr->numberOfRecordsReturned = pr->numberOfRecordsReturned; - apdu = new_apdu; + if (m_sr_transform) + { + m_sr_transform = 0; + Z_APDU *new_apdu = create_Z_PDU(Z_APDU_searchResponse); + Z_SearchResponse *sr = new_apdu->u.searchResponse; + sr->referenceId = pr->referenceId; + *sr->resultCount = m_last_resultCount; + sr->records = pr->records; + sr->nextResultSetPosition = pr->nextResultSetPosition; + sr->numberOfRecordsReturned = pr->numberOfRecordsReturned; + apdu = new_apdu; + } + if (pr->records->which == Z_Records_DBOSD && m_resultSetStartPoint) + { + m_cache.add(odr_decode(), + pr->records->u.databaseOrSurDiagnostics, + m_resultSetStartPoint, -1); + m_resultSetStartPoint = 0; + } } if (m_cookie && *m_cookie) set_otherInformationString (apdu, VAL_COOKIE, 1, m_cookie); @@ -613,4 +765,8 @@ void Yaz_ProxyClient::recv_Z_PDU(Z_APDU *apdu) yaz_log (LOG_LOG, "Sending %s to client", apdu_name(apdu)); m_server->send_Z_PDU(apdu); } + if (apdu->which == Z_APDU_close) + { + shutdown(); + } }