X-Git-Url: http://jsfdemo.indexdata.com/?a=blobdiff_plain;f=src%2Fsession.c;h=684cd8e0b52086a889aca92bd543de9950de8c41;hb=646158a86d80e5ef0221ef7d7ce2cfc6ba31eacc;hp=9b69b3860124c7ed292c48188c48c52c55ec7e01;hpb=98dbaf0f7a4ea46aa3330d79c90f802fc0671f41;p=pazpar2-moved-to-github.git diff --git a/src/session.c b/src/session.c index 9b69b38..684cd8e 100644 --- a/src/session.c +++ b/src/session.c @@ -111,15 +111,17 @@ static int session_use(int delta) no_session_total += delta; sessions = no_sessions; yaz_mutex_leave(g_session_mutex); - yaz_log(YLOG_DEBUG, "%s sesions=%d", delta == 0 ? "" : (delta > 0 ? "INC" : "DEC"), no_sessions); + yaz_log(YLOG_DEBUG, "%s sessions=%d", delta == 0 ? "" : (delta > 0 ? "INC" : "DEC"), no_sessions); return sessions; } -int sessions_count(void) { +int sessions_count(void) +{ return session_use(0); } -int session_count_total(void) { +int session_count_total(void) +{ int total = 0; if (!g_session_mutex) return 0; @@ -129,7 +131,6 @@ int session_count_total(void) { return total; } - static void log_xml_doc(xmlDoc *doc) { FILE *lf = yaz_log_file(); @@ -158,37 +159,10 @@ static void session_leave(struct session *s) yaz_mutex_leave(s->session_mutex); } -// Recursively traverse query structure to extract terms. -void pull_terms(NMEM nmem, struct ccl_rpn_node *n, char **termlist, int *num) -{ - char **words; - int numwords; - int i; - - switch (n->kind) - { - case CCL_RPN_AND: - case CCL_RPN_OR: - case CCL_RPN_NOT: - case CCL_RPN_PROX: - pull_terms(nmem, n->u.p[0], termlist, num); - pull_terms(nmem, n->u.p[1], termlist, num); - break; - case CCL_RPN_TERM: - nmem_strsplit(nmem, " ", n->u.t.term, &words, &numwords); - for (i = 0; i < numwords; i++) - termlist[(*num)++] = words[i]; - break; - default: // NOOP - break; - } -} - - void add_facet(struct session *s, const char *type, const char *value, int count) { struct conf_service *service = s->service; - pp2_relevance_token_t prt; + pp2_charset_token_t prt; const char *facet_component; WRBUF facet_wrbuf = wrbuf_alloc(); WRBUF display_wrbuf = wrbuf_alloc(); @@ -197,13 +171,20 @@ void add_facet(struct session *s, const char *type, const char *value, int count for (i = 0; i < service->num_metadata; i++) if (!strcmp((service->metadata + i)->name, type)) - icu_chain_id = (service->metadata + i)->icu_chain; - yaz_log(YLOG_LOG, "icu_chain id=%s", icu_chain_id ? icu_chain_id : "null"); - - prt = pp2_relevance_tokenize(service->facet_pct); - - pp2_relevance_first(prt, value, 0); - while ((facet_component = pp2_relevance_token_next(prt))) + 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); + if (!prt) + { + yaz_log(YLOG_FATAL, "Unknown ICU chain '%s' for facet of type '%s'", + icu_chain_id, type); + wrbuf_destroy(facet_wrbuf); + wrbuf_destroy(display_wrbuf); + return; + } + pp2_charset_token_first(prt, value, 0); + while ((facet_component = pp2_charset_token_next(prt))) { const char *display_component; if (*facet_component) @@ -220,10 +201,8 @@ void add_facet(struct session *s, const char *type, const char *value, int count wrbuf_puts(display_wrbuf, display_component); } } - pp2_relevance_token_destroy(prt); + pp2_charset_token_destroy(prt); - yaz_log(YLOG_LOG, "facet norm=%s", wrbuf_cstr(facet_wrbuf)); - yaz_log(YLOG_LOG, "facet display=%s", wrbuf_cstr(display_wrbuf)); if (wrbuf_len(facet_wrbuf)) { int i; @@ -236,6 +215,7 @@ void add_facet(struct session *s, const char *type, const char *value, int count { session_log(s, YLOG_FATAL, "Too many termlists"); wrbuf_destroy(facet_wrbuf); + wrbuf_destroy(display_wrbuf); return; } @@ -266,13 +246,13 @@ static xmlDoc *record_to_xml(struct session *se, if (!rdoc) { session_log(se, YLOG_FATAL, "Non-wellformed XML received from %s", - db->url); + db->id); return 0; } if (global_parameters.dump_records) { - session_log(se, YLOG_LOG, "Un-normalized record from %s", db->url); + session_log(se, YLOG_LOG, "Un-normalized record from %s", db->id); log_xml_doc(rdoc); } @@ -360,7 +340,7 @@ static xmlDoc *normalize_record(struct session *se, if (normalize_record_transform(sdb->map, &rdoc, (const char **)parms)) { session_log(se, YLOG_WARN, "Normalize failed from %s", - sdb->database->url); + sdb->database->id); } else { @@ -369,7 +349,7 @@ static xmlDoc *normalize_record(struct session *se, if (global_parameters.dump_records) { session_log(se, YLOG_LOG, "Normalized record from %s", - sdb->database->url); + sdb->database->id); log_xml_doc(rdoc); } } @@ -421,7 +401,7 @@ static int prepare_map(struct session *se, struct session_database *sdb) if (!sdb->settings) { - session_log(se, YLOG_WARN, "No settings on %s", sdb->database->url); + session_log(se, YLOG_WARN, "No settings on %s", sdb->database->id); return -1; } if ((s = session_setting_oneval(sdb, PZ_XSLT))) @@ -467,7 +447,7 @@ static int prepare_session_database(struct session *se, if (!sdb->settings) { session_log(se, YLOG_WARN, - "No settings associated with %s", sdb->database->url); + "No settings associated with %s", sdb->database->id); return -1; } if (sdb->settings[PZ_XSLT] && !sdb->map) @@ -541,11 +521,12 @@ void session_alert_watch(struct session *s, int what) } //callback for grep_databases -static void select_targets_callback(void *context, struct session_database *db) +static void select_targets_callback(struct session *se, + struct session_database *db) { - struct session *se = (struct session*) context; - struct client *cl = client_create(); + struct client *cl = client_create(db->database->id); struct client_list *l; + client_set_database(cl, db); client_set_session(cl, se); @@ -610,6 +591,59 @@ int session_is_preferred_clients_ready(struct session *s) return res == 0; } +void search_sort(struct session *se, const char *field, int increasing) +{ + struct client_list *l; + struct timeval tval; + + session_enter(se); + for (l = se->clients; l; l = l->next) + { + struct client *cl = l->client; + struct session_database *sdb = client_get_database(cl); + struct setting *s; + const char *strategy_plus_sort = 0; + + for (s = sdb->settings[PZ_SORTMAP]; s; s = s->next) + { + char *p = strchr(s->name + 3, ':'); + if (!p) + { + yaz_log(YLOG_WARN, "Malformed sortmap name: %s", s->name); + continue; + } + p++; + if (!strcmp(p, field)) + { + strategy_plus_sort = s->value; + break; + } + } + + if (strategy_plus_sort) + { + if (client_prep_connection(cl, se->service->z3950_operation_timeout, + se->service->z3950_session_timeout, + se->service->server->iochan_man, + &tval)) + { + char **array; + int num; + nmem_strsplit(se->nmem, ":", strategy_plus_sort, &array, &num); + + if (num == 2) + { + const char *sort_spec = array[1]; + while (*sort_spec == ' ') + sort_spec++; + client_start_search(cl, array[0], sort_spec); + } + } + } + } + session_leave(se); +} + enum pazpar2_error_code search(struct session *se, const char *query, const char *startrecs, const char *maxrecs, @@ -675,7 +709,7 @@ enum pazpar2_error_code search(struct session *se, se->service->z3950_session_timeout, se->service->server->iochan_man, &tval)) - client_start_search(cl); + client_start_search(cl, 0, 0); } } facet_limits_destroy(facet_limits); @@ -737,8 +771,6 @@ static struct session_database *load_session_database(struct session *se, { struct database *db = new_database(id, se->session_nmem); - resolve_database(se->service, db); - session_init_databases_fun((void*) se, db); // New sdb is head of se->databases list @@ -752,7 +784,7 @@ static struct session_database *find_session_database(struct session *se, struct session_database *sdb; for (sdb = se->databases; sdb; sdb = sdb->next) - if (!strcmp(sdb->database->url, id)) + if (!strcmp(sdb->database->id, id)) return sdb; return load_session_database(se, id); } @@ -857,13 +889,13 @@ struct session *new_session(NMEM nmem, struct conf_service *service, return session; } -struct hitsbytarget *hitsbytarget(struct session *se, int *count, NMEM nmem) +static struct hitsbytarget *hitsbytarget_nb(struct session *se, + int *count, NMEM nmem) { struct hitsbytarget *res = 0; struct client_list *l; size_t sz = 0; - session_enter(se); for (l = se->clients; l; l = l->next) sz++; @@ -876,7 +908,7 @@ struct hitsbytarget *hitsbytarget(struct session *se, int *count, NMEM nmem) const char *name = session_setting_oneval(client_get_database(cl), PZ_NAME); - res[*count].id = client_get_database(cl)->database->url; + res[*count].id = client_get_id(cl); res[*count].name = *name ? name : "Unknown"; res[*count].hits = client_get_hits(cl); res[*count].records = client_get_num_records(cl); @@ -888,10 +920,18 @@ struct hitsbytarget *hitsbytarget(struct session *se, int *count, NMEM nmem) wrbuf_destroy(w); (*count)++; } - session_leave(se); return res; } +struct hitsbytarget *get_hitsbytarget(struct session *se, int *count, NMEM nmem) +{ + struct hitsbytarget *p; + session_enter(se); + p = hitsbytarget_nb(se, count, nmem); + session_leave(se); + return p; +} + struct termlist_score **get_termlist_score(struct session *se, const char *name, int *num) { @@ -909,6 +949,118 @@ struct termlist_score **get_termlist_score(struct session *se, return tl; } +// Compares two hitsbytarget nodes by hitcount +static int cmp_ht(const void *p1, const void *p2) +{ + const struct hitsbytarget *h1 = p1; + const struct hitsbytarget *h2 = p2; + return h2->hits - h1->hits; +} + +static int targets_termlist_nb(WRBUF wrbuf, struct session *se, int num, + NMEM nmem) +{ + struct hitsbytarget *ht; + int count, i; + + ht = hitsbytarget_nb(se, &count, nmem); + qsort(ht, count, sizeof(struct hitsbytarget), cmp_ht); + for (i = 0; i < count && i < num && ht[i].hits > 0; i++) + { + + // do only print terms which have display names + + wrbuf_puts(wrbuf, "\n"); + + wrbuf_puts(wrbuf, ""); + wrbuf_xmlputs(wrbuf, ht[i].id); + wrbuf_puts(wrbuf, "\n"); + + wrbuf_puts(wrbuf, ""); + if (!ht[i].name || !ht[i].name[0]) + wrbuf_xmlputs(wrbuf, "NO TARGET NAME"); + else + wrbuf_xmlputs(wrbuf, ht[i].name); + wrbuf_puts(wrbuf, "\n"); + + wrbuf_printf(wrbuf, "" ODR_INT_PRINTF "\n", + ht[i].hits); + + wrbuf_puts(wrbuf, ""); + wrbuf_xmlputs(wrbuf, ht[i].state); + wrbuf_puts(wrbuf, "\n"); + + wrbuf_printf(wrbuf, "%d\n", + ht[i].diagnostic); + wrbuf_puts(wrbuf, "\n"); + } + return count; +} + +void perform_termlist(struct http_channel *c, struct session *se, + const char *name, int num) +{ + int i, j; + NMEM nmem_tmp = nmem_create(); + char **names; + int num_names = 0; + + if (name) + nmem_strsplit(nmem_tmp, ",", name, &names, &num_names); + + session_enter(se); + + for (j = 0; j < num_names; j++) + { + const char *tname; + for (i = 0; i < se->num_termlists; i++) + { + tname = se->termlists[i].name; + if (num_names > 0 && !strcmp(names[j], tname)) + { + struct termlist_score **p = 0; + int len; + p = termlist_highscore(se->termlists[i].termlist, &len); + if (p) + { + int i; + wrbuf_puts(c->wrbuf, "wrbuf, tname); + wrbuf_puts(c->wrbuf, "\">\n"); + for (i = 0; i < len && i < num; i++) + { + // prevent sending empty term elements + if (!p[i]->display_term || !p[i]->display_term[0]) + continue; + + wrbuf_puts(c->wrbuf, ""); + wrbuf_puts(c->wrbuf, ""); + wrbuf_xmlputs(c->wrbuf, p[i]->display_term); + wrbuf_puts(c->wrbuf, ""); + + wrbuf_printf(c->wrbuf, + "%d", + p[i]->frequency); + wrbuf_puts(c->wrbuf, "\n"); + } + wrbuf_puts(c->wrbuf, "\n"); + } + } + } + tname = "xtargets"; + if (num_names > 0 && !strcmp(names[j], tname)) + { + wrbuf_puts(c->wrbuf, "wrbuf, tname); + wrbuf_puts(c->wrbuf, "\">\n"); + targets_termlist_nb(c->wrbuf, se, num, c->nmem); + wrbuf_puts(c->wrbuf, "\n"); + } + } + session_leave(se); + nmem_destroy(nmem_tmp); +} + #ifdef MISSING_HEADERS void report_nmem_stats(void) { @@ -1125,15 +1277,15 @@ static int get_mergekey_from_doc(xmlDoc *doc, xmlNode *root, const char *name, if (value) { const char *norm_str; - pp2_relevance_token_t prt = - pp2_relevance_tokenize(service->mergekey_pct); + pp2_charset_token_t prt = + pp2_charset_token_create(service->charsets, "mergekey"); - pp2_relevance_first(prt, (const char *) value, 0); + pp2_charset_token_first(prt, (const char *) value, 0); if (wrbuf_len(norm_wr) > 0) wrbuf_puts(norm_wr, " "); wrbuf_puts(norm_wr, name); while ((norm_str = - pp2_relevance_token_next(prt))) + pp2_charset_token_next(prt))) { if (*norm_str) { @@ -1142,7 +1294,7 @@ static int get_mergekey_from_doc(xmlDoc *doc, xmlNode *root, const char *name, } } xmlFree(value); - pp2_relevance_token_destroy(prt); + pp2_charset_token_destroy(prt); no_found++; } } @@ -1164,11 +1316,11 @@ static const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no, if (mergekey) { const char *norm_str; - pp2_relevance_token_t prt = - pp2_relevance_tokenize(service->mergekey_pct); + pp2_charset_token_t prt = + pp2_charset_token_create(service->charsets, "mergekey"); - pp2_relevance_first(prt, (const char *) mergekey, 0); - while ((norm_str = pp2_relevance_token_next(prt))) + pp2_charset_token_first(prt, (const char *) mergekey, 0); + while ((norm_str = pp2_charset_token_next(prt))) { if (*norm_str) { @@ -1177,7 +1329,7 @@ static const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no, wrbuf_puts(norm_wr, norm_str); } } - pp2_relevance_token_destroy(prt); + pp2_charset_token_destroy(prt); xmlFree(mergekey); } else @@ -1206,7 +1358,7 @@ static const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no, if (wrbuf_len(norm_wr) == 0) { wrbuf_printf(norm_wr, "%s-%d", - client_get_database(cl)->database->url, record_no); + client_get_id(cl), record_no); } if (wrbuf_len(norm_wr) > 0) mergekey_norm = nmem_strdup(nmem, wrbuf_cstr(norm_wr)); @@ -1310,7 +1462,7 @@ int ingest_record(struct client *cl, const char *rec, if (!check_record_filter(root, sdb)) { session_log(se, YLOG_LOG, "Filtered out record no %d from %s", - record_no, sdb->database->url); + record_no, sdb->database->id); xmlFreeDoc(xdoc); return -2; } @@ -1370,13 +1522,13 @@ static int ingest_to_cluster(struct client *cl, return -1; if (global_parameters.dump_records) session_log(se, YLOG_LOG, "Cluster id %s from %s (#%d)", cluster->recid, - sdb->database->url, record_no); + sdb->database->id, record_no); relevance_newrec(se->relevance, cluster); // now parsing XML record and adding data to cluster or record metadata for (n = root->children; n; n = n->next) { - pp2_relevance_token_t prt; + pp2_charset_token_t prt; if (type) xmlFree(type); if (value) @@ -1443,16 +1595,15 @@ static int ingest_to_cluster(struct client *cl, // assign cluster or record based on merge action if (ser_md->merge == Metadata_merge_unique) { - struct record_metadata *mnode; - for (mnode = *wheretoput; mnode; mnode = mnode->next) - if (!strcmp((const char *) mnode->data.text.disp, + while (*wheretoput) + { + if (!strcmp((const char *) (*wheretoput)->data.text.disp, rec_md->data.text.disp)) break; - if (!mnode) - { - rec_md->next = *wheretoput; - *wheretoput = rec_md; + wheretoput = &(*wheretoput)->next; } + if (!*wheretoput) + *wheretoput = rec_md; } else if (ser_md->merge == Metadata_merge_longest) { @@ -1472,12 +1623,13 @@ static int ingest_to_cluster(struct client *cl, nmem_malloc(se->nmem, sizeof(union data_types)); - prt = pp2_relevance_tokenize(service->sort_pct); + prt = + pp2_charset_token_create(service->charsets, "sort"); - pp2_relevance_first(prt, rec_md->data.text.disp, - skip_article); + pp2_charset_token_first(prt, rec_md->data.text.disp, + skip_article); - pp2_relevance_token_next(prt); + pp2_charset_token_next(prt); sort_str = pp2_get_sort(prt); @@ -1491,13 +1643,14 @@ static int ingest_to_cluster(struct client *cl, } cluster->sortkeys[sk_field_id]->text.sort = nmem_strdup(se->nmem, sort_str); - pp2_relevance_token_destroy(prt); + pp2_charset_token_destroy(prt); } } } else if (ser_md->merge == Metadata_merge_all) { - rec_md->next = *wheretoput; + while (*wheretoput) + wheretoput = &(*wheretoput)->next; *wheretoput = rec_md; } else if (ser_md->merge == Metadata_merge_range)