From 6b431355cb6cfd0e73fb9f308bb09069da1812be Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 1 Sep 2014 08:15:08 +0200 Subject: [PATCH] xdoc caching in client --- src/client.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/client.h | 2 ++ src/session.c | 18 +++++++++++--- src/session.h | 2 ++ 4 files changed, 91 insertions(+), 4 deletions(-) diff --git a/src/client.c b/src/client.c index f78530c..0ba9f32 100644 --- a/src/client.c +++ b/src/client.c @@ -71,6 +71,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "relevance.h" #include "incref.h" +#define XDOC_CACHE_SIZE 100 + static YAZ_MUTEX g_mutex = 0; static int no_clients = 0; @@ -121,6 +123,7 @@ struct client { int same_search; char *sort_strategy; char *sort_criteria; + xmlDoc **xdoc; }; struct suggestions { @@ -192,6 +195,50 @@ void client_set_state(struct client *cl, enum client_state st) } } +static void client_init_xdoc(struct client *cl) +{ + int i; + + cl->xdoc = xmalloc(sizeof(*cl->xdoc) * XDOC_CACHE_SIZE); + for (i = 0; i < XDOC_CACHE_SIZE; i++) + cl->xdoc[i] = 0; +} + +static void client_destroy_xdoc(struct client *cl) +{ + int i; + + assert(cl->xdoc); + for (i = 0; i < XDOC_CACHE_SIZE; i++) + if (cl->xdoc[i]) + xmlFreeDoc(cl->xdoc[i]); + xfree(cl->xdoc); +} + +xmlDoc *client_get_xdoc(struct client *cl, int record_no) +{ + assert(cl->xdoc); + if (record_no >= 0 && record_no < XDOC_CACHE_SIZE) + return cl->xdoc[record_no]; + return 0; +} + +void client_store_xdoc(struct client *cl, int record_no, xmlDoc *xdoc) +{ + assert(cl->xdoc); + if (record_no >= 0 && record_no < XDOC_CACHE_SIZE) + { + if (cl->xdoc[record_no]) + xmlFreeDoc(cl->xdoc[record_no]); + cl->xdoc[record_no] = xdoc; + } + else + { + xmlFreeDoc(xdoc); + } +} + + static void client_show_raw_error(struct client *cl, const char *addinfo); struct connection *client_get_connection(struct client *cl) @@ -571,8 +618,27 @@ static void client_record_ingest(struct client *cl) ZOOM_record rec = 0; ZOOM_resultset resultset = cl->resultset; struct session *se = client_get_session(cl); + xmlDoc *xdoc; - if ((rec = ZOOM_resultset_record_immediate(resultset, cl->record_offset))) + xdoc = client_get_xdoc(cl, cl->record_offset + 1); + if (xdoc) + { + int offset = cl->record_offset++; + if (cl->session) + { + NMEM nmem = nmem_create(); + int rc = ingest_xml_record(cl, xdoc, offset, nmem); + if (rc == -1) + session_log(se, YLOG_WARN, + "Failed to ingest xdoc from %s #%d", + client_get_id(cl), offset); + else if (rc == -2) + cl->filtered++; + nmem_destroy(nmem); + } + } + else if ((rec = ZOOM_resultset_record_immediate(resultset, + cl->record_offset))) { int offset = ++cl->record_offset; if (cl->session == 0) @@ -888,6 +954,9 @@ int client_start_search(struct client *cl) cl->diagnostic = 0; cl->filtered = 0; + client_destroy_xdoc(cl); + client_init_xdoc(cl); + if (extra_args && *extra_args) ZOOM_connection_option_set(link, "extraArgs", extra_args); @@ -1001,6 +1070,7 @@ struct client *client_create(const char *id) cl->sort_criteria = 0; assert(id); cl->id = xstrdup(id); + client_init_xdoc(cl); client_use(1); yaz_log(YLOG_DEBUG, "client_create c=%p %s", cl, id); @@ -1046,6 +1116,7 @@ int client_destroy(struct client *c) assert(!c->connection); facet_limits_destroy(c->facet_limits); + client_destroy_xdoc(c); if (c->resultset) { ZOOM_resultset_destroy(c->resultset); diff --git a/src/client.h b/src/client.h index cb9d3ee..cd3e59a 100644 --- a/src/client.h +++ b/src/client.h @@ -112,6 +112,8 @@ const char *client_get_facet_limit_local(struct client *cl, void client_update_show_stat(struct client *cl, int cmd); +void client_store_xdoc(struct client *cl, int record_no, xmlDoc *xdoc); + #endif /* diff --git a/src/session.c b/src/session.c index eac40a0..52fea13 100644 --- a/src/session.c +++ b/src/session.c @@ -1706,6 +1706,9 @@ static int ingest_sub_record(struct client *cl, xmlDoc *xdoc, xmlNode *root, return ret; } +int ingest_xml_record(struct client *cl, xmlDoc *xdoc, + int record_no, NMEM nmem); + /** \brief ingest XML record \param cl client holds the result set for record \param rec record buffer (0 terminated) @@ -1722,9 +1725,19 @@ int ingest_record(struct client *cl, const char *rec, struct session_database *sdb = client_get_database(cl); struct conf_service *service = se->service; xmlDoc *xdoc = normalize_record(se, sdb, service, rec, nmem); - int r = 0; - xmlNode *root; + int r = ingest_xml_record(cl, xdoc, record_no, nmem); + client_store_xdoc(cl, record_no, xdoc); + return r; +} +int ingest_xml_record(struct client *cl, xmlDoc *xdoc, + int record_no, NMEM nmem) +{ + struct session *se = client_get_session(cl); + struct session_database *sdb = client_get_database(cl); + struct conf_service *service = se->service; + xmlNode *root; + int r = 0; if (!xdoc) return -1; @@ -1807,7 +1820,6 @@ int ingest_record(struct client *cl, const char *rec, (const char *) root->name); r = -1; } - xmlFreeDoc(xdoc); return r; } diff --git a/src/session.h b/src/session.h index a607c77..dcdce0c 100644 --- a/src/session.h +++ b/src/session.h @@ -186,6 +186,8 @@ void session_apply_setting(struct session *se, char *dbname, char *setting, char const char *session_setting_oneval(struct session_database *db, int offset); int ingest_record(struct client *cl, const char *rec, int record_no, NMEM nmem); +int ingest_xml_record(struct client *cl, xmlDoc *xdoc, + int record_no, NMEM nmem); void session_alert_watch(struct session *s, int what); void add_facet(struct session *s, const char *type, const char *value, int count); -- 1.7.10.4