X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fsession.c;h=9e238a68793c90ba6014f9739b509555fabe6160;hb=c1de9c944c1383e173558b15bc693bd0eae2fba5;hp=69d05ae4fbaa0d482604e05363c8b6ae8ab54f05;hpb=22ac82b6522cc7ed34f93fa8dbdcbff383d23dab;p=pazpar2-moved-to-github.git diff --git a/src/session.c b/src/session.c index 69d05ae..9e238a6 100644 --- a/src/session.c +++ b/src/session.c @@ -56,6 +56,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include #include +#include #define USE_TIMING 0 #if USE_TIMING @@ -149,30 +150,19 @@ static void session_leave(struct session *s, const char *caller) session_log(s, YLOG_DEBUG, "Session unlock by %s", caller); } -static void session_normalize_facet(struct session *s, - const char *type, const char *value, - WRBUF display_wrbuf, WRBUF facet_wrbuf) +static int run_icu(struct session *s, const char *icu_chain_id, + const char *value, + WRBUF norm_wr, WRBUF disp_wr) { - struct conf_service *service = s->service; - pp2_charset_token_t prt; const char *facet_component; - int i; - const char *icu_chain_id = 0; - - for (i = 0; i < service->num_metadata; i++) - if (!strcmp((service->metadata + i)->name, type)) - icu_chain_id = (service->metadata + i)->facetrule; - if (!icu_chain_id) - icu_chain_id = "facet"; - prt = pp2_charset_token_create(service->charsets, icu_chain_id); + struct conf_service *service = s->service; + pp2_charset_token_t prt = + pp2_charset_token_create(service->charsets, icu_chain_id); if (!prt) { session_log(s, YLOG_FATAL, - "Unknown ICU chain '%s' for facet of type '%s'", - icu_chain_id, type); - wrbuf_destroy(facet_wrbuf); - wrbuf_destroy(display_wrbuf); - return; + "Unknown ICU chain '%s'", icu_chain_id); + return 0; } pp2_charset_token_first(prt, value, 0); while ((facet_component = pp2_charset_token_next(prt))) @@ -180,19 +170,37 @@ static void session_normalize_facet(struct session *s, const char *display_component; if (*facet_component) { - if (wrbuf_len(facet_wrbuf)) - wrbuf_puts(facet_wrbuf, " "); - wrbuf_puts(facet_wrbuf, facet_component); + if (wrbuf_len(norm_wr)) + wrbuf_puts(norm_wr, " "); + wrbuf_puts(norm_wr, facet_component); } display_component = pp2_get_display(prt); if (display_component) { - if (wrbuf_len(display_wrbuf)) - wrbuf_puts(display_wrbuf, " "); - wrbuf_puts(display_wrbuf, display_component); + if (wrbuf_len(disp_wr)) + wrbuf_puts(disp_wr, " "); + wrbuf_puts(disp_wr, display_component); } } pp2_charset_token_destroy(prt); + return 1; +} + +static void session_normalize_facet(struct session *s, + const char *type, const char *value, + WRBUF display_wrbuf, WRBUF facet_wrbuf) +{ + struct conf_service *service = s->service; + int i; + const char *icu_chain_id = 0; + + for (i = 0; i < service->num_metadata; i++) + if (!strcmp((service->metadata + i)->name, type)) + icu_chain_id = (service->metadata + i)->facetrule; + if (!icu_chain_id) + icu_chain_id = "facet"; + + run_icu(s, icu_chain_id, value, facet_wrbuf, display_wrbuf); } void add_facet(struct session *s, const char *type, const char *value, int count) @@ -204,29 +212,18 @@ void add_facet(struct session *s, const char *type, const char *value, int count if (wrbuf_len(facet_wrbuf)) { - int i; - for (i = 0; i < s->num_termlists; i++) - if (!strcmp(s->termlists[i].name, type)) + struct named_termlist **tp = &s->termlists; + for (; (*tp); tp = &(*tp)->next) + if (!strcmp((*tp)->name, type)) break; - if (i == s->num_termlists) + if (!*tp) { - if (i == SESSION_MAX_TERMLISTS) - { - session_log(s, YLOG_FATAL, "Too many termlists"); - wrbuf_destroy(facet_wrbuf); - wrbuf_destroy(display_wrbuf); - return; - } - - s->termlists[i].name = nmem_strdup(s->nmem, type); - s->termlists[i].termlist = termlist_create(s->nmem); - s->num_termlists = i + 1; + *tp = nmem_malloc(s->nmem, sizeof(**tp)); + (*tp)->name = nmem_strdup(s->nmem, type); + (*tp)->termlist = termlist_create(s->nmem); + (*tp)->next = 0; } - -#if 0 - session_log(s, YLOG_LOG, "Facets for %s: %s norm:%s (%d)", type, value, wrbuf_cstr(facet_wrbuf), count); -#endif - termlist_insert(s->termlists[i].termlist, wrbuf_cstr(display_wrbuf), + termlist_insert((*tp)->termlist, wrbuf_cstr(display_wrbuf), wrbuf_cstr(facet_wrbuf), count); } wrbuf_destroy(facet_wrbuf); @@ -604,8 +601,7 @@ static void session_clear_set(struct session *se, struct reclist_sortparms *sp) nmem_total(se->nmem)); nmem_reset(se->nmem); se->total_records = se->total_merged = 0; - se->num_termlists = 0; - + se->termlists = 0; relevance_clear(se->relevance); /* reset list of sorted results and clear to relevance search */ @@ -621,10 +617,8 @@ static void session_clear_set(struct session *se, struct reclist_sortparms *sp) se->reclist = reclist_create(se->nmem); } -static void session_sort_unlocked(struct session *se, - struct reclist_sortparms *sp, - const char *mergekey, - const char *rank) +void session_sort(struct session *se, struct reclist_sortparms *sp, + const char *mergekey, const char *rank) { struct client_list *l; const char *field = sp->name; @@ -632,6 +626,7 @@ static void session_sort_unlocked(struct session *se, int type = sp->type; int clients_research = 0; + session_enter(se, "session_sort"); session_log(se, YLOG_DEBUG, "session_sort field=%s increasing=%d type=%d", field, increasing, type); @@ -665,6 +660,7 @@ static void session_sort_unlocked(struct session *se, { session_log(se, YLOG_DEBUG, "session_sort: field=%s increasing=%d type=%d already fetched", field, increasing, type); + session_leave(se, "session_sort"); return; } } @@ -682,14 +678,7 @@ static void session_sort_unlocked(struct session *se, client_parse_init(cl, 1); clients_research += client_parse_sort(cl, sp); } - if (clients_research) - { - session_log(se, YLOG_DEBUG, - "session_sort: reset results due to %d clients researching", - clients_research); - session_clear_set(se, sp); - } - else + if (!clients_research || se->clients_starting) { // A new sorting based on same record set struct reclist_sortparms *sr = nmem_malloc(se->nmem, sizeof(*sr)); @@ -699,36 +688,66 @@ static void session_sort_unlocked(struct session *se, sr->next = se->sorted_results; se->sorted_results = sr; session_log(se, YLOG_DEBUG, "session_sort: no research/ingesting done"); - return ; + session_leave(se, "session_sort"); } - session_log(se, YLOG_DEBUG, "Re- search/ingesting for clients due to change in sort order"); - - for (l = se->clients_active; l; l = l->next) + else { - struct client *cl = l->client; - if (client_get_state(cl) == Client_Connecting || - client_get_state(cl) == Client_Idle || - client_get_state(cl) == Client_Working) { - client_start_search(cl); - } - else + se->clients_starting = 1; + session_log(se, YLOG_DEBUG, + "session_sort: reset results due to %d clients researching", + clients_research); + session_clear_set(se, sp); + session_log(se, YLOG_DEBUG, "Re- search/ingesting for clients due to change in sort order"); + + session_leave(se, "session_sort"); + for (l = se->clients_active; l; l = l->next) { - session_log(se, YLOG_DEBUG, - "session_sort: %s: No re-start/ingest in show. " - "Wrong client state: %d", - client_get_id(cl), client_get_state(cl)); + struct client *cl = l->client; + if (client_get_state(cl) == Client_Connecting || + client_get_state(cl) == Client_Idle || + client_get_state(cl) == Client_Working) { + client_start_search(cl); + } + else + { + session_log(se, YLOG_DEBUG, + "session_sort: %s: No re-start/ingest in show. " + "Wrong client state: %d", + client_get_id(cl), client_get_state(cl)); + } } + session_enter(se, "session_sort"); + se->clients_starting = 0; + session_leave(se, "session_sort"); } } -void session_sort(struct session *se, struct reclist_sortparms *sp, - const char *mergekey, const char *rank) +void session_stop(struct session *se) { - //session_enter(se, "session_sort"); - session_sort_unlocked(se, sp, mergekey, rank); - //session_leave(se, "session_sort"); -} + struct client_list *l; + session_enter(se, "session_stop1"); + if (se->clients_starting) + { + session_leave(se, "session_stop1"); + return; + } + se->clients_starting = 1; + session_leave(se, "session_stop1"); + session_alert_watch(se, SESSION_WATCH_SHOW); + session_alert_watch(se, SESSION_WATCH_BYTARGET); + session_alert_watch(se, SESSION_WATCH_TERMLIST); + session_alert_watch(se, SESSION_WATCH_SHOW_PREF); + + for (l = se->clients_active; l; l = l->next) + { + struct client *cl = l->client; + client_stop(cl); + } + session_enter(se, "session_stop2"); + se->clients_starting = 0; + session_leave(se, "session_stop2"); +} enum pazpar2_error_code session_search(struct session *se, const char *query, @@ -746,17 +765,21 @@ enum pazpar2_error_code session_search(struct session *se, int no_working = 0; int no_failed_query = 0; int no_failed_limit = 0; - struct client_list *l, *l0; - - session_alert_watch(se, SESSION_WATCH_SHOW); - session_alert_watch(se, SESSION_WATCH_BYTARGET); - session_alert_watch(se, SESSION_WATCH_TERMLIST); - session_alert_watch(se, SESSION_WATCH_SHOW_PREF); + struct client_list *l; session_log(se, YLOG_DEBUG, "Search"); *addinfo = 0; + session_enter(se, "session_search0"); + if (se->clients_starting) + { + session_leave(se, "session_search0"); + return PAZPAR2_NO_ERROR; + } + se->clients_starting = 1; + session_leave(se, "session_search0"); + if (se->settings_modified) { session_remove_cached_clients(se); } @@ -784,6 +807,7 @@ enum pazpar2_error_code session_search(struct session *se, if (!live_channels) { session_leave(se, "session_search"); + se->clients_starting = 0; return PAZPAR2_NO_TARGETS; } @@ -793,14 +817,18 @@ enum pazpar2_error_code session_search(struct session *se, { *addinfo = "limit"; session_leave(se, "session_search"); + se->clients_starting = 0; return PAZPAR2_MALFORMED_PARAMETER_VALUE; } - l0 = se->clients_active; - se->clients_active = 0; session_leave(se, "session_search"); - for (l = l0; l; l = l->next) + session_alert_watch(se, SESSION_WATCH_SHOW); + session_alert_watch(se, SESSION_WATCH_BYTARGET); + session_alert_watch(se, SESSION_WATCH_TERMLIST); + session_alert_watch(se, SESSION_WATCH_SHOW_PREF); + + for (l = se->clients_active; l; l = l->next) { int parse_ret; struct client *cl = l->client; @@ -823,8 +851,9 @@ enum pazpar2_error_code session_search(struct session *se, no_working++; } } - session_reset_active_clients(se, l0); - + session_enter(se, "session_search2"); + se->clients_starting = 0; + session_leave(se, "session_search2"); if (no_working == 0) { if (no_failed_query > 0) @@ -992,7 +1021,7 @@ struct session *new_session(NMEM nmem, struct conf_service *service, session->total_records = 0; session->number_of_warnings_unknown_elements = 0; session->number_of_warnings_unknown_metadata = 0; - session->num_termlists = 0; + session->termlists = 0; session->reclist = reclist_create(nmem); session->clients_active = 0; session->clients_cached = 0; @@ -1004,6 +1033,7 @@ struct session *new_session(NMEM nmem, struct conf_service *service, session->facet_limits = 0; session->mergekey = 0; session->rank = 0; + session->clients_starting = 0; for (i = 0; i <= SESSION_WATCH_MAX; i++) { @@ -1140,7 +1170,7 @@ static int targets_termlist_nb(WRBUF wrbuf, struct session *se, int num, void perform_termlist(struct http_channel *c, struct session *se, const char *name, int num, int version) { - int i, j; + int j; NMEM nmem_tmp = nmem_create(); char **names; int num_names = 0; @@ -1157,9 +1187,10 @@ void perform_termlist(struct http_channel *c, struct session *se, const char *tname; int must_generate_empty = 1; /* bug 5350 */ - for (i = 0; i < se->num_termlists; i++) + struct named_termlist *t = se->termlists; + for (; t; t = t->next) { - tname = se->termlists[i].name; + tname = t->name; if (!strcmp(names[j], tname) || !strcmp(names[j], "*")) { struct termlist_score **p = 0; @@ -1170,8 +1201,7 @@ void perform_termlist(struct http_channel *c, struct session *se, wrbuf_puts(c->wrbuf, "\">\n"); must_generate_empty = 0; - p = termlist_highscore(se->termlists[i].termlist, &len, - nmem_tmp); + p = termlist_highscore(t->termlist, &len, nmem_tmp); if (p) { int i; @@ -1542,7 +1572,7 @@ static int get_mergekey_from_doc(xmlDoc *doc, xmlNode *root, const char *name, continue; if (!strcmp((const char *) n->name, "metadata")) { - xmlChar *type = xmlGetProp(n, (xmlChar *) "type"); + const char *type = yaz_xml_get_prop(n, "type"); if (type == NULL) { yaz_log(YLOG_FATAL, "Missing type attribute on metadata element. Skipping!"); } @@ -1561,7 +1591,6 @@ static int get_mergekey_from_doc(xmlDoc *doc, xmlNode *root, const char *name, if (value) xmlFree(value); } - xmlFree(type); } } return no_found; @@ -1574,7 +1603,7 @@ static const char *get_mergekey(xmlDoc *doc, xmlNode *root, { char *mergekey_norm = 0; WRBUF norm_wr = wrbuf_alloc(); - xmlChar *mergekey; + const char *mergekey; if (session_mergekey) { @@ -1586,10 +1615,9 @@ static const char *get_mergekey(xmlDoc *doc, xmlNode *root, for (i = 0; i < num; i++) get_mergekey_from_doc(doc, root, values[i], service, norm_wr); } - else if ((mergekey = xmlGetProp(root, (xmlChar *) "mergekey"))) + else if ((mergekey = yaz_xml_get_prop(root, "mergekey"))) { - mergekey_norm_wr(service->charsets, norm_wr, (const char *) mergekey); - xmlFree(mergekey); + mergekey_norm_wr(service->charsets, norm_wr, mergekey); } else { @@ -1656,7 +1684,7 @@ static int check_record_filter(xmlNode *root, struct session_database *sdb) continue; if (!strcmp((const char *) n->name, "metadata")) { - xmlChar *type = xmlGetProp(n, (xmlChar *) "type"); + const char *type = yaz_xml_get_prop(n, "type"); if (type) { size_t len; @@ -1684,7 +1712,6 @@ static int check_record_filter(xmlNode *root, struct session_database *sdb) } xmlFree(value); } - xmlFree(type); } } } @@ -1692,6 +1719,8 @@ static int check_record_filter(xmlNode *root, struct session_database *sdb) } static int ingest_to_cluster(struct client *cl, + WRBUF wrbuf_disp, + WRBUF wrbuf_norm, xmlDoc *xdoc, xmlNode *root, int record_no, @@ -1704,6 +1733,7 @@ static int ingest_sub_record(struct client *cl, xmlDoc *xdoc, xmlNode *root, { int ret = 0; struct session *se = client_get_session(cl); + WRBUF wrbuf_disp, wrbuf_norm; if (!check_record_filter(root, sdb)) { @@ -1712,11 +1742,15 @@ static int ingest_sub_record(struct client *cl, xmlDoc *xdoc, xmlNode *root, record_no, sdb->database->id); return 0; } + wrbuf_disp = wrbuf_alloc(); + wrbuf_norm = wrbuf_alloc(); session_enter(se, "ingest_sub_record"); if (client_get_session(cl) == se && se->relevance) - ret = ingest_to_cluster(cl, xdoc, root, record_no, mergekeys); + ret = ingest_to_cluster(cl, wrbuf_disp, wrbuf_norm, + xdoc, root, record_no, mergekeys); session_leave(se, "ingest_sub_record"); - + wrbuf_destroy(wrbuf_norm); + wrbuf_destroy(wrbuf_disp); return ret; } @@ -1997,14 +2031,14 @@ static int check_limit_local(struct client *cl, } static int ingest_to_cluster(struct client *cl, + WRBUF wrbuf_disp, + WRBUF wrbuf_norm, xmlDoc *xdoc, xmlNode *root, int record_no, struct record_metadata_attr *merge_keys) { xmlNode *n; - xmlChar *type = 0; - xmlChar *value = 0; struct session *se = client_get_session(cl); struct conf_service *service = se->service; int term_factor = 1; @@ -2021,12 +2055,6 @@ static int ingest_to_cluster(struct client *cl, for (n = root->children; n; n = n->next) { - if (type) - xmlFree(type); - if (value) - xmlFree(value); - type = value = 0; - if (n->type != XML_ELEMENT_NODE) continue; if (!strcmp((const char *) n->name, "metadata")) @@ -2035,20 +2063,26 @@ static int ingest_to_cluster(struct client *cl, struct record_metadata **wheretoput = 0; struct record_metadata *rec_md = 0; int md_field_id = -1; + xmlChar *value0; + const char *type = yaz_xml_get_prop(n, "type"); - type = xmlGetProp(n, (xmlChar *) "type"); - value = xmlNodeListGetString(xdoc, n->children, 1); if (!type) continue; - if (!value || !*value) + wrbuf_rewind(wrbuf_disp); + value0 = xmlNodeListGetString(xdoc, n->children, 1); + if (!value0 || !*value0) { - xmlChar *empty = xmlGetProp(n, (xmlChar *) "empty"); + const char *empty = yaz_xml_get_prop(n, "empty"); if (!empty) continue; - if (value) - xmlFree(value); - value = empty; + wrbuf_puts(wrbuf_disp, (const char *) empty); + } + else + { + wrbuf_puts(wrbuf_disp, (const char *) value0); } + if (value0) + xmlFree(value0); md_field_id = conf_service_metadata_field_id(service, (const char *) type); if (md_field_id < 0) @@ -2065,12 +2099,12 @@ static int ingest_to_cluster(struct client *cl, ser_md = &service->metadata[md_field_id]; // non-merged metadata - rec_md = record_metadata_init(se->nmem, (const char *) value, + rec_md = record_metadata_init(se->nmem, wrbuf_cstr(wrbuf_disp), ser_md->type, n->properties); if (!rec_md) { session_log(se, YLOG_WARN, "bad metadata data '%s' " - "for element '%s'", value, type); + "for element '%s'", wrbuf_cstr(wrbuf_disp), type); continue; } @@ -2078,7 +2112,7 @@ static int ingest_to_cluster(struct client *cl, { WRBUF w = wrbuf_alloc(); if (relevance_snippet(se->relevance, - (char*) value, ser_md->name, w)) + wrbuf_cstr(wrbuf_disp), ser_md->name, w)) rec_md->data.text.snippet = nmem_strdup(se->nmem, wrbuf_cstr(w)); wrbuf_destroy(w); @@ -2094,20 +2128,12 @@ static int ingest_to_cluster(struct client *cl, if (check_limit_local(cl, record, record_no)) { - if (type) - xmlFree(type); - if (value) - xmlFree(value); return -2; } cluster = reclist_insert(se->reclist, se->relevance, service, record, merge_keys, &se->total_merged); if (!cluster) { - if (type) - xmlFree(type); - if (value) - xmlFree(value); return 0; // complete match with existing record } @@ -2145,13 +2171,6 @@ static int ingest_to_cluster(struct client *cl, // now parsing XML record and adding data to cluster or record metadata for (n = root->children; n; n = n->next) { - pp2_charset_token_t prt; - if (type) - xmlFree(type); - if (value) - xmlFree(value); - type = value = 0; - if (n->type != XML_ELEMENT_NODE) continue; if (!strcmp((const char *) n->name, "metadata")) @@ -2163,12 +2182,13 @@ static int ingest_to_cluster(struct client *cl, int md_field_id = -1; int sk_field_id = -1; const char *rank = 0; - xmlChar *xml_rank = 0; - - type = xmlGetProp(n, (xmlChar *) "type"); - value = xmlNodeListGetString(xdoc, n->children, 1); + const char *xml_rank = 0; + const char *type = 0; + xmlChar *value0; - if (!type || !value || !*value) + wrbuf_rewind(wrbuf_disp); + type = yaz_xml_get_prop(n, "type"); + if (!type) continue; md_field_id @@ -2184,8 +2204,19 @@ static int ingest_to_cluster(struct client *cl, ser_sk = &service->sortkeys[sk_field_id]; } + value0 = xmlNodeListGetString(xdoc, n->children, 1); + if (!value0 || !*value0) + { + if (value0) + xmlFree(value0); + continue; + } + wrbuf_puts(wrbuf_disp, (const char *) value0); + xmlFree(value0); + + // merged metadata - rec_md = record_metadata_init(se->nmem, (const char *) value, + rec_md = record_metadata_init(se->nmem, wrbuf_cstr(wrbuf_disp), ser_md->type, 0); // see if the field was not in cluster already (from beginning) @@ -2212,7 +2243,7 @@ static int ingest_to_cluster(struct client *cl, } else { - xml_rank = xmlGetProp(n, (xmlChar *) "rank"); + xml_rank = yaz_xml_get_prop(n, "rank"); rank = xml_rank ? (const char *) xml_rank : ser_md->rank; } @@ -2248,6 +2279,7 @@ static int ingest_to_cluster(struct client *cl, *wheretoput = rec_md; if (ser_sk) { + pp2_charset_token_t prt; const char *sort_str = 0; int skip_article = ser_sk->type == Metadata_type_skiparticle; @@ -2311,7 +2343,8 @@ static int ingest_to_cluster(struct client *cl, if (rank) { relevance_countwords(se->relevance, cluster, - (char *) value, rank, ser_md->name); + wrbuf_cstr(wrbuf_disp), + rank, ser_md->name); } // construct facets ... unless the client already has reported them if (ser_md->termlist && !client_has_facet(cl, (char *) type)) @@ -2329,15 +2362,8 @@ static int ingest_to_cluster(struct client *cl, } } else - add_facet(se, (char *) type, (char *) value, term_factor); + add_facet(se, type, wrbuf_cstr(wrbuf_disp), term_factor); } - - // cleaning up - if (xml_rank) - xmlFree(xml_rank); - xmlFree(type); - xmlFree(value); - type = value = 0; } else { @@ -2347,11 +2373,6 @@ static int ingest_to_cluster(struct client *cl, se->number_of_warnings_unknown_elements++; } } - if (type) - xmlFree(type); - if (value) - xmlFree(value); - nmem_destroy(ingest_nmem); xfree(metadata0); relevance_donerecord(se->relevance, cluster);