Sort Keys are stored using the reckeys_t structure. sort files
[idzebra-moved-to-github.git] / index / zinfo.c
index b474306..f19a068 100644 (file)
@@ -1,5 +1,5 @@
-/* $Id: zinfo.c,v 1.55 2006-02-20 12:41:42 adam Exp $
-   Copyright (C) 1995-2005
+/* $Id: zinfo.c,v 1.63 2006-05-18 12:03:05 adam Exp $
+   Copyright (C) 1995-2006
    Index Data ApS
 
 This file is part of the Zebra server.
@@ -44,6 +44,8 @@ struct zebSUInfo {
        } su;
     } u;
     int ordinal;
+    zint doc_occurrences;
+    zint term_occurrences;
 };
 
 struct zebSUInfoB {
@@ -150,11 +152,15 @@ static Record createRecord(Records records, SYSNO *sysno)
     if (*sysno)
     {
        rec = rec_get(records, *sysno);
+       if (!rec)
+           return 0;
        xfree(rec->info[recInfo_storeData]);
     }
     else
     {
        rec = rec_new(records);
+       if (!rec)
+           return 0;
        *sysno = rec->sysno;
        
        rec->info[recInfo_fileType] =
@@ -520,6 +526,12 @@ ZebraExplainInfo zebraExplain_open(
 
            /* write now because we want to be sure about the sysno */
            trec = rec_new(records);
+           if (!trec)
+           {
+               yaz_log(YLOG_FATAL, "Cannot create root Explain record");
+               nmem_destroy(zei->nmem);
+               return 0;
+           }
            trec->info[recInfo_fileType] =
                rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
            trec->info[recInfo_databaseName] =
@@ -529,11 +541,11 @@ ZebraExplainInfo zebraExplain_open(
            trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
            memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
            trec->size[recInfo_storeData] = sgml_len;
-           
+               
            rec_put(records, &trec);
            rec_rm(&trec);
-
        }
+       
        zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
            
        if (!zei->categoryList->dirty)
@@ -584,6 +596,8 @@ static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
        data1_node *node_str = NULL;
        data1_node *node_ordinal = NULL;
        data1_node *node_type = NULL;
+        data1_node *node_doc_occurrences = NULL;
+        data1_node *node_term_occurrences = NULL;
        data1_node *np2;
        char oid_str[128];
        int oid_str_len;
@@ -605,6 +619,15 @@ static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
                node_ordinal = np2->child;
            else if (!strcmp(np2->u.tag.tag, "type"))
                node_type = np2->child;
+           else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
+               node_doc_occurrences = np2->child;
+           else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
+               node_term_occurrences = np2->child;
+            else
+            {
+                yaz_log(YLOG_LOG, "Unknown tag '%s' in attributeDetails",
+                        np2->u.tag.tag);
+            }
        }
        assert(node_ordinal);
 
@@ -619,6 +642,18 @@ static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
            (*zsuip)->info.index_type = 'w';
        }
 
+        if (node_doc_occurrences)
+        {
+            data1_node *np = node_doc_occurrences;
+            (*zsuip)->info.doc_occurrences = atoi_zn(np->u.data.data,
+                                                     np->u.data.len);
+        }
+        if (node_term_occurrences)
+        {
+            data1_node *np = node_term_occurrences;
+            (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
+                                                      np->u.data.len);
+        }
        if (node_set && node_use)
        {
            (*zsuip)->info.which = ZEB_SU_SET_USE;
@@ -986,6 +1021,8 @@ static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
 #endif
 
     drec = createRecord (zei->records, &sysno);
+    if (!drec)
+       return;
     
     node_ci = data1_search_tag (zei->dh, node_categoryList,
                                "/categoryList");
@@ -1040,6 +1077,8 @@ static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
 #endif
 
     drec = createRecord (zei->records, &zad->sysno);
+    if (!drec)
+       return;
     assert (zad->data1_tree);
 
     node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
@@ -1151,6 +1190,11 @@ static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
        }
        data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
                               zsui->info.ordinal, zei->nmem);
+
+        data1_mk_tag_data_zint (zei->dh, node_attr, "dococcurrences",
+                                zsui->info.doc_occurrences, zei->nmem);
+        data1_mk_tag_data_zint (zei->dh, node_attr, "termoccurrences",
+                                zsui->info.term_occurrences, zei->nmem);
     }
     /* convert to "SGML" and write it */
 #if ZINFO_DEBUG
@@ -1182,6 +1226,8 @@ static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
     yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
 #endif
     drec = createRecord (zei->records, &zdi->sysno);
