Use compspec in match in record cache lookup
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 25 Jul 2003 08:57:01 +0000 (08:57 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 25 Jul 2003 08:57:01 +0000 (08:57 +0000)
ChangeLog
include/yaz++/proxy.h
src/yaz-proxy.cpp
src/yaz-z-cache.cpp

index c66de04..e0d5440 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+Proxy caches records.
+
 Various C++ fixes for GCC 3.2.
 
 Proxy now closes socket when Close PDU is received from target.
index dcc71f8..a28601b 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -17,13 +17,22 @@ class YAZ_EXPORT Yaz_RecordCache {
  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
index 401d1c7..aa385f8 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -306,10 +306,12 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
        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);
@@ -352,12 +354,21 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
        {
            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);
@@ -367,7 +378,9 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
                
                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;
@@ -389,14 +402,7 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
                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;
            }
@@ -417,11 +423,20 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *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);
@@ -432,6 +447,8 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
                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;
@@ -450,13 +467,7 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
                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;
            }
@@ -561,6 +572,7 @@ void Yaz_Proxy::recv_Z_PDU(Z_APDU *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;
     }
@@ -718,7 +730,8 @@ void Yaz_ProxyClient::recv_Z_PDU(Z_APDU *apdu)
            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);
            }
        }
     }
@@ -741,7 +754,7 @@ void Yaz_ProxyClient::recv_Z_PDU(Z_APDU *apdu)
        {
            m_cache.add(odr_decode(),
                        pr->records->u.databaseOrSurDiagnostics,
-                       m_resultSetStartPoint);
+                       m_resultSetStartPoint, -1);
            m_resultSetStartPoint = 0;
        }
     }
index 125fdb5..9706009 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * 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 ()
@@ -31,48 +33,130 @@ void Yaz_RecordCache::clear ()
     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);
@@ -81,10 +165,7 @@ int Yaz_RecordCache::lookup (ODR o, Z_NamePlusRecordList **npr,
     {
        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;
@@ -97,10 +178,7 @@ int Yaz_RecordCache::lookup (ODR o, Z_NamePlusRecordList **npr,
     {
        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;