Position modifier for sort prevents local sort
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 7 Jun 2012 12:51:36 +0000 (14:51 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 7 Jun 2012 12:51:36 +0000 (14:51 +0200)
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.

13 files changed:
src/client.c
src/http_command.c
src/reclists.c
src/relevance.c
src/relevance.h
src/session.c
src/session.h
test/Makefile.am
test/test_url.urls
test/test_url_settings_1.xml [deleted file]
test/test_url_settings_2.xml [deleted file]
test/test_url_settings_3.xml [deleted file]
test/test_url_settings_4.xml [deleted file]

index 0ded33b..e6ddc66 100644 (file)
@@ -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;
index 84fac12..c92c7c3 100644 (file)
@@ -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);
 
index 2ba9b4d..c2b45e7 100644 (file)
@@ -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:
index a365ebd..418dc9a 100644 (file)
@@ -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;
     }
 }
index 70d8688..f20cbec 100644 (file)
@@ -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,
index 64920da..105c064 100644 (file)
@@ -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);
     
index 886f1b6..17d805f 100644 (file)
@@ -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,
index 24b417f..da39a91 100644 (file)
@@ -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 \
index ef092ea..a3de7ac 100644 (file)
@@ -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 (file)
index ec5b56b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<!-- Testign URL setting -->
-<settings target="my">
-  <set name="pz:name"  value="marcserver" />
-  <set name="pz:url"   value="z3950.indexdata.com/marc" />
-  <set name="pz:nativesyntax" value="iso2709" />
-  <set name="pz:requestsyntax" value="usmarc" />
-  <set name="pz:xslt" value="marc21_test.xsl" />
-  <set name="pz:elements" value="F" />
-</settings>
diff --git a/test/test_url_settings_2.xml b/test/test_url_settings_2.xml
deleted file mode 100644 (file)
index 9835248..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<!-- Testing URL changing, add sort -->
-<settings target="my">
-  <set name="pz:url"           value="z3950.indexdata.com/gils" />
-  <set name="pz:sortmap:title" value="type7:title" />
-</settings>
-
diff --git a/test/test_url_settings_3.xml b/test/test_url_settings_3.xml
deleted file mode 100644 (file)
index e18d45e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<!-- Testign URL setting -->
-<settings target="my">
-  <set name="pz:name"  value="marcserver" />
-  <set name="pz:url"   value="z3950.unknown.indexdata.com/marc" />
-  <set name="pz:nativesyntax" value="iso2709" />
-  <set name="pz:requestsyntax" value="usmarc" />
-  <set name="pz:xslt" value="marc21_test.xsl" />
-  <set name="pz:elements" value="F" />
-</settings>
diff --git a/test/test_url_settings_4.xml b/test/test_url_settings_4.xml
deleted file mode 100644 (file)
index f719eec..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<!-- Testign URL setting -->
-<settings target="my">
-  <set name="pz:name"          value="marcserver" />
-  <set name="pz:url"           value="z3950.indexdata.com/marc" />
-  <set name="pz:nativesyntax"  value="iso2709" />
-  <set name="pz:requestsyntax" value="usmarc" />
-  <set name="pz:xslt"          value="marc21_test.xsl" />
-  <set name="pz:elements"      value="F" />
-  <set name="pz:pqf_strftime"  value="fail %25%25" />
-</settings>