+    if (!drec)
+       return;
     assert (zdi->data1_database);
 
     node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
@@ -1272,6 +1318,8 @@ static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
 #endif
 
     drec = createRecord (zei->records, &o->sysno);
+    if (!drec)
+       return;
     node_root =
        data1_read_sgml (zei->dh, zei->nmem,
                         "<explain><attributeSetInfo>AttributeSetInfo\n"
@@ -1390,8 +1438,13 @@ int zebraExplain_lookup_attr_su_any_index(ZebraExplainInfo zei,
                                          int set, int use)
 {
     struct zebSUInfoB *zsui;
+    int ord;
 
     assert (zei->curDatabaseInfo);
+
+    ord = zebraExplain_lookup_attr_su(zei, 'w', set, use);
+    if (ord != -1)
+        return ord;
     for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
         zsui; zsui=zsui->next)
         if (zsui->info.which == ZEB_SU_SET_USE &&
@@ -1403,29 +1456,52 @@ int zebraExplain_lookup_attr_su_any_index(ZebraExplainInfo zei,
 int zebraExplain_lookup_attr_su(ZebraExplainInfo zei, int index_type,
                                int set, int use)
 {
-    struct zebSUInfoB *zsui;
+    struct zebSUInfoB **zsui;
 
+#if 0
+    yaz_log(YLOG_LOG, "lookup_attr_su index_type=%d set=%d use=%d",
+            index_type, set, use);
+#endif
     assert (zei->curDatabaseInfo);
-    for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
-        zsui; zsui=zsui->next)
-        if (zsui->info.index_type == index_type &&
-           zsui->info.which == ZEB_SU_SET_USE &&
-           zsui->info.u.su.use == use && zsui->info.u.su.set == set)
-            return zsui->info.ordinal;
+    for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
+        *zsui; zsui = &(*zsui)->next)
+        if ((*zsui)->info.index_type == index_type &&
+           (*zsui)->info.which == ZEB_SU_SET_USE &&
+           (*zsui)->info.u.su.use == use && (*zsui)->info.u.su.set == set)
+        {
+            struct zebSUInfoB *zsui_this = *zsui;
+
+            /* take it out of the list and move to front */
+            *zsui = (*zsui)->next;
+            zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
+            zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
+
+            return zsui_this->info.ordinal;
+        }
     return -1;
 }
 
 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, int index_type,
                                 const char *str)
 {
-    struct zebSUInfoB *zsui;
+    struct zebSUInfoB **zsui;
 
     assert (zei->curDatabaseInfo);
-    for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
-        zsui; zsui=zsui->next)
-        if (zsui->info.index_type == index_type &&
-           zsui->info.which == ZEB_SU_STR && !strcmp(zsui->info.u.str, str))
-            return zsui->info.ordinal;
+    for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
+        *zsui; zsui = &(*zsui)->next)
+        if ((*zsui)->info.index_type == index_type
+            && (*zsui)->info.which == ZEB_SU_STR 
+            && !strcmp((*zsui)->info.u.str, str))
+        {
+            struct zebSUInfoB *zsui_this = *zsui;
+
+            /* take it out of the list and move to front */
+            *zsui = (*zsui)->next;
+            zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
+            zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
+
+            return zsui_this->info.ordinal;
+        }
     return -1;
 }
 
@@ -1441,40 +1517,128 @@ int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
     }
     return 0;
 }
