2007.
[idzebra-moved-to-github.git] / index / rpnsearch.c
index 909e9cc..7743362 100644 (file)
@@ -1,5 +1,5 @@
-/* $Id: rpnsearch.c,v 1.1 2006-09-21 08:56:52 adam Exp $
-   Copyright (C) 1995-2006
+/* $Id: rpnsearch.c,v 1.6 2007-01-15 15:10:17 adam Exp $
+   Copyright (C) 1995-2007
    Index Data ApS
 
 This file is part of the Zebra server.
@@ -78,19 +78,25 @@ struct grep_info {
     ISAM_P *isam_p_buf;
     int isam_p_size;        
     int isam_p_indx;
+    int trunc_max;
     ZebraHandle zh;
     int reg_type;
     ZebraSet termset;
 };        
 
-static void add_isam_p(const char *name, const char *info,
-                      struct grep_info *p)
+static int add_isam_p(const char *name, const char *info,
+                      struct grep_info *p)
 {
     if (!log_level_set)
     {
         log_level_rpn = yaz_log_module_level("rpn");
         log_level_set = 1;
     }
+    /* we may have to stop this madness.. NOTE: -1 so that if
+       truncmax == trunxlimit we do *not* generate result sets */
+    if (p->isam_p_indx >= p->trunc_max - 1)
+        return 1;
+
     if (p->isam_p_indx == p->isam_p_size)
     {
         ISAM_P *new_isam_p_buf;
@@ -140,12 +146,12 @@ static void add_isam_p(const char *name, const char *info,
                         index_name, term_tmp);
     }
     (p->isam_p_indx)++;
+    return 0;
 }
 
 static int grep_handle(char *name, const char *info, void *p)
 {
-    add_isam_p(name, info, (struct grep_info *) p);
-    return 0;
+    return add_isam_p(name, info, (struct grep_info *) p);
 }
 
 static int term_pre(ZebraMaps zebra_maps, int reg_type, const char **src,
@@ -734,6 +740,10 @@ static int string_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
             *term_tmp++ = '[';
 
             *term_tmp++ = '^';
+
+            *term_tmp++ = 1;
+            *term_tmp++ = FIRST_IN_FIELD_CHAR;
+
             string_rel_add_char(&term_tmp, term_component, &i);
             *term_tmp++ = '-';
 
@@ -746,6 +756,7 @@ static int string_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
         }
         *term_tmp++ = ')';
         *term_tmp = '\0';
+        yaz_log(YLOG_LOG, "term_dict=%s", term_dict);
         break;
     case 2:
         if (!term_100(zh->reg->zebra_maps, reg_type,
@@ -764,6 +775,10 @@ static int string_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
             *term_tmp++ = '[';
 
             *term_tmp++ = '^';
+
+            *term_tmp++ = 1;
+            *term_tmp++ = FIRST_IN_FIELD_CHAR;
+
             string_rel_add_char(&term_tmp, term_component, &i);
             *term_tmp++ = '-';
 
@@ -1200,6 +1215,7 @@ static ZEBRA_RES grep_info_prepare(ZebraHandle zh,
 #ifdef TERM_COUNT
     grep_info->term_no = 0;
 #endif
+    grep_info->trunc_max = atoi(res_get_def(zh->res, "truncmax", "10000"));
     grep_info->isam_p_size = 0;
     grep_info->isam_p_buf = NULL;
     grep_info->zh = zh;
@@ -1683,7 +1699,7 @@ static int numeric_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
     yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_tmp);
     r = dict_lookup_grep(zh->reg->dict, term_dict, 0, grep_info, max_pos,
                           0, grep_handle);
-    if (r)
+    if (r != 0 && r != 1)
         yaz_log(YLOG_WARN, "dict_lookup_grep fail, rel = gt: %d", r);
     yaz_log(log_level_rpn, "%d positions", grep_info->isam_p_indx);
     return 1;
@@ -2309,6 +2325,37 @@ static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
                                      Z_Operator *parent_op,
                                      struct rset_key_control *kc);
 
+ZEBRA_RES rpn_get_top_approx_limit(ZebraHandle zh, Z_RPNStructure *zs,
+                                   zint *approx_limit)
+{
+    ZEBRA_RES res = ZEBRA_OK;
+    if (zs->which == Z_RPNStructure_complex)
+    {
+        if (res == ZEBRA_OK)
+            res = rpn_get_top_approx_limit(zh, zs->u.complex->s1,
+                                           approx_limit);
+        if (res == ZEBRA_OK)
+            res = rpn_get_top_approx_limit(zh, zs->u.complex->s2,
+                                           approx_limit);
+    }
+    else if (zs->which == Z_RPNStructure_simple)
+    {
+        if (zs->u.simple->which == Z_Operand_APT)
+        {
+            Z_AttributesPlusTerm *zapt = zs->u.simple->u.attributesPlusTerm;
+            AttrType global_hits_limit_attr;
+            int l;
+            
+            attr_init_APT(&global_hits_limit_attr, zapt, 12);
+            
+            l = attr_find(&global_hits_limit_attr, NULL);
+            if (l != -1)
+                *approx_limit = l;
+        }
+    }
+    return res;
+}
+
 ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs,
                         oid_value attributeSet, 
                         NMEM stream, NMEM rset_nmem,