Fixed bug #252: Sort does not work.
[idzebra-moved-to-github.git] / index / zsets.c
index ac28c8e..313a868 100644 (file)
@@ -1,5 +1,5 @@
-/* $Id: zsets.c,v 1.42 2003-02-27 22:55:40 adam Exp $
-   Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
+/* $Id: zsets.c,v 1.49.2.3 2005-01-21 11:35:49 adam Exp $
+   Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005
    Index Data Aps
 
 This file is part of the Zebra server.
@@ -55,6 +55,10 @@ struct zebra_set {
     int term_entries_max;
     struct zebra_set *next;
     int locked;
+
+    int cache_position;  /* last position */
+    RSFD cache_rfd;      /* rfd (NULL if not existing) */
+    int cache_psysno;
 };
 
 struct zset_sort_entry {
@@ -70,7 +74,7 @@ struct zset_sort_info {
     struct zset_sort_entry **entries;
 };
 
-ZebraSet resultSetAddRPN (ZebraHandle zh, ODR input, ODR output,
+ZebraSet resultSetAddRPN (ZebraHandle zh, NMEM m,
                          Z_RPNQuery *rpn, int num_bases,
                           char **basenames, 
                          const char *setname)
@@ -87,8 +91,8 @@ ZebraSet resultSetAddRPN (ZebraHandle zh, ODR input, ODR output,
        return 0;
     zebraSet->locked = 1;
     zebraSet->rpn = 0;
-    zebraSet->nmem = nmem_create ();
-
+    zebraSet->nmem = m;
+    
     zebraSet->num_bases = num_bases;
     zebraSet->basenames = 
         nmem_malloc (zebraSet->nmem, num_bases * sizeof(*zebraSet->basenames));
@@ -96,7 +100,7 @@ ZebraSet resultSetAddRPN (ZebraHandle zh, ODR input, ODR output,
         zebraSet->basenames[i] = nmem_strdup (zebraSet->nmem, basenames[i]);
 
 
-    zebraSet->rset = rpn_search (zh, output->mem, rpn,
+    zebraSet->rset = rpn_search (zh, zebraSet->nmem, rpn,
                                  zebraSet->num_bases,
                                 zebraSet->basenames, zebraSet->name,
                                 zebraSet);
@@ -201,12 +205,18 @@ ZebraSet resultSetAdd (ZebraHandle zh, const char *name, int ov)
        if (!ov || s->locked)
            return NULL;
        if (s->rset)
+       {
+           if (s->cache_rfd)
+               rset_close(s->rset, s->cache_rfd);
            rset_delete (s->rset);
+       }
        if (s->nmem)
            nmem_destroy (s->nmem);
     }
     else
     {
+       const char *sort_max_str = zebra_get_resource(zh, "sortmax", "1000");
+
        yaz_log (LOG_DEBUG, "adding result set %s", name);
        s = (ZebraSet) xmalloc (sizeof(*s));
        s->next = zh->sets;
@@ -216,7 +226,10 @@ ZebraSet resultSetAdd (ZebraHandle zh, const char *name, int ov)
 
        s->sort_info = (struct zset_sort_info *)
            xmalloc (sizeof(*s->sort_info));
-       s->sort_info->max_entries = 1000;
+       s->sort_info->max_entries = atoi(sort_max_str);
+       if (s->sort_info->max_entries < 2)
+           s->sort_info->max_entries = 2;
+
        s->sort_info->entries = (struct zset_sort_entry **)
            xmalloc (sizeof(*s->sort_info->entries) *
                     s->sort_info->max_entries);
@@ -232,6 +245,8 @@ ZebraSet resultSetAdd (ZebraHandle zh, const char *name, int ov)
     s->rset = 0;
     s->nmem = 0;
     s->rpn = 0;
+    s->cache_position = 0;
+    s->cache_rfd = 0;
     return s;
 }
 
@@ -263,8 +278,14 @@ void resultSetInvalidate (ZebraHandle zh)
     for (; s; s = s->next)
     {
         if (s->rset)
+       {
+           if (s->cache_rfd)
+               rset_close(s->rset, s->cache_rfd);
             rset_delete (s->rset);
+       }
         s->rset = 0;
+       s->cache_rfd = 0;
+       s->cache_position = 0;
     }
 }
 
@@ -304,7 +325,11 @@ void resultSetDestroy (ZebraHandle zh, int num, char **names,int *statuses)
            if (s->nmem)
                nmem_destroy (s->nmem);
            if (s->rset)
+           {
+               if (s->cache_rfd)
+                   rset_close (s->rset, s->cache_rfd);
                rset_delete (s->rset);
+           }
            xfree (s->name);
            xfree (s);
        }
@@ -388,7 +413,20 @@ ZebraPosSet zebraPosSetCreate (ZebraHandle zh, const char *name,
                position = sort_info->num_entries;
            while (num_i < num && positions[num_i] < position)
                num_i++;
-           rfd = rset_open (rset, RSETF_READ);
+           
+           if (sset->cache_rfd && 
+               num_i < num && positions[num_i] > sset->cache_position)
+           {
+               position = sset->cache_position;
+               rfd = sset->cache_rfd;
+               psysno = sset->cache_psysno;
+           } 
+           else
+           {
+               if (sset->cache_rfd)
+                   rset_close(rset, sset->cache_rfd);
+               rfd = rset_open (rset, RSETF_READ);
+           }
            while (num_i < num && rset_read (rset, rfd, &key, &term_index))
            {
                if (key.sysno != psysno)
@@ -414,7 +452,9 @@ ZebraPosSet zebraPosSetCreate (ZebraHandle zh, const char *name,
                    }
                }
            }
-           rset_close (rset, rfd);
+           sset->cache_position = position;
+           sset->cache_psysno = psysno;
+           sset->cache_rfd = rfd;
        }
     }
     return sr;
