New option -o <level> that optimization level (0 = no optimization).
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 6 Nov 2001 17:08:05 +0000 (17:08 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 6 Nov 2001 17:08:05 +0000 (17:08 +0000)
Database names mutch match too before doing result set optimization.

README.txt
include/yaz++/yaz-proxy.h
include/yaz++/yaz-z-databases.h [new file with mode: 0644]
src/Makefile.am
src/yaz-my-server.cpp
src/yaz-pdu-assoc-thread.cpp
src/yaz-pdu-assoc.cpp
src/yaz-proxy-main.cpp
src/yaz-proxy.cpp
src/yaz-z-databases.cpp [new file with mode: 0644]

index e43628c..27fd545 100644 (file)
@@ -1,6 +1,6 @@
 YAZ++ - A C++ library for YAZ
 
-$Id: README.txt,v 1.9 2001-04-25 19:40:18 adam Exp $
+$Id: README.txt,v 1.10 2001-11-06 17:08:05 adam Exp $
  
 o Introduction
 
@@ -18,7 +18,7 @@ example applications:
   yaz-my-server      basic server
   yaz-proxy          not-so-basic proxy server
 
-Directory structure of the YAZ++ package.
+Directory structure of the YAZ++ package:
 
   -- src (C++ source)
   -- include/yaz++ (C++ headers) 
index e4f3e5e..b0ad495 100644 (file)
@@ -2,11 +2,12 @@
  * Copyright (c) 1998-2000, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-proxy.h,v 1.3 2001-03-26 14:43:49 adam Exp $
+ * $Id: yaz-proxy.h,v 1.4 2001-11-06 17:08:05 adam Exp $
  */
 
 #include <yaz++/yaz-z-assoc.h>
 #include <yaz++/yaz-z-query.h>
+#include <yaz++/yaz-z-databases.h>
 
 class Yaz_Proxy;
 
@@ -28,6 +29,7 @@ class YAZ_EXPORT Yaz_ProxyClient : public Yaz_Z_Assoc {
     Yaz_ProxyClient **m_prev;
     int m_init_flag;
     Yaz_Z_Query *m_last_query;
+    Yaz_Z_Databases m_last_databases;
     int m_last_resultCount;
     int m_sr_transform;
     int m_seqno;
@@ -52,6 +54,7 @@ class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc {
     int m_keepalive;
     char *m_proxyTarget;
     long m_seed;
+    char *m_optimize;
  public:
     Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable);
     ~Yaz_Proxy();
@@ -61,6 +64,7 @@ class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc {
     void failNotify();
     void timeoutNotify();
     void connectNotify();
+    const char *option(const char *name, const char *value);
     void set_proxyTarget(const char *target);
     char *get_proxyTarget() { return m_proxyTarget; };
     void set_max_clients(int m) { m_max_clients = m; };
diff --git a/include/yaz++/yaz-z-databases.h b/include/yaz++/yaz-z-databases.h
new file mode 100644 (file)
index 0000000..f750c4d
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2001, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: yaz-z-databases.h,v 1.1 2001-11-06 17:08:05 adam Exp $
+ */
+
+#include <yaz/proto.h>
+
+/** Z39.50 Databases list
+ */
+class YAZ_EXPORT Yaz_Z_Databases {
+public:
+/// Make Query from rpn string
+    Yaz_Z_Databases();
+    ~Yaz_Z_Databases();
+    void set (int num, const char **db);
+    void get (NMEM n, int *num, char ***db);
+    void get (ODR o, int *num, char ***db);
+    int match (Yaz_Z_Databases &db);
+    int match (int num, const char **db);
+ private:
+    char **m_list;
+    int m_num;
+    NMEM nmem;
+};
index 07bc103..bccdfab 100644 (file)
@@ -1,4 +1,4 @@
-## $Id: Makefile.am,v 1.8 2001-11-04 22:36:21 adam Exp $
+## $Id: Makefile.am,v 1.9 2001-11-06 17:08:05 adam Exp $
 
 CXXFLAGS = $(YAZINC) -I$(srcdir)/../include
 
@@ -7,7 +7,7 @@ lib_LTLIBRARIES = libyaz++.la
 libyaz___la_SOURCES=yaz-socket-manager.cpp yaz-pdu-assoc.cpp \
        yaz-z-assoc.cpp yaz-proxy.cpp yaz-z-query.cpp yaz-ir-assoc.cpp \
        yaz-z-server.cpp yaz-pdu-assoc-thread.cpp yaz-z-server-sr.cpp \
-       yaz-z-server-ill.cpp yaz-z-server-update.cpp
+       yaz-z-server-ill.cpp yaz-z-server-update.cpp yaz-z-databases.cpp
 
 EXTRA_DIST=yaz-z-server-ursula.cpp
 
index 6f6a490..38a3bc7 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2001, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-my-server.cpp,v 1.8 2001-11-04 22:36:21 adam Exp $
+ * $Id: yaz-my-server.cpp,v 1.9 2001-11-06 17:08:05 adam Exp $
  */
 
 #include <yaz/log.h>
@@ -258,10 +258,14 @@ int main(int argc, char **argv)
            return 1;
        }
     }
+#if YAZ_POSIX_THREADS
     if (thread_flag)
        my_PDU_Assoc = new Yaz_PDU_AssocThread(&mySocketManager);
     else
        my_PDU_Assoc = new Yaz_PDU_Assoc(&mySocketManager);
+#else
+    my_PDU_Assoc = new Yaz_PDU_Assoc(&mySocketManager);
+#endif
     
     z = new MyServer(my_PDU_Assoc);
     z->server(addr);
index 4a445fd..aadcca1 100644 (file)
@@ -2,17 +2,26 @@
  * Copyright (c) 1998-2001, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-pdu-assoc-thread.cpp,v 1.4 2001-11-04 22:36:21 adam Exp $
+ * $Id: yaz-pdu-assoc-thread.cpp,v 1.5 2001-11-06 17:08:05 adam Exp $
  */
 
 #ifdef WIN32
+#define USE_THREADS 1
+#endif
+
+#if YAZ_POSIX_THREADS
+#define USE_THREADS 1
+#endif
+
+#if USE_THREADS
+
+#ifdef WIN32
 #include <process.h>
 #else
 #include <pthread.h>
 #include <unistd.h>
 #endif
 
-
 #include <errno.h>
 #include <yaz/log.h>
 #include <yaz/tcpip.h>
@@ -20,8 +29,6 @@
 #include <yaz++/yaz-pdu-assoc.h>
 #include <yaz++/yaz-socket-manager.h>
 
-
-
 Yaz_PDU_AssocThread::Yaz_PDU_AssocThread(
     IYazSocketObservable *socketObservable)
     : Yaz_PDU_Assoc(socketObservable)
@@ -78,3 +85,4 @@ void Yaz_PDU_AssocThread::childNotify(COMSTACK cs)
        pthread_detach (tid);
 #endif
 }