-                         
-int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
-                            int *index_type, 
-                            const char **db,
-                            int *set, int *use)
+
+
+struct zebSUInfoB *zebraExplain_get_sui_info (ZebraExplainInfo zei, int ord,
+                                              int dirty_mark,
+                                              const char **db)
 {
     struct zebDatabaseInfoB *zdb;
+
     for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
     {
-       struct zebSUInfoB *zsui;
+       struct zebSUInfoB **zsui;
 
        if (zdb->attributeDetails->readFlag)
            zebraExplain_readAttributeDetails (zei, zdb->attributeDetails);
-           
-       for (zsui = zdb->attributeDetails->SUInfo; zsui; zsui = zsui->next)
-           if (zsui->info.ordinal == ord)
-           {
-               if (db)
-                   *db = zdb->databaseName;
-               if (zsui->info.which == ZEB_SU_SET_USE)
-               {
-                   if (set)
-                       *set = zsui->info.u.su.set;
-                   if (use)
-                       *use = zsui->info.u.su.use;
-               }
-               if (index_type)
-                   *index_type = zsui->info.index_type;
-               return 0;
-           }
+
+       for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
+             zsui = &(*zsui)->next)
+           if ((*zsui)->info.ordinal == ord)
+            {
+                struct zebSUInfoB *zsui_this = *zsui;
+                
+                /* take it out of the list and move to front */
+                *zsui = (*zsui)->next;
+                zsui_this->next = zdb->attributeDetails->SUInfo;
+                zdb->attributeDetails->SUInfo = zsui_this;
+
+                if (dirty_mark)
+                    zdb->attributeDetails->dirty = 1;
+                if (db)
+                    *db = zdb->databaseName;
+                return zsui_this;
+            }
+    }
+    return 0;
+}
+
+
+
+int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
+                                        int term_delta, int doc_delta)
+{
+    struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
+    if (zsui)
+    {
+        zsui->info.term_occurrences += term_delta;
+        zsui->info.doc_occurrences += doc_delta;
+        return 0;
+    }
+    return -1;
+}
+
+int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
+                                     zint *term_occurrences,
+                                     zint *doc_occurrences)
+{
+    struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
+    if (zsui)
+    {
+        *term_occurrences = zsui->info.term_occurrences;
+        *doc_occurrences = zsui->info.doc_occurrences;
+        return 0;
+    }
+    return -1;
+}
+
+zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
+{
+    struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
+    if (zsui)
+        return zsui->info.doc_occurrences;
+    return 0;
+}
+
+zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
+{
+    struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
+    if (zsui)
+        return zsui->info.term_occurrences;
+    return 0;
+}
+
+int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
+                           int *index_type, 
+                           const char **db,
+                           int *set, int *use,
+                           const char **string_index)
+{
+    struct zebSUInfoB *zsui;
+
+    if (set)
+       *set = -1;
+    if (use)
+       *use = -1;
+    if (index_type)
+       *index_type = 0;
+    if (string_index)
+       *string_index = 0;
+
+    zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
+    if (zsui)
+    {
+        if (zsui->info.which == ZEB_SU_SET_USE)
+        {
+            if (set)
+                *set = zsui->info.u.su.set;
+            if (use)
+                *use = zsui->info.u.su.use;
+        }
+        
+        if (zsui->info.which == ZEB_SU_STR)
+            if (string_index)
+                *string_index = zsui->info.u.str;
+        
+        if (index_type)
+            *index_type = zsui->info.index_type;
+        return 0;
     }
     return -1;
 }
 
+
+
 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
                                          zebAccessObject *op,
                                          Odr_oid *oid)
@@ -1513,41 +1677,43 @@ void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
     }
 }
 
-int zebraExplain_add_attr_su(ZebraExplainInfo zei, int index_type,
-                            int set, int use)
+struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
+                                             int index_type)
 {
     struct zebSUInfoB *zsui;
 
     assert (zei->curDatabaseInfo);
-    zebraExplain_addAttributeSet (zei, set);
     zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
     zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
     zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
     zei->curDatabaseInfo->attributeDetails->dirty = 1;
     zei->dirty = 1;
     zsui->info.index_type = index_type;
+    zsui->info.doc_occurrences = 0;
+    zsui->info.term_occurrences = 0;
+    zsui->info.ordinal = (zei->ordinalSU)++;
+    return zsui;
+}
+
+int zebraExplain_add_attr_su(ZebraExplainInfo zei, int index_type,
+                            int set, int use)
+{
+    struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, index_type);
+
+    zebraExplain_addAttributeSet (zei, set);
     zsui->info.which = ZEB_SU_SET_USE;
     zsui->info.u.su.set = set;
     zsui->info.u.su.use = use;
-    zsui->info.ordinal = (zei->ordinalSU)++;
     return zsui->info.ordinal;
 }
 
 int zebraExplain_add_attr_str(ZebraExplainInfo zei, int index_type,
                              const char *index_name)
 {
-    struct zebSUInfoB *zsui;
+    struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, index_type);
 
-    assert (zei->curDatabaseInfo);
-    zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
-    zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
-    zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
-    zei->curDatabaseInfo->attributeDetails->dirty = 1;
-    zei->dirty = 1;
-    zsui->info.index_type = index_type;
     zsui->info.which = ZEB_SU_STR;
     zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
-    zsui->info.ordinal = (zei->ordinalSU)++;
     return zsui->info.ordinal;
 }
 
@@ -1633,3 +1799,11 @@ void zebraExplain_loadAttsets (data1_handle dh, Res res)
      If the database doesn't exist globally (in TargetInfo) an 
      AttributeSetInfo must be added (globally).
  */
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+