<start>0</start>
<num>2</num>
<hit>
- <title>How to program a computer, by Jack Collins</title>
+ <md-title>How to program a computer, by Jack Collins</md-title>
<count>2</count> <!-- Number of merged records -->
</hit>
<hit>
- <title>
+ <md-title>
Computer processing of dynamic images from an Anger scintillation camera :
the proceedings of a workshop /
- </title>
+ </md-title>
</hit>
</show>
How to use this:
-Usage: pazpar2 -h [listen-host:]listen-port -p host-to-proxy -s targetfile \
- -x normalization-stylesheet
+Usage: pazpar2 -f configfile -h [listen-host:]listen-port -p host-to-proxy -s targetfile
The host-to-proxy is the webserver where the user interface script
lives. It is used both for domain-name lookup and the contents of
<xsl:value-of select="marc:datafield[@tag='100']/marc:subfield[@code='a']"/>
</xsl:attribute>
-
<pz:metadata type="title">
<xsl:value-of select="marc:datafield[@tag='245']/marc:subfield[@code='a']"/>
<xsl:text> </xsl:text>
<xsl:value-of select="marc:datafield[@tag='245']/marc:subfield[@code='b']"/>
</pz:metadata>
+ <!--
+ <xsl:for-each select="marc:datafield[@tag='260']">
+ <pz:metadata type="date">
+ <xsl:value-of select="marc:subfield[@code='c']"/>
+ </pz:metadata>
+ </xsl:for-each>
+ -->
+
<xsl:for-each select="marc:datafield[@tag='650']">
- <pz:facet type="subject">
+ <pz:metadata type="subject">
<xsl:value-of select="marc:subfield[@code='a']"/>
- </pz:facet>
+ </pz:metadata>
</xsl:for-each>
<xsl:for-each select="marc:datafield[@tag='100']">
- <pz:facet type="author">
+ <pz:metadata type="author">
<xsl:value-of select="marc:subfield[@code='a']"/>
- </pz:facet>
+ </pz:metadata>
</xsl:for-each>
+
</pz:record>
</xsl:template>
</xsl:stylesheet>
-
<?xml version="1.0" encoding="UTF-8"?> <pazpar2 xmlns="http://www.indexdata.com/pazpar2/1.0">
-<!-- NOTE: This is not yet a functional config file. It's meant as a scratchpad/
- discussion area to figure out just how the heck to structure this kind of
- configuration.
--->
-
<server>
<listen port="9004"/>
<proxy host="localhost" port="80"/>
<service>
- <!-- <metadata name="title"/> -->
+ <metadata name="title" brief="yes" sortkey="skiparticle" merge="longest"/>
+ <!-- <metadata name="date" brief="yes" sortkey="numeric" type="year" merge="range"/> -->
+ <metadata name="author" brief="yes" termlist="yes" merge="longest"/>
+ <metadata name="subject" merge="unique" termlist="yes"/>
</service>
</server>
-/* $Id: config.c,v 1.4 2007-01-08 12:43:41 adam Exp $ */
+/* $Id: config.c,v 1.5 2007-01-08 18:32:35 quinn Exp $ */
#include <string.h>
{
xmlNode *n;
struct conf_service *r = nmem_malloc(nmem, sizeof(struct conf_service));
+ int num_metadata = 0;
+ int md_node = 0;
- r->termlists = 0;
+ // Allocate array of conf metadata structs, if necessary
+ for (n = node->children; n; n = n->next)
+ if (n->type == XML_ELEMENT_NODE && !strcmp(n->name, "metadata"))
+ num_metadata++;
+ if (num_metadata)
+ r->metadata = nmem_malloc(nmem, sizeof(struct conf_metadata) * num_metadata);
+ r->num_metadata = num_metadata;
for (n = node->children; n; n = n->next)
{
if (n->type != XML_ELEMENT_NODE)
continue;
- if (!strcmp(n->name, "termlist"))
+ if (!strcmp(n->name, "metadata"))
{
- struct conf_termlist *tl = nmem_malloc(nmem, sizeof(struct conf_termlist));
+ struct conf_metadata *md = &r->metadata[md_node];
xmlChar *name = xmlGetProp(n, "name");
+ xmlChar *brief = xmlGetProp(n, "brief");
+ xmlChar *sortkey = xmlGetProp(n, "sortkey");
+ xmlChar *merge = xmlGetProp(n, "merge");
+ xmlChar *type = xmlGetProp(n, "type");
+ xmlChar *termlist = xmlGetProp(n, "termlist");
+
if (!name)
{
- yaz_log(YLOG_WARN, "Missing name attribute in termlist");
- continue;
+ yaz_log(YLOG_FATAL, "Must specify name in metadata element");
+ return 0;
+ }
+ md->name = nmem_strdup(nmem, name);
+ if (brief)
+ {
+ if (!strcmp(brief, "yes"))
+ md->brief = 1;
+ else if (strcmp(brief, "no"))
+ {
+ yaz_log(YLOG_FATAL, "metadata/brief must be yes or no");
+ return 0;
+ }
+ }
+ else
+ md->brief = 0;
+
+ if (termlist)
+ {
+ if (!strcmp(termlist, "yes"))
+ md->termlist = 1;
+ else if (strcmp(termlist, "no"))
+ {
+ yaz_log(YLOG_FATAL, "metadata/termlist must be yes or no");
+ return 0;
+ }
+ }
+ else
+ md->termlist = 0;
+
+ if (type)
+ {
+ if (!strcmp(type, "generic"))
+ md->type = Metadata_type_generic;
+ else if (!strcmp(type, "integer"))
+ md->type = Metadata_type_integer;
+ else if (!strcmp(type, "year"))
+ md->type = Metadata_type_year;
+ else
+ {
+ yaz_log(YLOG_FATAL, "Unknown value for metadata/type: %s", type);
+ return 0;
+ }
+ }
+ md->type = Metadata_type_generic;
+
+ if (sortkey)
+ {
+ if (!strcmp(sortkey, "no"))
+ md->sortkey = Metadata_sortkey_no;
+ else if (!strcmp(sortkey, "numeric"))
+ md->sortkey = Metadata_sortkey_numeric;
+ else if (!strcmp(sortkey, "range"))
+ md->sortkey = Metadata_sortkey_range;
+ else if (!strcmp(sortkey, "skiparticle"))
+ md->sortkey = Metadata_sortkey_skiparticle;
+ else
+ {
+ yaz_log(YLOG_FATAL, "Unknown sortkey in metadata element: %s", sortkey);
+ return 0;
+ }
}
- tl->name = nmem_strdup(nmem, name);
- tl->next = r->termlists;
- r->termlists = tl;
+ else
+ md->sortkey = Metadata_sortkey_no;
+
+ if (merge)
+ {
+ if (!strcmp(merge, "no"))
+ md->merge = Metadata_merge_no;
+ else if (!strcmp(merge, "unique"))
+ md->merge = Metadata_merge_unique;
+ else if (!strcmp(merge, "longest"))
+ md->merge = Metadata_merge_longest;
+ else if (!strcmp(merge, "range"))
+ md->merge = Metadata_merge_range;
+ else if (!strcmp(merge, "all"))
+ md->merge = Metadata_merge_all;
+ else
+ {
+ yaz_log(YLOG_FATAL, "Unknown value for metadata/merge: %s", merge);
+ return 0;
+ }
+ }
+ else
+ md->merge = Metadata_merge_no;
+
+ xmlFree(name);
+ xmlFree(brief);
+ xmlFree(sortkey);
+ xmlFree(merge);
+ xmlFree(termlist);
+ md_node++;
}
else
{
r->port = atoi(port);
if (host)
r->host = nmem_strdup(nmem, host);
+ xmlFree(port);
+ xmlFree(host);
}
else if (!strcmp(n->name, "proxy"))
{
r->proxy_port = atoi(port);
if (host)
r->proxy_host = nmem_strdup(nmem, host);
+ xmlFree(port);
+ xmlFree(host);
}
else if (!strcmp(n->name, "service"))
{
return 0;
}
}
+ xmlFree(name);
+ xmlFree(format);
+ xmlFree(encoding);
+ xmlFree(mapto);
}
else if (!strcmp(n->name, "map"))
{
}
*rm = m;
rm = &m->next;
+ xmlFree(type);
+ xmlFree(charset);
+ xmlFree(format);
+ xmlFree(stylesheet);
}
else
{
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>
-struct conf_termlist
-{
- char *name;
- struct conf_termlist *next;
-};
-
// Describes known metadata elements and how they are to be manipulated
struct conf_metadata
{
char *name; // The name of this element. Output by normalization stylesheet
int brief; // Is this element to be returned in the brief format?
+ int termlist;// Is this field to be treated as a termlist for browsing?
enum
{
Metadata_type_generic, // Generic text field
Metadata_merge_no, // Don't merge
Metadata_merge_unique, // Include unique elements in merged block
Metadata_merge_longest, // Include the longest (strlen) value
- Metadata_merge_range // Store value as a range of lowest-highest
+ Metadata_merge_range, // Store value as a range of lowest-highest
+ Metadata_merge_all // Just include all elements found
} merge;
};
struct conf_service
{
- struct conf_termlist *termlists;
+ int num_metadata;
struct conf_metadata *metadata;
};
/*
- * $Id: http_command.c,v 1.9 2007-01-08 12:43:41 adam Exp $
+ * $Id: http_command.c,v 1.10 2007-01-08 18:32:35 quinn Exp $
*/
#include <stdio.h>
struct http_request *rq = c->request;
struct http_response *rs = c->response;
struct http_session *s = locate_session(rq, rs);
- struct record **rl;
+ struct record_cluster **rl;
NMEM nmem_show;
char *start = http_argbyname(rq, "start");
char *num = http_argbyname(rq, "num");
{
int ccount;
struct record *p;
+ struct record_cluster *rec = rl[i];
+ struct conf_service *service = global_parameters.server->service;
+ int imeta;
wrbuf_puts(c->wrbuf, "<hit>\n");
- wrbuf_printf(c->wrbuf, "<title>%s</title>\n", rl[i]->title);
- for (ccount = 1, p = rl[i]->next_cluster; p; p = p->next_cluster, ccount++)
+ for (imeta = 0; imeta < service->num_metadata; imeta++)
+ {
+ struct conf_metadata *cmd = &service->metadata[imeta];
+ struct record_metadata *md;
+ if (!rec->metadata[imeta])
+ continue;
+ if (!cmd->brief)
+ continue;
+ for (md = rec->metadata[imeta]; md; md = md->next)
+ {
+ wrbuf_printf(c->wrbuf, "<md-%s>", cmd->name);
+ switch (cmd->type)
+ {
+ case Metadata_type_generic:
+ wrbuf_puts(c->wrbuf, md->data.text);
+ break;
+ default:
+ wrbuf_puts(c->wrbuf, "[Can't represent]");
+ }
+ wrbuf_printf(c->wrbuf, "</md-%s>", cmd->name);
+ }
+ }
+ for (ccount = 0, p = rl[i]->records; p; p = p->next, ccount++)
;
if (ccount > 1)
wrbuf_printf(c->wrbuf, "<count>%d</count>\n", ccount);
-/* $Id: pazpar2.c,v 1.18 2007-01-08 12:43:41 adam Exp $ */;
+/* $Id: pazpar2.c,v 1.19 2007-01-08 18:32:35 quinn Exp $ */;
#include <stdlib.h>
#include <stdio.h>
"Client_Stopped"
};
+// Note: Some things in this structure will eventually move to configuration
struct parameters global_parameters =
{
0,
+ 0,
30,
"81",
"Index Data PazPar2 (MasterKey)",
termlist_insert(s->termlists[i].termlist, value);
}
+int yaz_marc_write_xml();
+
static xmlDoc *normalize_record(struct client *cl, Z_External *rec)
{
struct conf_retrievalprofile *rprofile = cl->database->rprofile;
{
xmlDoc *xdoc = normalize_record(cl, rec);
xmlNode *root, *n;
- struct record *res, *head;
+ struct record *res;
+ struct record_cluster *cluster;
struct session *se = cl->session;
xmlChar *mergekey, *mergekey_norm;
+ xmlChar *type;
+ xmlChar *value;
+ struct conf_service *service = global_parameters.server->service;
if (!xdoc)
return 0;
}
res = nmem_malloc(se->nmem, sizeof(struct record));
- res->next_cluster = 0;
+ res->next = 0;
res->target_offset = -1;
res->term_frequency_vec = 0;
- res->title = "Unknown";
+ 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;
mergekey_norm = nmem_strdup(se->nmem, (char*) mergekey);
xmlFree(mergekey);
- res->merge_key = normalize_mergekey(mergekey_norm);
+ normalize_mergekey(mergekey_norm);
- head = reclist_insert(se->reclist, res);
- if (!head)
+ cluster = reclist_insert(se->reclist, res, mergekey_norm);
+ if (!cluster)
{
/* no room for record */
xmlFreeDoc(xdoc);
return 0;
}
- relevance_newrec(se->relevance, head);
+ relevance_newrec(se->relevance, cluster);
+ type = value = 0;
for (n = root->children; n; n = n->next)
{
+ if (type)
+ xmlFree(type);
+ if (value)
+ xmlFree(value);
+ type = value = 0;
+
if (n->type != XML_ELEMENT_NODE)
continue;
- if (!strcmp(n->name, "facet"))
+ if (!strcmp(n->name, "metadata"))
{
- xmlChar *type = xmlGetProp(n, "type");
- xmlChar *value = xmlNodeListGetString(xdoc, n->children, 0);
- if (type && value)
+ type = xmlGetProp(n, "type");
+ value = xmlNodeListGetString(xdoc, n->children, 0);
+ struct conf_metadata *md = 0;
+ struct record_metadata **wheretoput, *newm;
+ int imeta;
+
+ // First, find out what field we're looking at
+ for (imeta = 0; imeta < service->num_metadata; imeta++)
+ if (!strcmp(type, service->metadata[imeta].name))
+ {
+ md = &service->metadata[imeta];
+ break;
+ }
+ if (!md)
{
- add_facet(se, type, value);
- relevance_countwords(se->relevance, head, value, 1);
+ yaz_log(YLOG_WARN, "Ignoring unknown metadata element: %s", type);
+ continue;
}
- xmlFree(type);
- xmlFree(value);
- }
- else if (!strcmp(n->name, "metadata"))
- {
- xmlChar *type = xmlGetProp(n, "type");
- if (type && !strcmp(type, "title"))
+
+ // Find out where we are putting it
+ if (md->merge == Metadata_merge_no)
+ wheretoput = &res->metadata[imeta];
+ else
+ wheretoput = &cluster->metadata[imeta];
+
+ // Put it there
+ newm = nmem_malloc(se->nmem, sizeof(struct record_metadata));
+ newm->next = 0;
+ if (md->type == Metadata_type_generic)
+ {
+ newm->data.text = nmem_strdup(se->nmem, value);
+ }
+ else
{
- xmlChar *value = xmlNodeListGetString(xdoc, n->children, 0);
- if (value)
+ yaz_log(YLOG_WARN, "Unknown type in metadata element %s", type);
+ continue;
+ }
+ if (md->merge == Metadata_merge_unique)
+ {
+ struct record_metadata *mnode;
+ for (mnode = *wheretoput; mnode; mnode = mnode->next)
+ if (!strcmp(mnode->data.text, mnode->data.text))
+ break;
+ if (!mnode)
{
- res->title = nmem_strdup(se->nmem, value);
- relevance_countwords(se->relevance, head, value, 4);
- xmlFree(value);
+ newm->next = *wheretoput;
+ *wheretoput = newm;
}
}
+ else if (md->merge == Metadata_merge_longest)
+ {
+ if (!*wheretoput ||
+ strlen(newm->data.text) > strlen((*wheretoput)->data.text))
+ *wheretoput = newm;
+ }
+ else if (md->merge == Metadata_merge_all || md->merge == Metadata_merge_no)
+ {
+ newm->next = *wheretoput;
+ *wheretoput = newm;
+ }
+ 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->termlist)
+ add_facet(se, type, value);
xmlFree(type);
+ xmlFree(value);
+ type = value = 0;
}
else
yaz_log(YLOG_WARN, "Unexpected element %s in internal record", n->name);
xmlFreeDoc(xdoc);
- relevance_donerecord(se->relevance, head);
+ relevance_donerecord(se->relevance, cluster);
se->total_records++;
return res;
}
#endif
-struct record **show(struct session *s, int start, int *num, int *total,
+struct record_cluster **show(struct session *s, int start, int *num, int *total,
int *sumhits, NMEM nmem_show)
{
- struct record **recs = nmem_malloc(nmem_show, *num
- * sizeof(struct record *));
+ struct record_cluster **recs = nmem_malloc(nmem_show, *num
+ * sizeof(struct record_cluster *));
int i;
#if USE_TIMING
yaz_timing_t t = yaz_timing_create();
for (i = 0; i < *num; i++)
{
- struct record *r = reclist_read_record(s->reclist);
+ struct record_cluster *r = reclist_read_record(s->reclist);
if (!r)
{
*num = i;
}
}
+ if (!config)
+ {
+ yaz_log(YLOG_FATAL, "Load config with -f");
+ exit(1);
+ }
+ global_parameters.server = config->servers;
+
if (!setport)
{
fprintf(stderr, "Set command port with -h\n");
struct client;
-struct record_metadata
-{
- union
- {
+struct record_metadata {
+ union {
char *text;
struct {
- int first;
- int last;
- } year_range;
- int year;
- } interpretation;
+ int year1;
+ int year2;
+ } year;
+ } data;
+ struct record_metadata *next; // next item of this name
};
struct record {
struct client *client;
- char *title;
int target_offset;
+ struct record_metadata **metadata; // Array mirrors list of metadata fields in config
+ int relevance;
+ int *term_frequency_vec;
+ struct record *next;
+};
+
+struct record_cluster
+{
+ struct record_metadata **metadata; // Array mirrors list of metadata fields in config
char *merge_key;
- struct record_metadata *md;
int relevance;
int *term_frequency_vec;
- struct record *next_cluster;
+ struct record *records;
};
struct connection;
};
struct parameters {
+ struct conf_server *server;
int dump_records;
int timeout; /* operations timeout, in seconds */
char implementationId[128];
int load_targets(struct session *s, const char *fn);
void statistics(struct session *s, struct statistics *stat);
char *search(struct session *s, char *query);
-struct record **show(struct session *s, int start, int *num, int *total,
+struct record_cluster **show(struct session *s, int start, int *num, int *total,
int *sumhits, NMEM nmem_show);
struct termlist_score **termlist(struct session *s, const char *name, int *num);
void session_set_watch(struct session *s, int what, session_watchfun fun, void *data);
/*
- * $Id: reclists.c,v 1.3 2007-01-08 12:43:41 adam Exp $
+ * $Id: reclists.c,v 1.4 2007-01-08 18:32:35 quinn Exp $
*/
#include <assert.h>
#include "pazpar2.h"
#include "reclists.h"
+extern struct parameters global_parameters;
+
struct reclist_bucket
{
- struct record *record;
+ struct record_cluster *record;
struct reclist_bucket *next;
};
-struct record *reclist_read_record(struct reclist *l)
+struct record_cluster *reclist_read_record(struct reclist *l)
{
if (l->pointer < l->num_records)
return l->flatlist[l->pointer++];
res->hashmask = hashsize - 1; // Creates a bitmask
res->num_records = 0;
- res->flatlist = nmem_malloc(nmem, numrecs * sizeof(struct record*));
+ res->flatlist = nmem_malloc(nmem, numrecs * sizeof(struct record_cluster*));
res->flatlist_size = numrecs;
return res;
}
-struct record *reclist_insert(struct reclist *l, struct record *record)
+// Insert a record. Return record cluster (newly formed or pre-existing)
+struct record_cluster *reclist_insert(struct reclist *l, struct record *record,
+ char *merge_key)
{
unsigned int bucket;
struct reclist_bucket **p;
- struct record *head = 0;
+ struct record_cluster *cluster = 0;
+ struct conf_service *service = global_parameters.server->service;
- bucket = hash((unsigned char*) record->merge_key) & l->hashmask;
+ bucket = hash((unsigned char*) merge_key) & l->hashmask;
for (p = &l->hashtable[bucket]; *p; p = &(*p)->next)
{
// We found a matching record. Merge them
- if (!strcmp(record->merge_key, (*p)->record->merge_key))
+ if (!strcmp(merge_key, (*p)->record->merge_key))
{
- struct record *existing = (*p)->record;
- record->next_cluster = existing->next_cluster;
- existing->next_cluster = record;
- head = existing;
+ struct record_cluster *existing = (*p)->record;
+ record->next = existing->records;
+ existing->records = record;
+ cluster = existing;
break;
}
}
- if (!head && l->num_records < l->flatlist_size)
+ if (!cluster && l->num_records < l->flatlist_size)
{
struct reclist_bucket *new =
nmem_malloc(l->nmem, sizeof(struct reclist_bucket));
+ struct record_cluster *newc =
+ nmem_malloc(l->nmem, sizeof(struct record_cluster));
- assert(!*p);
-
- new->record = record;
- record->next_cluster = 0;
+ record->next = 0;
+ new->record = newc;
new->next = 0;
+ newc->records = record;
+ newc->merge_key = merge_key;
+ newc->relevance = 0;
+ newc->term_frequency_vec = 0;
+ newc->metadata = 0;
+ newc->metadata = nmem_malloc(l->nmem,
+ sizeof(struct record_metadata*) * service->num_metadata);
+ bzero(newc->metadata, sizeof(struct record_metadata*) * service->num_metadata);
+
*p = new;
- assert(l->num_records < l->flatlist_size);
- l->flatlist[l->num_records++] = record;
- head = record;
+ l->flatlist[l->num_records++] = newc;
+ cluster = newc;
}
- return head;
+ return cluster;
}
int hashtable_size;
int hashmask;
- struct record **flatlist;
+ struct record_cluster **flatlist;
int flatlist_size;
int num_records;
int pointer;
};
struct reclist *reclist_create(NMEM, int numrecs);
-struct record * reclist_insert(struct reclist *tl, struct record *record);
-struct record *reclist_read_record(struct reclist *l);
+struct record_cluster *reclist_insert(struct reclist *tl, struct record *record,
+ char *merg_key);
+struct record_cluster *reclist_read_record(struct reclist *l);
void reclist_rewind(struct reclist *l);
#endif
/*
- * $Id: relevance.c,v 1.4 2007-01-08 12:43:41 adam Exp $
+ * $Id: relevance.c,v 1.5 2007-01-08 18:32:35 quinn Exp $
*/
#include <ctype.h>
return res;
}
-void relevance_newrec(struct relevance *r, struct record *rec)
+void relevance_newrec(struct relevance *r, struct record_cluster *rec)
{
if (!rec->term_frequency_vec)
{
// FIXME. The definition of a word is crude here.. should support
// some form of localization mechanism?
-void relevance_countwords(struct relevance *r, struct record *head,
+void relevance_countwords(struct relevance *r, struct record_cluster *cluster,
const char *words, int multiplier)
{
while (*words)
if ((res = word_trie_match(r->wt, words, &skipped)))
{
words += skipped;
- head->term_frequency_vec[res] += multiplier;
+ cluster->term_frequency_vec[res] += multiplier;
}
else
{
while (*words && (c = raw_char(tolower(*words))) >= 0)
words++;
}
- head->term_frequency_vec[0]++;
+ cluster->term_frequency_vec[0]++;
}
}
-void relevance_donerecord(struct relevance *r, struct record *head)
+void relevance_donerecord(struct relevance *r, struct record_cluster *cluster)
{
int i;
for (i = 1; i < r->vec_len; i++)
- if (head->term_frequency_vec[i] > 0)
+ if (cluster->term_frequency_vec[i] > 0)
r->doc_frequency_vec[i]++;
r->doc_frequency_vec[0]++;
for (i = 0; i < reclist->num_records; i++)
{
int t;
- struct record *rec = reclist->flatlist[i];
+ struct record_cluster *rec = reclist->flatlist[i];
float relevance;
relevance = 0;
for (t = 1; t < rel->vec_len; t++)
struct relevance;
struct relevance *relevance_create(NMEM nmem, const char **terms, int numrecs);
-void relevance_newrec(struct relevance *r, struct record *rec);
-void relevance_countwords(struct relevance *r, struct record *rec,
+void relevance_newrec(struct relevance *r, struct record_cluster *cluster);
+void relevance_countwords(struct relevance *r, struct record_cluster *cluster,
const char *words, int multiplier);
-void relevance_donerecord(struct relevance *r, struct record *rec);
+void relevance_donerecord(struct relevance *r, struct record_cluster *cluster);
void relevance_prepare_read(struct relevance *rel, struct reclist *rec);
/*
- * $Id: termlists.c,v 1.2 2007-01-08 12:43:41 adam Exp $
+ * $Id: termlists.c,v 1.3 2007-01-08 18:32:35 quinn Exp $
*/
#include <stdlib.h>
int smallest;
int me = -1;
- if (t->frequency < tl->highscore_min)
+ if (tl->highscore_num > tl->highscore_size && t->frequency < tl->highscore_min)
return;
smallest = 0;
}
if (tl->highscore_num)
tl->highscore_min = tl->highscore[smallest]->frequency;
+ if (t->frequency < tl->highscore_min)
+ tl->highscore_min = t->frequency;
if (me >= 0)
return;
if (tl->highscore_num < tl->highscore_size)
-/* $Id: search.js,v 1.8 2007-01-05 02:12:51 quinn Exp $
+/* $Id: search.js,v 1.9 2007-01-08 18:32:35 quinn Exp $
* ---------------------------------------------------
* Javascript container
*/
{
body.innerHTML += '<p>';
body.innerHTML += (i + start + 1) + ': ';
- var mk = hits[i].getElementsByTagName("title");
+ var mk = hits[i].getElementsByTagName("md-title");
if (mk[0])
body.innerHTML += mk[0].childNodes[0].nodeValue;
body.innerHTML += '</p>';