+#endif
index 0ed6f29..0238d0c 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2001, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-pdu-assoc.cpp,v 1.25 2001-11-04 22:36:21 adam Exp $
+ * $Id: yaz-pdu-assoc.cpp,v 1.26 2001-11-06 17:08:05 adam Exp $
  */
 
 #include <assert.h>
@@ -286,7 +286,7 @@ void Yaz_PDU_Assoc::destroy()
 
 Yaz_PDU_Assoc::PDU_Queue::PDU_Queue(const char *buf, int len)
 {
-    m_buf = (char *) malloc (len);
+    m_buf = (char *) xmalloc (len);
     memcpy (m_buf, buf, len);
     m_len = len;
     m_next = 0;
@@ -294,7 +294,7 @@ Yaz_PDU_Assoc::PDU_Queue::PDU_Queue(const char *buf, int len)
 
 Yaz_PDU_Assoc::PDU_Queue::~PDU_Queue()
 {
-    free (m_buf);
+    xfree (m_buf);
 }
 
 int Yaz_PDU_Assoc::flush_PDU()
@@ -420,7 +420,7 @@ void Yaz_PDU_Assoc::connect(IYaz_PDU_Observer *observer,
     m_socketObservable->addObserver(cs_fileno(m_cs), this);
 
     if (res >= 0)
-    {   // Connect pending or complet
+    {   // Connect pending or complete
        m_state = Connecting;
        unsigned mask = YAZ_SOCKET_OBSERVE_EXCEPT;
        if (m_cs->io_pending & CS_WANT_WRITE)
@@ -441,8 +441,6 @@ void Yaz_PDU_Assoc::connect(IYaz_PDU_Observer *observer,
 // Single-threaded... Only useful for non-blocking handlers
 void Yaz_PDU_Assoc::childNotify(COMSTACK cs)
 {
-
     Yaz_PDU_Assoc *new_observable =
        new Yaz_PDU_Assoc (m_socketObservable, cs);
     
index 0487363..ef8214e 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2001, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-proxy-main.cpp,v 1.14 2001-11-04 22:36:21 adam Exp $
+ * $Id: yaz-proxy-main.cpp,v 1.15 2001-11-06 17:08:05 adam Exp $
  */
 
 #include <yaz/log.h>
@@ -14,7 +14,7 @@
 
 void usage(char *prog)
 {
-    fprintf (stderr, "%s: [-a log] [-c num] [-v level] [-t target] @:port\n", prog);
+    fprintf (stderr, "%s: [-a log] [-c num] [-v level] [-t target] [-o optlevel] @:port\n", prog);
     exit (1);
 }
 
@@ -26,7 +26,7 @@ int args(Yaz_Proxy *proxy, int argc, char **argv)
     char *prog = argv[0];
     int ret;
 
-    while ((ret = options("a:t:v:c:", argv, argc, &arg)) != -2)
+    while ((ret = options("o:a:t:v:c:", argv, argc, &arg)) != -2)
     {
         switch (ret)
         {
@@ -44,6 +44,9 @@ int args(Yaz_Proxy *proxy, int argc, char **argv)
         case 't':
            proxy->set_proxyTarget(arg);
            break;
+        case 'o':
+           proxy->option("optimize", arg);
+           break;
        case 'v':
            yaz_log_init_level (yaz_log_mask_str(arg));
            break;
index a73c95a..384fde6 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2001, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-proxy.cpp,v 1.28 2001-11-04 22:36:21 adam Exp $
+ * $Id: yaz-proxy.cpp,v 1.29 2001-11-06 17:08:05 adam Exp $
  */
 
 #include <assert.h>
@@ -23,11 +23,13 @@ Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable) :
     m_proxyTarget = 0;
     m_max_clients = 50;
     m_seed = time(0);
+    m_optimize = xstrdup ("1");
 }
 
 Yaz_Proxy::~Yaz_Proxy()
 {
     xfree (m_proxyTarget);
+    xfree (m_optimize);
 }
 
 void Yaz_Proxy::set_proxyTarget(const char *target)
@@ -90,34 +92,28 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
     
     get_otherInfoAPDU(apdu, &oi);
     char *cookie = get_cookie(oi);
-    yaz_log (LOG_LOG, "Yaz_Proxy::get_client cookie=%s", cookie ? cookie :
-         "null");
 
     const char *proxy_host = get_proxy(oi);
     if (proxy_host)
        set_proxyTarget(proxy_host);
-    yaz_log (LOG_LOG, "proxy_host = %s", m_proxyTarget ? m_proxyTarget:"none");
     
     // no target specified at all?
     if (!m_proxyTarget)
        return 0;
 
+    if (!strcmp(m_proxyTarget, "stop"))
+       exit (0);
     if (cookie && *cookie)
     {
-       yaz_log (LOG_LOG, "lookup of clients cookie=%s target=%s",
-             cookie, m_proxyTarget);
        Yaz_ProxyClient *cc = 0;
        
        for (c = parent->m_clientPool; c; c = c->m_next)
        {
-           yaz_log (LOG_LOG, " found client cookie = %s target=%s seqno=%d",
-                 c->m_cookie, c->get_hostname(), c->m_seqno);
            assert (c->m_prev);
            assert (*c->m_prev == c);
            if (!strcmp(cookie,c->m_cookie) &&
                !strcmp(m_proxyTarget, c->get_hostname()))
            {
-               yaz_log (LOG_LOG, "found!");
                cc = c;
            }
        }
@@ -148,7 +144,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
            c->m_server = this;
            c->m_seqno = parent->m_seqno;
            (parent->m_seqno)++;
-           yaz_log (LOG_LOG, "get_client 1 %p %p", this, c);
+           yaz_log (LOG_DEBUG, "get_client 1 %p %p", this, c);
            return c;
        }
     }
@@ -201,7 +197,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
                    delete c->m_server;
                }
                (parent->m_seqno)++;
-               yaz_log (LOG_LOG, "get_client 2 %p %p", this, c);
+               yaz_log (LOG_DEBUG, "get_client 2 %p %p", this, c);
                return c;
            }
        }
@@ -235,7 +231,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
 
        (parent->m_seqno)++;
     }
-    yaz_log (LOG_LOG, "get_client 3 %p %p", this, c);
+    yaz_log (LOG_DEBUG, "get_client 3 %p %p", this, c);
     return c;
 }
 
