-/* $Id: pazpar2.c,v 1.19 2007-01-08 18:32:35 quinn Exp $ */;
+/* $Id: pazpar2.c,v 1.26 2007-01-10 11:56:10 adam Exp $ */
#include <stdlib.h>
#include <stdio.h>
#include <yaz/timing.h>
#endif
+#include <netinet/in.h>
+
#include "pazpar2.h"
#include "eventl.h"
#include "http.h"
return rdoc;
}
+// Extract what appears to be years from buf, storing highest and
+// lowest values.
+static int extract_years(const char *buf, int *first, int *last)
+{
+ *first = -1;
+ *last = -1;
+ while (*buf)
+ {
+ const char *e;
+ int len;
+
+ while (*buf && !isdigit(*buf))
+ buf++;
+ len = 0;
+ for (e = buf; *e && isdigit(*e); e++)
+ len++;
+ if (len == 4)
+ {
+ int value = atoi(buf);
+ if (*first < 0 || value < *first)
+ *first = value;
+ if (*last < 0 || value > *last)
+ *last = value;
+ }
+ buf = e;
+ }
+ return *first;
+}
+
static struct record *ingest_record(struct client *cl, Z_External *rec)
{
xmlDoc *xdoc = normalize_record(cl, rec);
res = nmem_malloc(se->nmem, sizeof(struct record));
res->next = 0;
- res->target_offset = -1;
- res->term_frequency_vec = 0;
res->metadata = nmem_malloc(se->nmem,
sizeof(struct record_metadata*) * service->num_metadata);
- bzero(res->metadata, sizeof(struct record_metadata*) * service->num_metadata);
- res->relevance = 0;
+ memset(res->metadata, 0, sizeof(struct record_metadata*) * service->num_metadata);
mergekey_norm = nmem_strdup(se->nmem, (char*) mergekey);
xmlFree(mergekey);
normalize_mergekey(mergekey_norm);
- cluster = reclist_insert(se->reclist, res, mergekey_norm);
+ cluster = reclist_insert(se->reclist, res, mergekey_norm, &se->total_merged);
if (!cluster)
{
/* no room for record */
struct conf_metadata *md = 0;
struct record_metadata **wheretoput, *newm;
int imeta;
+ int first, last;
// First, find out what field we're looking at
for (imeta = 0; imeta < service->num_metadata; imeta++)
{
newm->data.text = nmem_strdup(se->nmem, value);
}
+ else if (md->type == Metadata_type_year)
+ {
+ if (extract_years(value, &first, &last) < 0)
+ continue;
+ }
else
{
yaz_log(YLOG_WARN, "Unknown type in metadata element %s", type);
continue;
}
+ if (md->type == Metadata_type_year && md->merge != Metadata_merge_range)
+ {
+ yaz_log(YLOG_WARN, "Only range merging supported for years");
+ continue;
+ }
if (md->merge == Metadata_merge_unique)
{
struct record_metadata *mnode;
newm->next = *wheretoput;
*wheretoput = newm;
}
+ else if (md->merge == Metadata_merge_range)
+ {
+ assert(md->type == Metadata_type_year);
+ if (!*wheretoput)
+ {
+ *wheretoput = newm;
+ (*wheretoput)->data.year.year1 = first;
+ (*wheretoput)->data.year.year2 = last;
+ }
+ else
+ {
+ if (first < (*wheretoput)->data.year.year1)
+ (*wheretoput)->data.year.year1 = first;
+ if (last > (*wheretoput)->data.year.year2)
+ (*wheretoput)->data.year.year2 = last;
+ }
+ }
else
yaz_log(YLOG_WARN, "Don't know how to merge on element name %s", md->name);
- relevance_countwords(se->relevance, cluster, value, 4);
+ if (md->rank)
+ relevance_countwords(se->relevance, cluster, value, md->rank);
if (md->termlist)
add_facet(se, type, value);
xmlFree(type);
if (!(addr = cs_straddr(link, cl->database->host->ipport)))
{
- yaz_log(YLOG_WARN|YLOG_ERRNO, "Lookup of IP address failed?");
+ yaz_log(YLOG_WARN|YLOG_ERRNO, "Lookup of IP address %s failed?",
+ cl->database->host->ipport);
return 0;
}
}
assert(addrinfo->ai_family == PF_INET);
memcpy(addrbuf, &((struct sockaddr_in*)addrinfo->ai_addr)->sin_addr.s_addr, 4);
- sprintf(ipport, "%hhd.%hhd.%hhd.%hhd:%s",
+ sprintf(ipport, "%u.%u.%u.%u:%s",
addrbuf[0], addrbuf[1], addrbuf[2], addrbuf[3], port);
host->ipport = xstrdup(ipport);
freeaddrinfo(addrinfo);
se->reclist = reclist_create(se->nmem, maxrecs);
extract_terms(se->nmem, query, p);
se->relevance = relevance_create(se->nmem, (const char **) p, maxrecs);
- se->total_records = se->total_hits = 0;
+ se->total_records = se->total_hits = se->total_merged = 0;
se->expected_maxrecs = maxrecs;
}
else
}
#endif
+struct record_cluster *show_single(struct session *s, int id)
+{
+ struct record_cluster *r;
+
+ reclist_rewind(s->reclist);
+ while ((r = reclist_read_record(s->reclist)))
+ if (r->recid == id)
+ return r;
+ return 0;
+}
+
struct record_cluster **show(struct session *s, int start, int *num, int *total,
int *sumhits, NMEM nmem_show)
{
struct client *cl;
int count = 0;
- bzero(stat, sizeof(*stat));
+ memset(stat, 0, sizeof(*stat));
for (cl = se->clients; cl; cl = cl->next)
{
if (!cl->connection)
char *arg;
int setport = 0;
- if (signal(SIGPIPE, SIG_IGN) < 0)
+ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
yaz_log(YLOG_WARN|YLOG_ERRNO, "signal");
yaz_log_init(YLOG_DEFAULT_LEVEL, "pazpar2", 0);