+Proxy caches records.
+
Various C++ fixes for GCC 3.2.
Proxy now closes socket when Close PDU is received from target.
* Copyright (c) 1998-2003, Index Data.
* See the file LICENSE for details.
*
- * $Id: proxy.h,v 1.4 2003-07-18 13:27:20 adam Exp $
+ * $Id: proxy.h,v 1.5 2003-07-25 08:57:01 adam Exp $
*/
#include <yaz++/z-assoc.h>
public:
Yaz_RecordCache ();
~Yaz_RecordCache ();
- void add (ODR o, Z_NamePlusRecordList *npr, int start);
+ void add (ODR o, Z_NamePlusRecordList *npr, int start, int hits);
+
int lookup (ODR o, Z_NamePlusRecordList **npr, int start, int num,
- Odr_oid *syntax);
+ Odr_oid *syntax, Z_RecordComposition *comp);
void clear();
+
+ void copy_searchRequest(Z_SearchRequest *sr);
+ void copy_presentRequest(Z_PresentRequest *pr);
private:
NMEM m_mem;
Yaz_RecordCache_Entry *m_entries;
+ Z_SearchRequest *m_searchRequest;
+ Z_PresentRequest *m_presentRequest;
+ int match (Yaz_RecordCache_Entry *entry,
+ Odr_oid *syntax, int offset,
+ Z_RecordComposition *comp);
};
/// Private class
* Copyright (c) 1998-2003, Index Data.
* See the file LICENSE for details.
*
- * $Id: yaz-proxy.cpp,v 1.44 2003-07-18 13:27:20 adam Exp $
+ * $Id: yaz-proxy.cpp,v 1.45 2003-07-25 08:57:01 adam Exp $
*/
#include <assert.h>
int toget = *pr->numberOfRecordsRequested;
int start = *pr->resultSetStartPoint;
- if (!strcmp(m_client->m_last_resultSetId, pr->resultSetId))
+ 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->preferredRecordSyntax,
+ pr->recordComposition))
{
yaz_log (LOG_LOG, "Returned cache records for present request");
Z_APDU *new_apdu = create_Z_PDU(Z_APDU_presentResponse);
{
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)
+ {
+ comp = (Z_RecordComposition *)
+ odr_malloc(odr_encode(), sizeof(Z_RecordComposition));
+ comp->which = Z_RecordComp_simple;
+ comp->u.simple = sr->mediumSetElementSetNames;
+ }
if (m_client->m_cache.lookup (odr_encode(), &npr, 1, toget,
- sr->preferredRecordSyntax))
+ 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->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;
pr->resultSetId = sr->resultSetName;
pr->preferredRecordSyntax = sr->preferredRecordSyntax;
*pr->numberOfRecordsRequested = toget;
- if (sr->mediumSetElementSetNames)
- {
- pr->recordComposition = (Z_RecordComposition *)
- odr_malloc(odr_encode(), sizeof(Z_RecordComposition));
- pr->recordComposition->which = Z_RecordComp_simple;
- pr->recordComposition->u.simple =
- sr->mediumSetElementSetNames;
- }
+ pr->recordComposition = comp;
m_client->m_sr_transform = 1;
return new_apdu;
}
{
Z_NamePlusRecordList *npr;
int toget = m_client->m_last_resultCount;
+ Z_RecordComposition *comp = 0;
// small set
// send a present request (small set)
+
+ if (sr->smallSetElementSetNames)
+ {
+ comp = (Z_RecordComposition *)
+ odr_malloc(odr_encode(), sizeof(Z_RecordComposition));
+ comp->which = Z_RecordComp_simple;
+ comp->u.simple = sr->smallSetElementSetNames;
+ }
if (m_client->m_cache.lookup (odr_encode(), &npr, 1, toget,
- sr->preferredRecordSyntax))
+ 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->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;
pr->resultSetId = sr->resultSetName;
pr->preferredRecordSyntax = sr->preferredRecordSyntax;
*pr->numberOfRecordsRequested = toget;
- if (sr->smallSetElementSetNames)
- {
- pr->recordComposition = (Z_RecordComposition *)
- odr_malloc(odr_encode(), sizeof(Z_RecordComposition));
- pr->recordComposition->which = Z_RecordComp_simple;
- pr->recordComposition->u.simple = sr->smallSetElementSetNames;
- }
+ pr->recordComposition = comp;
m_client->m_sr_transform = 1;
return new_apdu;
}
{
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 (sr->records && sr->records->which == Z_Records_DBOSD)
{
m_cache.add(odr_decode(),
- sr->records->u.databaseOrSurDiagnostics, 1);
+ sr->records->u.databaseOrSurDiagnostics, 1,
+ *sr->resultCount);
}
}
}
{
m_cache.add(odr_decode(),
pr->records->u.databaseOrSurDiagnostics,
- m_resultSetStartPoint);
+ m_resultSetStartPoint, -1);
m_resultSetStartPoint = 0;
}
}
/*
- * Copyright (c) 1998-2003, Index Data.
+ * Copyright (c) 2002-2003, Index Data.
* See the file LICENSE for details.
*
- * $Id: yaz-z-cache.cpp,v 1.1 2003-07-18 13:27:20 adam Exp $
+ * $Id: yaz-z-cache.cpp,v 1.2 2003-07-25 08:57:01 adam Exp $
*/
#include <yaz/log.h>
struct Yaz_RecordCache_Entry {
int m_offset;
Z_NamePlusRecord *m_record;
+ Z_RecordComposition *m_comp;
Yaz_RecordCache_Entry *m_next;
};
-
Yaz_RecordCache::Yaz_RecordCache ()
{
m_mem = nmem_create();
m_entries = 0;
+ m_presentRequest = 0;
+ m_searchRequest = 0;
}
Yaz_RecordCache::~Yaz_RecordCache ()
nmem_destroy(m_mem);
m_mem = nmem_create();
m_entries = 0;
+ m_presentRequest = 0;
+ m_searchRequest = 0;
}
-#if 0
-void Yaz_RecordCache::prepare_present(Z_RecordComposition *comp)
+void Yaz_RecordCache::copy_searchRequest(Z_SearchRequest *sr)
{
- if (!comp)
- m_recordComposition = 0;
- else
+ ODR encode = odr_createmem(ODR_ENCODE);
+ ODR decode = odr_createmem(ODR_DECODE);
+
+ m_searchRequest = 0;
+ m_presentRequest = 0;
+ int v = z_SearchRequest (encode, &sr, 1, 0);
+ if (v)
{
- m_recordComposition = nmem_malloc(m_mem, sizeof(*m_recordComposition));
- m_recordComposition->which = comp->which;
- if (comp->which == Z_RecordComp_simple)
- {
- m_recordComposition->u.simple = (Z_ElementSetNames *)
- nmem_malloc(m_mem, sizeof(Z_ElementSetNames));
- }
+ int len;
+ char *buf = odr_getbuf(encode, &len, 0);
+ odr_setbuf(decode, buf, len, 0);
+ z_SearchRequest(decode, &m_searchRequest, 1, 0);
+ nmem_transfer(m_mem, decode->mem);
}
+ odr_destroy(encode);
+ odr_destroy(decode);
+}
+void Yaz_RecordCache::copy_presentRequest(Z_PresentRequest *pr)
+{
+ ODR encode = odr_createmem(ODR_ENCODE);
+ ODR decode = odr_createmem(ODR_DECODE);
+
+ m_searchRequest = 0;
+ m_presentRequest = 0;
+ int v = z_PresentRequest (encode, &pr, 1, 0);
+ if (v)
+ {
+ int len;
+ char *buf = odr_getbuf(encode, &len, 0);
+ odr_setbuf(decode, buf, len, 0);
+ z_PresentRequest(decode, &m_presentRequest, 1, 0);
+ nmem_transfer(m_mem, decode->mem);
+ }
+ odr_destroy(encode);
+ odr_destroy(decode);
}
-#endif
-void Yaz_RecordCache::add (ODR o, Z_NamePlusRecordList *npr, int start)
+void Yaz_RecordCache::add (ODR o, Z_NamePlusRecordList *npr, int start,
+ int hits)
{
+ // Build appropriate compspec for this response
+ Z_RecordComposition *comp = 0;
+ if (hits == -1 && m_presentRequest)
+ comp = m_presentRequest->recordComposition;
+ else if (hits > 0 && m_searchRequest)
+ {
+ Z_ElementSetNames *esn;
+
+ if (hits <= *m_searchRequest->smallSetUpperBound)
+ esn = m_searchRequest->smallSetElementSetNames;
+ else
+ esn = m_searchRequest->mediumSetElementSetNames;
+ comp = (Z_RecordComposition *) nmem_malloc(m_mem, sizeof(*comp));
+ comp->which = Z_RecordComp_simple;
+ comp->u.simple = esn;
+ }
+
+ // Z_NamePlusRecordList *npr to be owned by m_mem..
NMEM tmp_mem = odr_extract_mem(o);
nmem_transfer(m_mem, tmp_mem);
nmem_destroy(tmp_mem);
-
+
+ // Insert individual records in cache
int i;
for (i = 0; i<npr->num_records; i++)
{
Yaz_RecordCache_Entry *entry = (Yaz_RecordCache_Entry *)
nmem_malloc(m_mem, sizeof(*entry));
entry->m_record = npr->records[i];
+ entry->m_comp = comp;
entry->m_offset = i + start;
entry->m_next = m_entries;
m_entries = entry;
}
}
+int Yaz_RecordCache::match (Yaz_RecordCache_Entry *entry,
+ Odr_oid *syntax, int offset,
+ Z_RecordComposition *comp)
+{
+ // See if our compspec match...
+ int match = 0;
+ ODR o1 = odr_createmem(ODR_ENCODE);
+ ODR o2 = odr_createmem(ODR_ENCODE);
+
+ z_RecordComposition(o1, &comp, 1, 0);
+ z_RecordComposition(o2, &entry->m_comp, 1, 0);
+
+ int len1 = -1;
+ char *buf1 = odr_getbuf(o1, &len1, 0);
+ int len2 = -1;
+ char *buf2 = odr_getbuf(o2, &len2, 0);
+
+ yaz_log(LOG_LOG, "buf1=%p buf2=%p len1=%d len2=%d", buf1, buf2, len1, len2);
+ if (buf1 && buf2 && len1 && len1 == len2 && !memcmp(buf1, buf2, len1))
+ match = 1;
+ else if (!buf1 && !buf2 && !len1 && !len2)
+ match = 1;
+
+ odr_destroy(o1);
+ odr_destroy(o2);
+ if (!match)
+ return 0;
+
+ // See if offset, OID match..
+ if (entry->m_offset == offset &&
+ entry->m_record->which == Z_NamePlusRecord_databaseRecord &&
+ !oid_oidcmp(entry->m_record->u.databaseRecord->direct_reference,
+ syntax))
+ return 1;
+ return 0;
+}
+
int Yaz_RecordCache::lookup (ODR o, Z_NamePlusRecordList **npr,
int start, int num,
- Odr_oid *syntax)
+ Odr_oid *syntax,
+ Z_RecordComposition *comp)
{
int i;
yaz_log(LOG_LOG, "cache lookup start=%d num=%d", start, num);
{
Yaz_RecordCache_Entry *entry = m_entries;
for(; entry; entry = entry->m_next)
- if (entry->m_offset == start + i &&
- entry->m_record->which == Z_NamePlusRecord_databaseRecord &&
- !oid_oidcmp(entry->m_record->u.databaseRecord->direct_reference,
- syntax))
+ if (match(entry, syntax, start+i, comp))
break;
if (!entry)
return 0;
{
Yaz_RecordCache_Entry *entry = m_entries;
for(; entry; entry = entry->m_next)
- if (entry->m_offset == start + i &&
- entry->m_record->which == Z_NamePlusRecord_databaseRecord &&
- !oid_oidcmp(entry->m_record->u.databaseRecord->direct_reference,
- syntax))
+ if (match(entry, syntax, start+i, comp))
break;
if (!entry)
return 0;