@@ -243,13 +239,20 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
 {
     if (apdu->which != Z_APDU_searchRequest)
        return apdu;
+    if (*m_parent->m_optimize != '1')
+        return apdu;
     Z_SearchRequest *sr = apdu->u.searchRequest;
     Yaz_Z_Query *this_query = new Yaz_Z_Query;
+    Yaz_Z_Databases this_databases;
+
+    this_databases.set(sr->num_databaseNames, (const char **)
+                       sr->databaseNames);
     
     this_query->set_Z_Query(sr->query);
     
     if (m_client->m_last_query &&
-       m_client->m_last_query->match(this_query))
+       m_client->m_last_query->match(this_query) &&
+        m_client->m_last_databases.match(this_databases))
     {
        delete this_query;
        if (m_client->m_last_resultCount > *sr->smallSetUpperBound &&
@@ -311,6 +314,8 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
        yaz_log (LOG_LOG, "Yaz_Proxy::result_set_optimize new set");
        delete m_client->m_last_query;
        m_client->m_last_query = this_query;
+        m_client->m_last_databases.set(sr->num_databaseNames,
+                                       (const char **) sr->databaseNames);
     }
     return apdu;
 }
@@ -369,29 +374,31 @@ void Yaz_Proxy::connectNotify()
 
 void Yaz_Proxy::shutdown()
 {
-    yaz_log (LOG_LOG, "shutdown (client to proxy)");
     // only keep if keep_alive flag and cookie is set...
     if (m_keepalive && m_client && m_client->m_cookie[0])
     {
-       yaz_log (LOG_LOG, "shutdown - keepalive this=%p, m_server=%p",
-            this, m_client->m_server);
        if (m_client->m_waiting == 2)
            abort();
        // Tell client (if any) that no server connection is there..
        m_client->m_server = 0;
+        yaz_log (LOG_LOG, "shutdown (client to proxy) keepalive %s", m_client->get_hostname());
     }
     else if (m_client)
     {
-       yaz_log (LOG_LOG, "deleting %p %p", this, m_client);
        if (m_client->m_waiting == 2)
            abort();
+        yaz_log (LOG_LOG, "shutdown (client to proxy) close %s", m_client->get_hostname());
        delete m_client;
     }
     else if (!m_parent)
     {
-       yaz_log (LOG_LOG, "abort %p", this);
+        yaz_log (LOG_LOG, "shutdown (client to proxy) bad state");
         abort();
     }
+    else 
+    {
+        yaz_log (LOG_LOG, "shutdown (client to proxy)");
+    }
     delete this;
 }
 
