Extend the ranking interface so staticrank is passed to calc method.
[idzebra-moved-to-github.git] / index / zebraapi.c
index 8d6acb9..ce56154 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: zebraapi.c,v 1.169 2005-05-17 08:50:49 adam Exp $
+/* $Id: zebraapi.c,v 1.183 2005-08-19 09:21:34 adam Exp $
    Copyright (C) 1995-2005
    Index Data ApS
 
@@ -27,7 +27,8 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <io.h>
 #include <process.h>
 #include <direct.h>
-#else
+#endif
+#if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 
@@ -38,6 +39,8 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <charmap.h>
 #include <idzebra/api.h>
 
+#define DEFAULT_APPROX_LIMIT 2000000000
+
 /* simple asserts to validate the most essential input args */
 #define ASSERTZH assert(zh && zh->service)
 #define ASSERTZHRES assert(zh && zh->service && zh->res)
@@ -115,6 +118,7 @@ ZebraHandle zebra_open (ZebraService zs)
     zh->num_basenames = 0;
     zh->basenames = 0;
 
+    zh->approx_limit = DEFAULT_APPROX_LIMIT;
     zh->trans_no = 0;
     zh->trans_w_no = 0;
 
@@ -122,6 +126,7 @@ ZebraHandle zebra_open (ZebraService zs)
     zh->lock_shadow = 0;
 
     zh->shadow_enable = 1;
+    zh->m_staticrank = 0;
 
     default_encoding = res_get_def(zs->global_res, "encoding", "ISO-8859-1");
 
@@ -168,33 +173,39 @@ ZebraService zebra_start_res (const char *configName, Res def_res, Res over_res)
         log_level = yaz_log_module_level("zebraapi");
         log_level_initialized = 1;
     }