@@ -506,8 +546,8 @@ void resultSetInsertSort (ZebraHandle zh, ZebraSet sset,
     new_entry->score = -1;
 }
 
-void resultSetInsertRank (ZebraHandle zh, struct zset_sort_info *sort_info,
-                         int sysno, int score, int relation)
+void resultSetInsertRank(ZebraHandle zh, struct zset_sort_info *sort_info,
+                        int sysno, int score, int relation)
 {
     struct zset_sort_entry *new_entry = NULL;
     int i, j;
@@ -598,6 +638,7 @@ void resultSetSortSingle (ZebraHandle zh, NMEM nmem,
                          ZebraSet sset, RSET rset,
                          Z_SortKeySpecList *sort_sequence, int *sort_status)
 {
+    int kno = 0;
     int i, psysno = 0;
     struct it_key key;
     struct sortKeyInfo sort_criteria[3];
@@ -605,7 +646,6 @@ void resultSetSortSingle (ZebraHandle zh, NMEM nmem,
     int term_index;
     RSFD rfd;
 
-    yaz_log (LOG_LOG, "resultSetSortSingle start");
     sset->sort_info->num_entries = 0;
 
     sset->hits = 0;
@@ -617,9 +657,9 @@ void resultSetSortSingle (ZebraHandle zh, NMEM nmem,
        Z_SortKeySpec *sks = sort_sequence->specs[i];
        Z_SortKey *sk;
 
-       if (*sks->sortRelation == Z_SortRelation_ascending)
+       if (*sks->sortRelation == Z_SortKeySpec_ascending)
            sort_criteria[i].relation = 'A';
-       else if (*sks->sortRelation == Z_SortRelation_descending)
+       else if (*sks->sortRelation == Z_SortKeySpec_descending)
            sort_criteria[i].relation = 'D';
        else
        {
@@ -670,6 +710,7 @@ void resultSetSortSingle (ZebraHandle zh, NMEM nmem,
     rfd = rset_open (rset, RSETF_READ);
     while (rset_read (rset, rfd, &key, &term_index))
     {
+       kno++;
         if (key.sysno != psysno)
         {
            (sset->hits)++;
@@ -680,6 +721,7 @@ void resultSetSortSingle (ZebraHandle zh, NMEM nmem,
     }
     rset_close (rset, rfd);
 
+    yaz_log (LOG_LOG, "%d keys, %d sysnos, sort", kno, sset->hits);
     for (i = 0; i < rset->no_rset_terms; i++)
        yaz_log (LOG_LOG, "term=\"%s\" nn=%d type=%s count=%d",
                  rset->rset_terms[i]->name,
@@ -687,11 +729,10 @@ void resultSetSortSingle (ZebraHandle zh, NMEM nmem,
                  rset->rset_terms[i]->flags,
                  rset->rset_terms[i]->count);
 
-    *sort_status = Z_SortStatus_success;
-    yaz_log (LOG_LOG, "resultSetSortSingle end");
+    *sort_status = Z_SortResponse_success;
 }
 
-RSET resultSetRef (ZebraHandle zh, Z_ResultSetId *resultSetId)
+RSET resultSetRef (ZebraHandle zh, const char *resultSetId)
 {
     ZebraSet s;
 
@@ -709,15 +750,19 @@ void resultSetRank (ZebraHandle zh, ZebraSet zebraSet, RSET rset)
     ZebraRankClass rank_class;
     struct rank_control *rc;
     struct zset_sort_info *sort_info;
+    const char *rank_handler_name = res_get_def(zh->res, "rank", "rank-1");
 
     sort_info = zebraSet->sort_info;
     sort_info->num_entries = 0;
     zebraSet->hits = 0;
     rfd = rset_open (rset, RSETF_READ);
 
-    yaz_log (LOG_LOG, "resultSetRank");
-
-    rank_class = zebraRankLookup (zh, res_get_def(zh->res, "rank", "rank-1"));
+    rank_class = zebraRankLookup (zh, rank_handler_name);
+    if (!rank_class)
+    {
+        yaz_log (LOG_WARN, "No such rank handler: %s", rank_handler_name);
+        return;
+    }
     rc = rank_class->control;
 
     if (rset_read (rset, rfd, &key, &term_index))
@@ -747,6 +792,7 @@ void resultSetRank (ZebraHandle zh, ZebraSet zebraSet, RSET rset)
     }
     rset_close (rset, rfd);
 
+    yaz_log (LOG_LOG, "%d keys, %d sysnos, rank", kno, zebraSet->hits);
     for (i = 0; i < rset->no_rset_terms; i++)
        yaz_log (LOG_LOG, "term=\"%s\" nn=%d type=%s count=%d",
                  rset->rset_terms[i]->name,
@@ -754,7 +800,6 @@ void resultSetRank (ZebraHandle zh, ZebraSet zebraSet, RSET rset)
                  rset->rset_terms[i]->flags,
                  rset->rset_terms[i]->count);
     
-    yaz_log (LOG_LOG, "%d keys, %d distinct sysnos", kno, zebraSet->hits);
 }
 
 ZebraRankClass zebraRankLookup (ZebraHandle zh, const char *name)
@@ -765,7 +810,7 @@ ZebraRankClass zebraRankLookup (ZebraHandle zh, const char *name)
     if (p && !p->init_flag)
     {
        if (p->control->create)
-           p->class_handle = (*p->control->create)(zh->reg);
+           p->class_handle = (*p->control->create)(zh);
        p->init_flag = 1;
     }
     return p;