Fixed several prototypes.. Most changes are f() to f(void).
[idzebra-moved-to-github.git] / index / zsets.c
index 5dd1eef..643ba2c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: zsets.c,v 1.104 2006-05-19 23:20:24 adam Exp $
+/* $Id: zsets.c,v 1.112 2006-10-29 17:20:01 adam Exp $
    Copyright (C) 1995-2006
    Index Data ApS
 
@@ -15,9 +15,9 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with Zebra; see the file LICENSE.zebra.  If not, write to the
-Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
 */
 
 
@@ -34,8 +34,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <yaz/diagbib1.h>
 #include <rset.h>
 
-#define SORT_IDX_ENTRYSIZE 64
-#define ZSET_SORT_MAX_LEVEL 3
+#define ZSET_SORT_MAX_LEVEL 10
 
 struct zebra_set_term_entry {
     int reg_type;
@@ -69,7 +68,6 @@ struct zebra_set {
 struct zset_sort_entry {
     zint sysno;
     int score;
-    char buf[ZSET_SORT_MAX_LEVEL][SORT_IDX_ENTRYSIZE];
 };
 
 struct zset_sort_info {
@@ -85,7 +83,7 @@ static int log_level_searchhits=0;
 static int log_level_searchterms=0;
 static int log_level_resultsets=0;
 
-static void loglevels()
+static void loglevels(void)
 {
     if (log_level_set)
         return;
@@ -536,19 +534,16 @@ void zebra_meta_records_destroy (ZebraHandle zh, ZebraMetaRecord *records,
 
 struct sortKeyInfo {
     int relation;
-#if 0
-    int attrUse;
-#else
     int ord;
-#endif
     int numerical;
+    int index_type;
 };
 
-void resultSetInsertSort (ZebraHandle zh, ZebraSet sset,
-                          struct sortKeyInfo *criteria, int num_criteria,
-                          zint sysno)
+void resultSetInsertSort(ZebraHandle zh, ZebraSet sset,
+                         struct sortKeyInfo *criteria, int num_criteria,
+                         zint sysno,
+                         char *cmp_buf[], char *tmp_cmp_buf[])
 {
-    struct zset_sort_entry this_entry;
     struct zset_sort_entry *new_entry = NULL;
     struct zset_sort_info *sort_info = sset->sort_info;
     int i, j;
@@ -556,8 +551,13 @@ void resultSetInsertSort (ZebraHandle zh, ZebraSet sset,
     sortIdx_sysno (zh->reg->sortIdx, sysno);
     for (i = 0; i<num_criteria; i++)
     {
-        sortIdx_type (zh->reg->sortIdx, criteria[i].ord);
-        sortIdx_read (zh->reg->sortIdx, this_entry.buf[i]);
+        char *this_entry_buf = tmp_cmp_buf[i];
+        memset(this_entry_buf, '\0', SORT_IDX_ENTRYSIZE);
+        if (criteria[i].ord != -1)
+        {
+            sortIdx_type(zh->reg->sortIdx, criteria[i].ord);
+            sortIdx_read(zh->reg->sortIdx, this_entry_buf);
+        }
     }
     i = sort_info->num_entries;
     while (--i >= 0)
@@ -565,20 +565,32 @@ void resultSetInsertSort (ZebraHandle zh, ZebraSet sset,
         int rel = 0;
         for (j = 0; j<num_criteria; j++)
         {
+            char *this_entry_buf = tmp_cmp_buf[j];
+            char *other_entry_buf = 
+                cmp_buf[j] + i * SORT_IDX_ENTRYSIZE;
             if (criteria[j].numerical)
             {
-                double diff = atof(this_entry.buf[j]) -
-                              atof(sort_info->entries[i]->buf[j]);
-                rel = 0;
+                char this_entry_org[1024];
+                char other_entry_org[1024];
+                double diff;
+                int index_type = criteria[j].index_type;
+                zebra_term_untrans(zh, index_type, this_entry_org,
+                                   this_entry_buf);
+                zebra_term_untrans(zh, index_type, other_entry_org,
+                                   other_entry_buf);
+                diff = atof(this_entry_org) - atof(other_entry_org);
+                
                 if (diff > 0.0)
                     rel = 1;
                 else if (diff < 0.0)
                     rel = -1;
+                else
+                    rel = 0;
             }
             else
             {
-                rel = memcmp (this_entry.buf[j], sort_info->entries[i]->buf[j],
-                          SORT_IDX_ENTRYSIZE);
+                rel = memcmp(this_entry_buf, other_entry_buf,
+                             SORT_IDX_ENTRYSIZE);
             }
             if (rel)
                 break;
@@ -608,19 +620,30 @@ void resultSetInsertSort (ZebraHandle zh, ZebraSet sset,
     new_entry = sort_info->entries[j];
     while (j != i)
     {
+        int k;
+        for (k = 0; k<num_criteria; k++)
+        {
+            char *j_buf = cmp_buf[k] + j * SORT_IDX_ENTRYSIZE;
+            char *j_1_buf = cmp_buf[k] + (j-1) * SORT_IDX_ENTRYSIZE;
+            memcpy(j_buf, j_1_buf, SORT_IDX_ENTRYSIZE);
+        }
         sort_info->entries[j] = sort_info->entries[j-1];
         --j;
     }
     sort_info->entries[i] = new_entry;
     assert (new_entry);
     for (i = 0; i<num_criteria; i++)
-        memcpy (new_entry->buf[i], this_entry.buf[i], SORT_IDX_ENTRYSIZE);
+    {
+        char *new_entry_buf = cmp_buf[i] + j * SORT_IDX_ENTRYSIZE;
+        char *this_entry_buf = tmp_cmp_buf[i];
+        memcpy(new_entry_buf, this_entry_buf, SORT_IDX_ENTRYSIZE);
+    }
     new_entry->sysno = sysno;
     new_entry->score = -1;
 }
 
-void resultSetInsertRank (ZebraHandle zh, struct zset_sort_info *sort_info,
-                          zint sysno, int score, int relation)
+void resultSetInsertRank(ZebraHandle zh, struct zset_sort_info *sort_info,
+                         zint sysno, int score, int relation)
 {
     struct zset_sort_entry *new_entry = NULL;
     int i, j;
@@ -789,7 +812,9 @@ ZEBRA_RES resultSetSortSingle(ZebraHandle zh, NMEM nmem,
     zint kno = 0;
     zint psysno = 0;
     struct it_key key;
-    struct sortKeyInfo sort_criteria[3];
+    struct sortKeyInfo sort_criteria[ZSET_SORT_MAX_LEVEL];
+    char *cmp_buf[ZSET_SORT_MAX_LEVEL];
+    char *tmp_cmp_buf[ZSET_SORT_MAX_LEVEL];
     int num_criteria;
     RSFD rfd;
     TERMID termid;
@@ -809,13 +834,22 @@ ZEBRA_RES resultSetSortSingle(ZebraHandle zh, NMEM nmem,
 
     sset->hits = 0;
     num_criteria = sort_sequence->num_specs;
-    if (num_criteria > 3)
-        num_criteria = 3;
+    if (num_criteria > ZSET_SORT_MAX_LEVEL)
+        num_criteria = ZSET_SORT_MAX_LEVEL;
     for (i = 0; i < num_criteria; i++)
     {
         Z_SortKeySpec *sks = sort_sequence->specs[i];
         Z_SortKey *sk;
+        ZEBRA_RES res;
+
+        sort_criteria[i].ord = -1;
+        sort_criteria[i].numerical = 0;
 
+        if (sks->which == Z_SortKeySpec_missingValueData)
+        {
+           zebra_setError(zh, YAZ_BIB1_UNSUPP_MISSING_DATA_ACTION, 0);
+            return ZEBRA_FAIL;
+        }
         if (*sks->sortRelation == Z_SortKeySpec_ascending)
             sort_criteria[i].relation = 'A';
         else if (*sks->sortRelation == Z_SortKeySpec_descending)
@@ -843,9 +877,11 @@ ZEBRA_RES resultSetSortSingle(ZebraHandle zh, NMEM nmem,
                    i+1);
             sort_criteria[i].numerical = 0;
             sort_criteria[i].ord = 
-                zebraExplain_lookup_attr_str(zh->reg->zei, 's',
-                                             sk->u.sortField);
-            if (sort_criteria[i].ord == -1)
+                zebraExplain_lookup_attr_str(zh->reg->zei,
+                                             zinfo_index_category_sort,
+                                             -1, sk->u.sortField);
+            if (sks->which != Z_SortKeySpec_null
+                && sort_criteria[i].ord == -1)
             {
                 zebra_setError(zh,
                                YAZ_BIB1_CANNOT_SORT_ACCORDING_TO_SEQUENCE, 0);
@@ -859,13 +895,28 @@ ZEBRA_RES resultSetSortSingle(ZebraHandle zh, NMEM nmem,
             return ZEBRA_FAIL;
         case Z_SortKey_sortAttributes:
             yaz_log(log_level_sort, "key %d is of type sortAttributes", i+1);
-            if (zebra_sort_get_ord(zh, sk->u.sortAttributes,
-                                   &sort_criteria[i].ord,
-                                   &sort_criteria[i].numerical)
-                != ZEBRA_OK)
+            res = zebra_sort_get_ord(zh, sk->u.sortAttributes,
+
+                                     &sort_criteria[i].ord,
+                                     &sort_criteria[i].numerical);
+            if (sks->which != Z_SortKeySpec_null && res != ZEBRA_OK)
                 return ZEBRA_FAIL;
             break;
         }
+        if (zebraExplain_lookup_ord(zh->reg->zei, sort_criteria[i].ord,
+                                    &sort_criteria[i].index_type,
+                                    0, 0))
+        {
+            zebra_setError(zh, YAZ_BIB1_CANNOT_SORT_ACCORDING_TO_SEQUENCE, 0);
+            return ZEBRA_FAIL;
+        }
+    }
+    /* allocate space for each cmpare buf + one extra for tmp comparison */
+    for (i = 0; i<num_criteria; i++)
+    {
+        cmp_buf[i] = xmalloc(sset->sort_info->max_entries
+                             * SORT_IDX_ENTRYSIZE);
+        tmp_cmp_buf[i] = xmalloc(SORT_IDX_ENTRYSIZE);
     }
     rfd = rset_open (rset, RSETF_READ);
     while (rset_read (rfd, &key, &termid))
@@ -878,11 +929,19 @@ ZEBRA_RES resultSetSortSingle(ZebraHandle zh, NMEM nmem,
         {
             (sset->hits)++;
             psysno = this_sys;
-            resultSetInsertSort (zh, sset,
-                                 sort_criteria, num_criteria, psysno);
+            resultSetInsertSort(zh, sset,
+                                sort_criteria, num_criteria, psysno, cmp_buf,
+                                tmp_cmp_buf);
         }
     }
     rset_close (rfd);
+
+    for (i = 0; i<num_criteria; i++)
+    {
+        xfree(cmp_buf[i]);
+        xfree(tmp_cmp_buf[i]);
+    }
+
     yaz_log(log_level_sort, ZINT_FORMAT " keys, " ZINT_FORMAT " sysnos, sort",
            kno, sset->hits);   
     for (i = 0; i < numTerms; i++)
@@ -940,7 +999,7 @@ ZEBRA_RES resultSetRank(ZebraHandle zh, ZebraSet zebraSet,
     {
        RSFD rfd = rset_open(rset, RSETF_READ);
        struct rank_control *rc = rank_class->control;
-       double score;
+       int score;
        zint count = 0;
        
        void *handle =
@@ -1158,8 +1217,8 @@ ZEBRA_RES zebra_snippets_hit_vector(ZebraHandle zh, const char *setname,
        NMEM nmem = nmem_create();
        struct it_key key;
        RSET rsets[2], rset_comb;
-       RSET rset_temp = rstemp_create(nmem, kc, kc->scope, 
-                                      res_get (zh->res, "setTmpDir"),0 );
+       RSET rset_temp = rset_create_temp(nmem, kc, kc->scope, 
+                                          res_get (zh->res, "setTmpDir"),0 );
        
        TERMID termid;
        RSFD rsfd = rset_open(rset_temp, RSETF_WRITE);
@@ -1175,7 +1234,7 @@ ZEBRA_RES zebra_snippets_hit_vector(ZebraHandle zh, const char *setname,
        rsets[0] = rset_temp;
        rsets[1] = rset_dup(sset->rset);
        
-       rset_comb = rsmulti_and_create(nmem, kc, kc->scope, 2, rsets);
+       rset_comb = rset_create_and(nmem, kc, kc->scope, 2, rsets);
 
        rsfd = rset_open(rset_comb, RSETF_READ);