-
-    yaz_log(log_level, "zebra_start %s",configName);
-    assert(configName);
+    
+    yaz_log(YLOG_LOG, "zebra_start %s %s", ZEBRAVER,
+           configName ? configName : "");
 
     if ((res = res_open (configName, def_res, over_res)))
     {
+       const char *passwd_plain = 0;
+       const char *passwd_encrypt = 0;
         ZebraService zh = xmalloc(sizeof(*zh));
 
-       yaz_log (YLOG_DEBUG, "Read resources `%s'", configName);
-        
         zh->global_res = res;
-        zh->configName = xstrdup(configName);
         zh->sessions = 0;
         
         zebra_chdir (zh);
         
         zebra_mutex_cond_init (&zh->session_lock);
-        if (!res_get (zh->global_res, "passwd"))
+       passwd_plain = res_get (zh->global_res, "passwd");
+       passwd_encrypt = res_get (zh->global_res, "passwd.c");
+
+        if (!passwd_plain && !passwd_encrypt)
             zh->passwd_db = NULL;
         else
         {
-            zh->passwd_db = passwd_db_open ();
+            zh->passwd_db = passwd_db_open();
             if (!zh->passwd_db)
                 yaz_log (YLOG_WARN|YLOG_ERRNO, "passwd_db_open failed");
             else
-                passwd_db_file (zh->passwd_db,
-                                res_get (zh->global_res, "passwd"));
+           {
+               if (passwd_plain)
+                   passwd_db_file_plain(zh->passwd_db, passwd_plain);
+               if (passwd_encrypt)
+                   passwd_db_file_crypt(zh->passwd_db, passwd_encrypt);
+           }
         }
         zh->path_root = res_get (zh->global_res, "root");
        zh->nmem = nmem_create();
@@ -224,22 +235,16 @@ Dict dict_open_res (BFiles bfs, const char *name, int cache, int rw,
 {
     int page_size = 4096;
     char resource_str[200];
-    const char *v;
     sprintf (resource_str, "dict.%.100s.pagesize", name);
     assert(bfs);
     assert(name);
 
-    v = res_get(res, resource_str);
-    if (v)
-    {
-       page_size = atoi(v);
+    if (res_get_int(res, resource_str, &page_size) == ZEBRA_OK)
        yaz_log(YLOG_LOG, "Using custom dictionary page size %d for %s",
                page_size, name);
-    }
     return dict_open(bfs, name, cache, rw, compact_flag, page_size);
 }
 
-
 static
 struct zebra_register *zebra_register_open (ZebraService zs, const char *name,
                                             int rw, int useshadow, Res res,
@@ -309,6 +314,9 @@ struct zebra_register *zebra_register_open (ZebraService zs, const char *name,
 
     reg->sortKeys.buf = 0;
     reg->sortKeys.buf_max = 0;
+#if NATTR
+    reg->sortKeys.codec_handle = iscz1_start();
+#endif
 
     reg->records = 0;
     reg->dict = 0;
@@ -322,8 +330,9 @@ struct zebra_register *zebra_register_open (ZebraService zs, const char *name,
     reg->key_file_no = 0;
     reg->ptr_i = 0;
     
-    zebraRankInstall (reg, rank1_class);
-    zebraRankInstall (reg, rankzv_class);
+    zebraRankInstall (reg, rank_1_class);
+    zebraRankInstall (reg, rank_zv_class);
+    zebraRankInstall (reg, rank_static_class);
 
     recordCompression = res_get_def (res, "recordCompression", "none");
     if (!strcmp (recordCompression, "none"))
@@ -473,6 +482,10 @@ static void zebra_register_close (ZebraService zs, struct zebra_register *reg)
     xfree(reg->keys.buf);
     if (reg->keys.codec_handle)
        iscz1_stop(reg->keys.codec_handle);
+#if NATTR
+    if (reg->sortKeys.codec_handle)
+       iscz1_stop(reg->sortKeys.codec_handle);
+#endif
     xfree(reg->key_buf);
     xfree(reg->name);
     xfree(reg);
@@ -497,7 +510,6 @@ ZEBRA_RES zebra_stop(ZebraService zs)
     recTypeClass_destroy(zs->record_classes);
     nmem_destroy(zs->nmem);
     res_close (zs->global_res);
-    xfree(zs->configName);
     xfree(zs);
     return ZEBRA_OK;
 }
@@ -683,6 +695,19 @@ static void zebra_select_register (ZebraHandle zh, const char *new_reg)
            zebra_close_res(zh);
        }
     }
+    if (zh->res)
+    {
+       int approx = 0;
+       if (res_get_int(zh->res, "estimatehits", &approx) == ZEBRA_OK)
+           zebra_set_approx_limit(zh, approx);
+    }
+    if (zh->res)
+    {
+       if (res_get_int(zh->res, "staticrank", &zh->m_staticrank) == ZEBRA_OK)
+           yaz_log(YLOG_LOG, "static rank set and is %d", zh->m_staticrank);
+       else
+           yaz_log(YLOG_LOG, "static rank unset");
+    }
 }
 
 void map_basenames_func (void *vp, const char *name, const char *value)
@@ -855,6 +880,14 @@ ZEBRA_RES zebra_select_databases (ZebraHandle zh, int num_bases,
     return ZEBRA_OK;
 }
 
+ZEBRA_RES zebra_set_approx_limit(ZebraHandle zh, zint approx_limit)
+{
+    if (approx_limit == 0)
+       approx_limit = DEFAULT_APPROX_LIMIT;
+    zh->approx_limit = approx_limit;
+    return ZEBRA_OK;
+}
+
 ZEBRA_RES zebra_search_RPN(ZebraHandle zh, ODR o, Z_RPNQuery *query,
                           const char *setname, zint *hits)
 {
@@ -935,11 +968,18 @@ ZEBRA_RES zebra_records_retrieve(ZebraHandle zh, ODR stream,
            {
                char *buf;
                int len;
+               zebra_snippets *hit_snippet = zebra_snippets_create();
+
+               zebra_snippets_hit_vector(zh, setname, poset[i].sysno, 
+                                         hit_snippet);
+
                recs[i].errCode =
                    zebra_record_fetch(zh, poset[i].sysno, poset[i].score,
+                                      hit_snippet,
                                       stream, input_format, comp,
                                       &recs[i].format, &buf, &len,
                                       &recs[i].base, &recs[i].errString);
+               
                recs[i].len = len;
                if (len > 0)
                {
@@ -950,15 +990,24 @@ ZEBRA_RES zebra_records_retrieve(ZebraHandle zh, ODR stream,
                    recs[i].buf = buf;
                 recs[i].score = poset[i].score;
                 recs[i].sysno = poset[i].sysno;
+               zebra_snippets_destroy(hit_snippet);
            }
            else
            {
-               if (ret == ZEBRA_OK) /* only need to set it once */
+               /* only need to set it once */
+               if (pos_array[i] < zh->approx_limit && ret == ZEBRA_OK)
+               {
                    zebra_setError_zint(zh,
                                        YAZ_BIB1_PRESENT_REQUEST_OUT_OF_RANGE,
                                        pos_array[i]);
-               ret = ZEBRA_FAIL;
-                break;
+                   ret = ZEBRA_FAIL;
+                   break;
+               }
+               recs[i].buf = 0;  /* no record and no error issued */
+               recs[i].len = 0;
+               recs[i].errCode = 0;
+               recs[i].format = VAL_NONE;
+               recs[i].sysno = 0;
            }
        }
        zebra_meta_records_destroy(zh, poset, num_recs);
@@ -971,7 +1020,8 @@ ZEBRA_RES zebra_records_retrieve(ZebraHandle zh, ODR stream,
 ZEBRA_RES zebra_scan_PQF(ZebraHandle zh, ODR stream, const char *query,
                         int *position,
                         int *num_entries, ZebraScanEntry **entries,
-                        int *is_partial)
+                        int *is_partial,
+                        const char *setname)
 {
     YAZ_PQF_Parser pqf_parser = yaz_pqf_create ();
     Z_AttributesPlusTerm *zapt;
@@ -985,18 +1035,21 @@ ZEBRA_RES zebra_scan_PQF(ZebraHandle zh, ODR stream, const char *query,
     }
     else
        res = zebra_scan(zh, stream, zapt, VAL_BIB1,
-                        position, num_entries, entries, is_partial);
+                        position, num_entries, entries, is_partial,
+                        setname);
     yaz_pqf_destroy (pqf_parser);
     return res;
 }
 
-ZEBRA_RES zebra_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
-                     oid_value attributeset,
-                     int *position,
-                     int *num_entries, ZebraScanEntry **entries,
-                     int *is_partial)
+ZEBRA_RES zebra_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
+                    oid_value attributeset,
+                    int *position,
+                    int *num_entries, ZebraScanEntry **entries,
+                    int *is_partial,
+                    const char *setname)
 {
     ZEBRA_RES res;
+    RSET limit_rset = 0;
     ASSERTZH;
     assert(stream);
     assert(zapt);
@@ -1012,9 +1065,21 @@ ZEBRA_RES zebra_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
        *num_entries = 0;
        return ZEBRA_FAIL;
     }
+    if (setname)
+    {
+       limit_rset = resultSetRef(zh, setname);
+       if (!limit_rset)
+       {
+           zebra_setError(zh, 
+                          YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
+                          setname);
+           zebra_end_read (zh);
+           return ZEBRA_FAIL;
+       }
+    }
     res = rpn_scan (zh, stream, zapt, attributeset,
                    zh->num_basenames, zh->basenames, position,
-                   num_entries, entries, is_partial, 0, 0);
+                   num_entries, entries, is_partial, limit_rset, 0);
     zebra_end_read (zh);
     return res;
 }
