Merge branch 'master' into protocol-version2
authorDennis Schafroth <dennis@indexdata.com>
Mon, 23 Apr 2012 10:44:21 +0000 (10:44 +0000)
committerDennis Schafroth <dennis@indexdata.com>
Mon, 23 Apr 2012 10:44:21 +0000 (10:44 +0000)
1  2 
src/session.c

diff --combined src/session.c
@@@ -76,8 -76,6 +76,8 @@@ Foundation, Inc., 51 Franklin St, Fift
  #include "settings.h"
  #include "normalize7bit.h"
  
 +#include <libxml/tree.h>
 +
  #define TERMLIST_HIGH_SCORE 25
  
  #define MAX_CHUNK 15
@@@ -821,7 -819,8 +821,7 @@@ void session_init_databases(struct sess
  static struct session_database *load_session_database(struct session *se, 
                                                        char *id)
  {
 -    struct database *db = new_database(id, se->session_nmem);
 -
 +    struct database *db = new_database_inherit_settings(id, se->session_nmem, se->service->settings);
      session_init_databases_fun((void*) se, db);
  
      // New sdb is head of se->databases list
@@@ -962,9 -961,7 +962,9 @@@ static struct hitsbytarget *hitsbytarge
          res[*count].id = client_get_id(cl);
          res[*count].name = *name ? name : "Unknown";
          res[*count].hits = client_get_hits(cl);
 +        res[*count].approximation = client_get_approximation(cl);
          res[*count].records = client_get_num_records(cl);
 +        res[*count].filtered = client_get_num_records_filtered(cl);
          res[*count].diagnostic =
              client_get_diagnostic(cl, &res[*count].addinfo);
          res[*count].state = client_get_state_str(cl);
@@@ -1014,25 -1011,14 +1014,25 @@@ static int cmp_ht(const void *p1, cons
      return h2->hits - h1->hits;
  }
  
 +// Compares two hitsbytarget nodes by hitcount
 +static int cmp_ht_approx(const void *p1, const void *p2)
 +{
 +    const struct hitsbytarget *h1 = p1;
 +    const struct hitsbytarget *h2 = p2;
 +    return h2->approximation - h1->approximation;
 +}
 +
  static int targets_termlist_nb(WRBUF wrbuf, struct session *se, int num,
 -                               NMEM nmem)
 +                               NMEM nmem, int version)
  {
      struct hitsbytarget *ht;
      int count, i;
  
      ht = hitsbytarget_nb(se, &count, nmem);
 -    qsort(ht, count, sizeof(struct hitsbytarget), cmp_ht);
 +    if (version >= 2)
 +        qsort(ht, count, sizeof(struct hitsbytarget), cmp_ht_approx);
 +    else
 +        qsort(ht, count, sizeof(struct hitsbytarget), cmp_ht);
      for (i = 0; i < count && i < num && ht[i].hits > 0; i++)
      {
  
          
          wrbuf_printf(wrbuf, "<frequency>" ODR_INT_PRINTF "</frequency>\n",
                       ht[i].hits);
 -        
 +
 +        if (version >= 2) {
 +            // Should not print if we know it isn't a approximation.
 +            wrbuf_printf(wrbuf, "<approximation>" ODR_INT_PRINTF "</approximation>\n", ht[i].approximation);
 +            wrbuf_printf(wrbuf, "<records>%d</records>\n", ht[i].records - ht[i].filtered);
 +            wrbuf_printf(wrbuf, "<filtered>%d</filtered>\n", ht[i].filtered);
 +        }
 +
          wrbuf_puts(wrbuf, "<state>");
          wrbuf_xmlputs(wrbuf, ht[i].state);
          wrbuf_puts(wrbuf, "</state>\n");
  }
  
  void perform_termlist(struct http_channel *c, struct session *se,
 -                      const char *name, int num)
 +                      const char *name, int num, int version)
  {
      int i, j;
      NMEM nmem_tmp = nmem_create();
              wrbuf_xmlputs(c->wrbuf, tname);
              wrbuf_puts(c->wrbuf, "\">\n");
  
 -            targets_termlist_nb(c->wrbuf, se, num, c->nmem);
 +            targets_termlist_nb(c->wrbuf, se, num, c->nmem, version);
              wrbuf_puts(c->wrbuf, "</list>\n");
              must_generate_empty = 0;
          }
@@@ -1199,7 -1178,7 +1199,7 @@@ void show_single_stop(struct session *s
  
  struct record_cluster **show_range_start(struct session *se,
                                           struct reclist_sortparms *sp, 
 -                                         int start, int *num, int *total, Odr_int *sumhits)
 +                                         int start, int *num, int *total, Odr_int *sumhits, Odr_int *approx_hits)
  {
      struct record_cluster **recs;
      struct reclist_sortparms *spp;
      {
          *num = 0;
          *total = 0;
 -        *sumhits = 0;
 +        *sumhits = 0;        
 +        *approx_hits = 0;
          recs = 0;
      }
      else
          *total = reclist_get_num_records(se->reclist);
  
          *sumhits = 0;
 -        for (l = se->clients_active; l; l = l->next)
 +        *approx_hits = 0;
 +        for (l = se->clients_active; l; l = l->next) {
              *sumhits += client_get_hits(l->client);
 -        
 +            *approx_hits += client_get_approximation(l->client);
 +        }
          for (i = 0; i < start; i++)
              if (!reclist_read_record(se->reclist))
              {
@@@ -1565,7 -1541,8 +1565,7 @@@ int ingest_record(struct client *cl, co
      
      if (!check_record_filter(root, sdb))
      {
 -        session_log(se, YLOG_LOG, "Filtered out record no %d from %s",
 -                    record_no, sdb->database->id);
 +        session_log(se, YLOG_LOG, "Filtered out record no %d from %s", record_no, sdb->database->id);
          xmlFreeDoc(xdoc);
          return -2;
      }
      return ret;
  }
  
 +// Skip record on non-zero
  static int check_limit_local(struct client *cl,
                               struct record *record,
                               int record_no)
          char **values = 0;
          int i, num_v = 0;
          
 -        const char *name =
 -            client_get_facet_limit_local(cl, sdb, &l, nmem_tmp, &num_v,
 -                                         &values);
 +        const char *name = client_get_facet_limit_local(cl, sdb, &l, nmem_tmp, &num_v, &values);
          if (!name)
              break;
          
                  }
                  else
                  {
 -                    yaz_log(YLOG_LOG, "cmp: '%s' '%s'",
 -                            rec_md->data.text.disp, values[i]);
 +                    yaz_log(YLOG_LOG, "cmp: '%s' '%s'", rec_md->data.text.disp, values[i]);
                      if (!strcmp(rec_md->data.text.disp, values[i]))
                      {
 +                        // Value equals, should not be filtered.
                          break;
                      }
                  }
                  i++;
              }
          }
 +        // At end , not match
          if (i == num_v)
          {
              skip_record = 1;
@@@ -1786,6 -1763,8 +1786,8 @@@ static int ingest_to_cluster(struct cli
              struct record_metadata *rec_md = 0;
              int md_field_id = -1;
              int sk_field_id = -1;
+             int rank = 0;
+             xmlChar *rank_str = 0;
              
              type = xmlGetProp(n, (xmlChar *) "type");
              value = xmlNodeListGetString(xdoc, n->children, 1);
                  continue;
              
              ser_md = &service->metadata[md_field_id];
+             rank_str = xmlGetProp(n, (xmlChar *) "rank");
+             if (rank_str)
+             {
+                 rank = atoi((const char *) rank_str);
+                 xmlFree(rank_str);
+             }
+             else
+                 rank = ser_md->rank;
              
              if (ser_md->sortkey_offset >= 0)
              {
  
  
              // ranking of _all_ fields enabled ... 
-             if (ser_md->rank)
+             if (rank)
+             {
                  relevance_countwords(se->relevance, cluster, 
-                                      (char *) value, ser_md->rank,
-                                      ser_md->name);
+                                      (char *) value, rank, ser_md->name);
+             }
  
              // construct facets ... unless the client already has reported them
              if (ser_md->termlist && !client_has_facet(cl, (char *) type))