@@ -404,7 +411,7 @@ void Yaz_ProxyClient::shutdown()
 
 void Yaz_Proxy::failNotify()
 {
-    yaz_log (LOG_LOG, "connection closed by client");
+    yaz_log (LOG_LOG, "Yaz_Proxy connection closed by client");
     shutdown();
 }
 
@@ -462,6 +469,17 @@ Yaz_ProxyClient::Yaz_ProxyClient(IYaz_PDU_Observable *the_PDU_Observable) :
     m_waiting = 0;
 }
 
+const char *Yaz_Proxy::option(const char *name, const char *value)
+{
+    if (!strcmp (name, "optimize")) {
+       if (value) {
+            xfree (m_optimize);        
+           m_optimize = xstrdup (value);
+        }
+       return m_optimize;
+    }
+}
+
 void Yaz_ProxyClient::recv_Z_PDU(Z_APDU *apdu)
 {
     m_waiting = 0;
@@ -491,7 +509,7 @@ void Yaz_ProxyClient::recv_Z_PDU(Z_APDU *apdu)
        sr->numberOfRecordsReturned = pr->numberOfRecordsReturned;
        apdu = new_apdu;
     }
-    if (m_cookie)
+    if (m_cookie && *m_cookie)
        set_otherInformationString (apdu, VAL_COOKIE, 1, m_cookie);
     if (m_server)
     {
diff --git a/src/yaz-z-databases.cpp b/src/yaz-z-databases.cpp
new file mode 100644 (file)
index 0000000..362bd5a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2001, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: yaz-z-databases.cpp,v 1.1 2001-11-06 17:08:05 adam Exp $
+ */
+
+#include <string.h>
+
+#include <yaz++/yaz-z-databases.h>
+
+Yaz_Z_Databases::Yaz_Z_Databases()
+{
+    nmem = nmem_create ();
+    m_num = 0;
+    m_list = 0;
+}
+
+Yaz_Z_Databases::~Yaz_Z_Databases()
+{
+    nmem_destroy (nmem);
+}
+
+void Yaz_Z_Databases::set (int num, const char **db)
+{
+    nmem_reset (nmem);
+
+    m_list = (char **) nmem_malloc (nmem, num * sizeof(char*));
+    m_num = num;
+    for (int i = 0; i<num; i++)
+        m_list[i] = nmem_strdup (nmem, db[i] ? db[i] : "Default");
+}
+
+void Yaz_Z_Databases::get (NMEM n, int *num, char ***db)
+{
+    *num = m_num;
+    *db = (char **) nmem_malloc (n, m_num * sizeof(char*));
+    for (int i = 0; i < m_num; i++)
+        (*db)[i] = nmem_strdup (n, m_list[i]);
+}
+
+void Yaz_Z_Databases::get (ODR o, int *num, char ***db)
+{
+    return get (o->mem, num, db);
+}
+
+int Yaz_Z_Databases::match (Yaz_Z_Databases &db)
+{
+    if (db.m_num != m_num)
+        return 0;
+    for (int i = 0; i<m_num; i++)
+        if (strcmp (m_list[i], db.m_list[i]))
+            return 0;
+    return 1;
+}
+
+int Yaz_Z_Databases::match (int num, const char **db)
+{
+    if (num != m_num)
+        return 0;
+    for (int i = 0; i<m_num; i++)
+        if (strcmp (m_list[i], db[i]))
+            return 0;
+    return 1;
+}