@@ -1289,20 +1354,20 @@ static int delete_SU_handle(void *handle, int ord)
     return 0;
 }
 
-ZEBRA_RES zebra_drop_database  (ZebraHandle zh, const char *database)
+ZEBRA_RES zebra_drop_database(ZebraHandle zh, const char *db)
 {
     ZEBRA_RES ret = ZEBRA_OK;
     ASSERTZH;
-    yaz_log(log_level, "zebra_drop_database");
+    yaz_log(log_level, "zebra_drop_database %s", db);
     zebra_clearError(zh);
 
-    if (zebra_select_database (zh, database) == ZEBRA_FAIL)
+    if (zebra_select_database (zh, db) == ZEBRA_FAIL)
         return ZEBRA_FAIL;
     if (zebra_begin_trans (zh, 1) == ZEBRA_FAIL)
         return ZEBRA_FAIL;
     if (zh->reg->isamb)
     {
-       zebraExplain_curDatabase (zh->reg->zei, database);
+       zebraExplain_curDatabase (zh->reg->zei, db);
        
        zebraExplain_trav_ord(zh->reg->zei, zh, delete_SU_handle);
        zebraExplain_removeDatabase(zh->reg->zei, zh);
@@ -1316,24 +1381,24 @@ ZEBRA_RES zebra_drop_database  (ZebraHandle zh, const char *database)
     return ret;
 }
 
-ZEBRA_RES zebra_create_database (ZebraHandle zh, const char *database)
+ZEBRA_RES zebra_create_database (ZebraHandle zh, const char *db)
 {
     ASSERTZH;
-    yaz_log(log_level, "zebra_create_database %s", database);
-    assert(database);
+    yaz_log(log_level, "zebra_create_database %s", db);
+    assert(db);
     zebra_clearError(zh);
 
-    if (zebra_select_database (zh, database) == ZEBRA_FAIL)
+    if (zebra_select_database (zh, db) == ZEBRA_FAIL)
         return ZEBRA_FAIL;
     if (zebra_begin_trans (zh, 1))
         return ZEBRA_FAIL;
 
     /* announce database */
-    if (zebraExplain_newDatabase (zh->reg->zei, database, 0 
+    if (zebraExplain_newDatabase (zh->reg->zei, db, 0 
                                   /* explainDatabase */))
     {
         zebra_end_trans (zh);
-       zebra_setError(zh, YAZ_BIB1_ES_IMMEDIATE_EXECUTION_FAILED, database);
+       zebra_setError(zh, YAZ_BIB1_ES_IMMEDIATE_EXECUTION_FAILED, db);
        return ZEBRA_FAIL;
     }
     return zebra_end_trans (zh);
@@ -1976,7 +2041,6 @@ const char *zebra_get_resource(ZebraHandle zh,
     const char *v;
     ASSERTZH;
     assert(name);
-    assert(defaultvalue);
     v = res_get_def (zh->res, name, (char *)defaultvalue);
     zebra_clearError(zh);
     yaz_log(log_level, "zebra_get_resource %s:%s", name, v);
@@ -2128,9 +2192,9 @@ ZEBRA_RES zebra_delete_record (ZebraHandle zh,
 */
 
 ZEBRA_RES zebra_search_PQF(ZebraHandle zh, const char *pqf_query,
-                          const char *setname, zint *numhits)
+                          const char *setname, zint *hits)
 {
-    zint hits = 0;
+    zint lhits = 0;
     ZEBRA_RES res = ZEBRA_OK;
     Z_RPNQuery *query;
     ODR odr = odr_createmem(ODR_ENCODE);
@@ -2149,14 +2213,14 @@ ZEBRA_RES zebra_search_PQF(ZebraHandle zh, const char *pqf_query,
        res = ZEBRA_FAIL;
     }
     else
-        res = zebra_search_RPN(zh, odr, query, setname, &hits);
+        res = zebra_search_RPN(zh, odr, query, setname, &lhits);
     
     odr_destroy(odr);
 
-    yaz_log(log_level, "Hits: " ZINT_FORMAT, hits);
+    yaz_log(log_level, "Hits: " ZINT_FORMAT, lhits);
 
-    if (numhits)
-       *numhits = hits;
+    if (hits)
+       *hits = lhits;
 
     return res;
 }