From eb673212c641c36afba4cd502e283247de52a015 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 7 Jun 2012 14:51:36 +0200 Subject: [PATCH] Position modifier for sort prevents local sort Sort spec may be suffixed with p, for example "title:0p" which sorts by position locally (ie no sort), but by title natively (if sortmap is given). This allows getting sorted records from a database that Pazpar2 does not resort. --- src/client.c | 3 +- src/http_command.c | 3 +- src/reclists.c | 76 +++++++++++++++++++++++---------------- src/relevance.c | 4 ++- src/relevance.h | 2 +- src/session.c | 81 +++++++++++++++++++++++++----------------- src/session.h | 3 +- test/Makefile.am | 2 +- test/test_url.urls | 6 +++- test/test_url_settings_1.xml | 9 ----- test/test_url_settings_2.xml | 6 ---- test/test_url_settings_3.xml | 9 ----- test/test_url_settings_4.xml | 10 ------ 13 files changed, 109 insertions(+), 105 deletions(-) delete mode 100644 test/test_url_settings_1.xml delete mode 100644 test/test_url_settings_2.xml delete mode 100644 test/test_url_settings_3.xml delete mode 100644 test/test_url_settings_4.xml diff --git a/src/client.c b/src/client.c index 0ded33b..e6ddc66 100644 --- a/src/client.c +++ b/src/client.c @@ -1290,8 +1290,7 @@ int client_parse_query(struct client *cl, const char *query, if (!se->relevance) { // Initialize relevance structure with query terms - se->relevance = relevance_create_ccl( - se->service->charsets, se->nmem, cn); + se->relevance = relevance_create_ccl(se->service->charsets, cn); } ccl_rpn_delete(cn); return ret_value; diff --git a/src/http_command.c b/src/http_command.c index 84fac12..c92c7c3 100644 --- a/src/http_command.c +++ b/src/http_command.c @@ -1173,7 +1173,8 @@ static void cmd_show(struct http_channel *c) release_session(c, s); return; } - session_sort(s->psession, sp->name, sp->increasing); + session_sort(s->psession, sp->name, sp->increasing, + sp->type == Metadata_sortkey_position); status = session_active_clients(s->psession); diff --git a/src/reclists.c b/src/reclists.c index 2ba9b4d..c2b45e7 100644 --- a/src/reclists.c +++ b/src/reclists.c @@ -64,10 +64,10 @@ struct reclist_sortparms *reclist_parse_sortparms(NMEM nmem, const char *parms, char parm[256]; char *pp; const char *cpp; - int increasing; + int increasing = 0; int i; int offset = 0; - enum conf_sortkey_type type; + enum conf_sortkey_type type = Metadata_sortkey_string; struct reclist_sortparms *new; if (!(cpp = strchr(parms, ','))) @@ -77,39 +77,56 @@ struct reclist_sortparms *reclist_parse_sortparms(NMEM nmem, const char *parms, if ((pp = strchr(parm, ':'))) { - increasing = pp[1] == '1' ? 1 : 0; + if (pp[1] == '1') + increasing = 1; + else if (pp[1] == '0') + increasing = 0; + else + { + yaz_log(YLOG_FATAL, "Bad sortkey modifier: %s", parm); + return 0; + } + + if (pp[2]) + { + if (pp[2] == 'p') + type = Metadata_sortkey_position; + else + yaz_log(YLOG_FATAL, "Bad sortkey modifier: %s", parm); + } *pp = '\0'; } - else - increasing = 0; - if (!strcmp(parm, "relevance")) - { - type = Metadata_sortkey_relevance; - } - else if (!strcmp(parm, "position")) - { - type = Metadata_sortkey_position; - } - else + if (type != Metadata_sortkey_position) { - for (i = 0; i < service->num_sortkeys; i++) + if (!strcmp(parm, "relevance")) { - struct conf_sortkey *sk = &service->sortkeys[i]; - if (!strcmp(sk->name, parm)) - { - type = sk->type; - if (type == Metadata_sortkey_skiparticle) - type = Metadata_sortkey_string; - break; - } - } - if (i >= service->num_sortkeys) + type = Metadata_sortkey_relevance; + } + else if (!strcmp(parm, "position")) { - yaz_log(YLOG_FATAL, "Bad sortkey: %s", parm); - return 0; + type = Metadata_sortkey_position; } else + { + for (i = 0; i < service->num_sortkeys; i++) + { + struct conf_sortkey *sk = &service->sortkeys[i]; + if (!strcmp(sk->name, parm)) + { + type = sk->type; + if (type == Metadata_sortkey_skiparticle) + type = Metadata_sortkey_string; + break; + } + } + if (i >= service->num_sortkeys) + { + yaz_log(YLOG_FATAL, "Sortkey not defined in service: %s", + parm); + return 0; + } offset = i; + } } new = *rp = nmem_malloc(nmem, sizeof(struct reclist_sortparms)); new->next = 0; @@ -179,10 +196,7 @@ static int reclist_cmp(const void *p1, const void *p2) for (rec = r2->records; rec; rec = rec->next) if (pos2 == 0 || rec->position < pos2) pos2 = rec->position; - if (s->increasing) - res = pos1 - pos2; - else - res = pos2 - pos1; + res = pos1 - pos2; } break; default: diff --git a/src/relevance.c b/src/relevance.c index a365ebd..418dc9a 100644 --- a/src/relevance.c +++ b/src/relevance.c @@ -130,8 +130,9 @@ static void pull_terms(struct relevance *res, struct ccl_rpn_node *n) } struct relevance *relevance_create_ccl(pp2_charset_fact_t pft, - NMEM nmem, struct ccl_rpn_node *query) + struct ccl_rpn_node *query) { + NMEM nmem = nmem_create(); struct relevance *res = nmem_malloc(nmem, sizeof(*res)); int i; @@ -153,6 +154,7 @@ void relevance_destroy(struct relevance **rp) if (*rp) { pp2_charset_token_destroy((*rp)->prt); + nmem_destroy((*rp)->nmem); *rp = 0; } } diff --git a/src/relevance.h b/src/relevance.h index 70d8688..f20cbec 100644 --- a/src/relevance.h +++ b/src/relevance.h @@ -29,7 +29,7 @@ struct record_cluster; struct reclist; struct relevance *relevance_create_ccl(pp2_charset_fact_t pft, - NMEM nmem, struct ccl_rpn_node *query); + struct ccl_rpn_node *query); void relevance_destroy(struct relevance **rp); void relevance_newrec(struct relevance *r, struct record_cluster *cluster); void relevance_countwords(struct relevance *r, struct record_cluster *cluster, diff --git a/src/session.c b/src/session.c index 64920da..105c064 100644 --- a/src/session.c +++ b/src/session.c @@ -622,34 +622,64 @@ int session_is_preferred_clients_ready(struct session *s) return res == 0; } -void session_sort(struct session *se, const char *field, int increasing) +static void session_clear_set(struct session *se, + const char *sort_field, int increasing) +{ + reclist_destroy(se->reclist); + se->reclist = 0; + if (nmem_total(se->nmem)) + session_log(se, YLOG_DEBUG, "NMEN operation usage %zd", + nmem_total(se->nmem)); + nmem_reset(se->nmem); + se->total_records = se->total_merged = 0; + se->num_termlists = 0; + + /* reset list of sorted results and clear to relevance search */ + se->sorted_results = nmem_malloc(se->nmem, sizeof(*se->sorted_results)); + se->sorted_results->field = nmem_strdup(se->nmem, sort_field); + se->sorted_results->increasing = increasing; + se->sorted_results->next = 0; + + se->reclist = reclist_create(se->nmem); +} + +void session_sort(struct session *se, const char *field, int increasing, + int clear_set) { struct session_sorted_results *sr; struct client_list *l; session_enter(se); - /* see if we already have sorted for this critieria */ - for (sr = se->sorted_results; sr; sr = sr->next) + yaz_log(YLOG_LOG, "session_sort field=%s", field); + if (clear_set) { - if (!strcmp(field, sr->field) && increasing == sr->increasing) - break; + session_clear_set(se, field, increasing); } - if (sr) + else { - session_log(se, YLOG_DEBUG, "search_sort: field=%s increasing=%d already fetched", - field, increasing); - session_leave(se); - return; + /* see if we already have sorted for this critieria */ + for (sr = se->sorted_results; sr; sr = sr->next) + { + if (!strcmp(field, sr->field) && increasing == sr->increasing) + break; + } + if (sr) + { + session_log(se, YLOG_DEBUG, "search_sort: field=%s increasing=%d already fetched", + field, increasing); + session_leave(se); + return; + } + session_log(se, YLOG_DEBUG, "search_sort: field=%s increasing=%d must fetch", + field, increasing); + sr = nmem_malloc(se->nmem, sizeof(*sr)); + sr->field = nmem_strdup(se->nmem, field); + sr->increasing = increasing; + sr->next = se->sorted_results; + se->sorted_results = sr; } - session_log(se, YLOG_DEBUG, "search_sort: field=%s increasing=%d must fetch", - field, increasing); - sr = nmem_malloc(se->nmem, sizeof(*sr)); - sr->field = nmem_strdup(se->nmem, field); - sr->increasing = increasing; - sr->next = se->sorted_results; - se->sorted_results = sr; - + for (l = se->clients_active; l; l = l->next) { struct client *cl = l->client; @@ -688,29 +718,16 @@ enum pazpar2_error_code session_search(struct session *se, session_reset_active_clients(se, 0); session_enter(se); - reclist_destroy(se->reclist); - se->reclist = 0; se->settings_modified = 0; + session_clear_set(se, sort_field, increasing); relevance_destroy(&se->relevance); - if (nmem_total(se->nmem)) - session_log(se, YLOG_DEBUG, "NMEN operation usage %zd", nmem_total(se->nmem)); - nmem_reset(se->nmem); - se->total_records = se->total_merged = 0; - se->num_termlists = 0; - /* reset list of sorted results and clear to relevance search */ - se->sorted_results = nmem_malloc(se->nmem, sizeof(*se->sorted_results)); - se->sorted_results->field = nmem_strdup(se->nmem, sort_field); - se->sorted_results->increasing = increasing; - se->sorted_results->next = 0; - live_channels = select_targets(se, filter); if (!live_channels) { session_leave(se); return PAZPAR2_NO_TARGETS; } - se->reclist = reclist_create(se->nmem); yaz_gettimeofday(&tval); diff --git a/src/session.h b/src/session.h index 886f1b6..17d805f 100644 --- a/src/session.h +++ b/src/session.h @@ -156,7 +156,8 @@ void session_destroy(struct session *s); void session_init_databases(struct session *s); void statistics(struct session *s, struct statistics *stat); -void session_sort(struct session *se, const char *field, int increasing); +void session_sort(struct session *se, const char *field, int increasing, + int clear_set); enum pazpar2_error_code session_search(struct session *s, const char *query, const char *startrecs, diff --git a/test/Makefile.am b/test/Makefile.am index 24b417f..da39a91 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -22,7 +22,7 @@ EXTRA_DIST = run_pazpar2.sh marc21_test.xsl tmarc.xsl solr-pz2.xsl \ test_filter.cfg test_filter.urls \ test_termlist_block.cfg test_termlist_block.urls \ test_facets_settings_1.xml test_facets_settings_2.xml \ - test_url_service.xml test_url_settings_1.xml test_url_settings_2.xml test_url_settings_3.xml test_url_settings_4.xml \ + test_url_service.xml test_url_settings.xml \ test_limit_limitmap.cfg test_limit_limitmap.urls \ test_limit_limitmap_service.xml \ test_limit_limitmap_settings_1.xml test_limit_limitmap_settings_2.xml \ diff --git a/test/test_url.urls b/test/test_url.urls index ef092ea..a3de7ac 100644 --- a/test/test_url.urls +++ b/test/test_url.urls @@ -1,7 +1,7 @@ http://localhost:9763/search.pz2?command=init&clear=1&pz:elements%5Bmy%5D=F&pz:requestsyntax%5Bmy%5D=usmarc&pz:nativesyntax%5Bmy%5D=iso2709&pz:xslt%5Bmy%5D=marc21_test.xsl&pz:name%5Bmy%5D=marcserver&pz:url%5Bmy%5D=z3950.indexdata.com%2Fmarc http://localhost:9763/search.pz2?session=1&command=search&query=computer 2 http://localhost:9763/search.pz2?session=1&command=show&block=1 -test_url_settings_2.xml http://localhost:9763/search.pz2?session=1&command=settings +test_url_settings.xml http://localhost:9763/search.pz2?session=1&command=settings http://localhost:9763/search.pz2?session=1&command=search&query=the&maxrecs=3 2 http://localhost:9763/search.pz2?session=1&command=show&block=1 2 http://localhost:9763/search.pz2?session=1&command=show&block=1&sort=title:1 @@ -12,3 +12,7 @@ http://localhost:9763/search.pz2?command=init&clear=1&pz:elements%5Bmy%5D=F&pz:r http://localhost:9763/search.pz2?session=2&command=search&query=fail http://localhost:9763/search.pz2?command=init&clear=1&pz:elements%5Bmy%5D=F&pz:requestsyntax%5Bmy%5D=usmarc&pz:nativesyntax%5Bmy%5D=iso2709&pz:xslt%5Bmy%5D=marc21_test.xsl&pz:name%5Bmy%5D=marcserver&pz:url%5Bmy%5D=z3950.indexdata.com%2Fmarc&pz:pqf_strftime%5Bmy%5D=fail+%25%25 http://localhost:9763/search.pz2?session=3&command=search&query=fail +test_url_settings.xml http://localhost:9763/search.pz2?session=1&command=settings +http://localhost:9763/search.pz2?session=1&command=search&query=water +2 http://localhost:9763/search.pz2?session=1&command=show&block=1&sort=title:1p +2 http://localhost:9763/search.pz2?session=1&command=show&block=1&sort=date:0p diff --git a/test/test_url_settings_1.xml b/test/test_url_settings_1.xml deleted file mode 100644 index ec5b56b..0000000 --- a/test/test_url_settings_1.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/test/test_url_settings_2.xml b/test/test_url_settings_2.xml deleted file mode 100644 index 9835248..0000000 --- a/test/test_url_settings_2.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/test/test_url_settings_3.xml b/test/test_url_settings_3.xml deleted file mode 100644 index e18d45e..0000000 --- a/test/test_url_settings_3.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/test/test_url_settings_4.xml b/test/test_url_settings_4.xml deleted file mode 100644 index f719eec..0000000 --- a/test/test_url_settings_4.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - -- 1.7.10.4