From 5ac0f94cc7fc45e3ae81e8575facb88aa1740a98 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 12 Feb 2010 14:10:50 +0100 Subject: [PATCH] Protect struct reclist --- src/http_command.c | 3 ++- src/logic.c | 10 +++++++--- src/reclists.c | 39 ++++++++++++++++++++++++++++++++------- src/reclists.h | 4 +++- src/record.h | 2 +- src/relevance.c | 6 +++--- 6 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/http_command.c b/src/http_command.c index 913af79..9bada03 100644 --- a/src/http_command.c +++ b/src/http_command.c @@ -848,7 +848,8 @@ static void show_records(struct http_channel *c, int active) if (ccount > 1) wrbuf_printf(c->wrbuf, "%d\n", ccount); if (strstr(sort, "relevance")) - wrbuf_printf(c->wrbuf, "%d\n", rec->relevance); + wrbuf_printf(c->wrbuf, "%d\n", + rec->relevance_score); wrbuf_puts(c->wrbuf, ""); wrbuf_xmlputs(c->wrbuf, rec->recid); wrbuf_puts(c->wrbuf, "\n"); diff --git a/src/logic.c b/src/logic.c index f6f6cbd..9174fa0 100644 --- a/src/logic.c +++ b/src/logic.c @@ -613,6 +613,7 @@ void destroy_session(struct session *s) for (sdb = s->databases; sdb; sdb = sdb->next) session_database_destroy(sdb); normalize_cache_destroy(s->normalize_cache); + reclist_destroy(s->reclist); nmem_destroy(s->nmem); service_destroy(s->service); wrbuf_destroy(s->wrbuf); @@ -708,7 +709,7 @@ struct record_cluster *show_single(struct session *s, const char *id, { struct record_cluster *r; - reclist_rewind(s->reclist); + reclist_enter(s->reclist); *prev_r = 0; *next_r = 0; while ((r = reclist_read_record(s->reclist))) @@ -716,11 +717,12 @@ struct record_cluster *show_single(struct session *s, const char *id, if (!strcmp(r->recid, id)) { *next_r = reclist_read_record(s->reclist); - return r; + break; } *prev_r = r; } - return 0; + reclist_leave(s->reclist); + return r; } struct record_cluster **show(struct session *s, struct reclist_sortparms *sp, @@ -752,6 +754,7 @@ struct record_cluster **show(struct session *s, struct reclist_sortparms *sp, } reclist_sort(s->reclist, sp); + reclist_enter(s->reclist); *total = reclist_get_num_records(s->reclist); *sumhits = s->total_hits; @@ -773,6 +776,7 @@ struct record_cluster **show(struct session *s, struct reclist_sortparms *sp, } recs[i] = r; } + reclist_leave(s->reclist); } #if USE_TIMING yaz_timing_stop(t); diff --git a/src/reclists.c b/src/reclists.c index a4b1ac0..b7a3db2 100644 --- a/src/reclists.c +++ b/src/reclists.c @@ -39,6 +39,7 @@ struct reclist struct reclist_bucket *sorted_ptr; struct reclist_bucket **last; NMEM nmem; + YAZ_MUTEX mutex; }; static struct reclist_sortparms *qsort_sortparms = 0; /* thread pr */ @@ -133,7 +134,7 @@ static int reclist_cmp(const void *p1, const void *p2) switch (s->type) { case Metadata_sortkey_relevance: - res = r2->relevance - r1->relevance; + res = r2->relevance_score - r1->relevance_score; break; case Metadata_sortkey_string: s1 = ut1 ? ut1->text.sort : ""; @@ -172,10 +173,16 @@ static int reclist_cmp(const void *p1, const void *p2) void reclist_sort(struct reclist *l, struct reclist_sortparms *parms) { + struct reclist_bucket **flatlist = xmalloc(sizeof(*flatlist) * l->num_records); - struct reclist_bucket *ptr = l->sorted_list; - struct reclist_bucket **prev = &l->sorted_list; + struct reclist_bucket *ptr; + struct reclist_bucket **prev; int i = 0; + + reclist_enter(l); + + ptr = l->sorted_list; + prev = &l->sorted_list; while (ptr) { flatlist[i] = ptr; @@ -196,7 +203,7 @@ void reclist_sort(struct reclist *l, struct reclist_sortparms *parms) xfree(flatlist); - reclist_rewind(l); + reclist_leave(l); } struct record_cluster *reclist_read_record(struct reclist *l) @@ -211,12 +218,22 @@ struct record_cluster *reclist_read_record(struct reclist *l) return 0; } -void reclist_rewind(struct reclist *l) +void reclist_enter(struct reclist *l) +{ + yaz_mutex_enter(l->mutex); + if (l) + l->sorted_ptr = l->sorted_list; +} + + +void reclist_leave(struct reclist *l) { + yaz_mutex_leave(l->mutex); if (l) l->sorted_ptr = l->sorted_list; } + struct reclist *reclist_create(NMEM nmem) { struct reclist *res = nmem_malloc(nmem, sizeof(struct reclist)); @@ -231,9 +248,16 @@ struct reclist *reclist_create(NMEM nmem) res->last = &res->sorted_list; res->num_records = 0; + res->mutex = 0; + yaz_mutex_create(&res->mutex); return res; } +void reclist_destroy(struct reclist *l) +{ + yaz_mutex_destroy(&l->mutex); +} + int reclist_get_num_records(struct reclist *l) { if (l) @@ -259,6 +283,7 @@ struct record_cluster *reclist_insert( struct reclist *l, bucket = jenkins_hash((unsigned char*) merge_key) % l->hash_size; + yaz_mutex_enter(l->mutex); for (p = &l->hashtable[bucket]; *p; p = &(*p)->hnext) { // We found a matching record. Merge them @@ -283,7 +308,7 @@ struct record_cluster *reclist_insert( struct reclist *l, new->hnext = 0; cluster->records = record; cluster->merge_key = merge_key; - cluster->relevance = 0; + cluster->relevance_score = 0; cluster->term_frequency_vec = 0; cluster->recid = merge_key; (*total)++; @@ -308,10 +333,10 @@ struct record_cluster *reclist_insert( struct reclist *l, l->num_records++; } + yaz_mutex_leave(l->mutex); return cluster; } - /* * Local variables: * c-basic-offset: 4 diff --git a/src/reclists.h b/src/reclists.h index 42aff14..b1dcae6 100644 --- a/src/reclists.h +++ b/src/reclists.h @@ -35,13 +35,15 @@ struct reclist_sortparms }; struct reclist *reclist_create(NMEM); +void reclist_destroy(struct reclist *l); struct record_cluster *reclist_insert( struct reclist *tl, struct conf_service *service, struct record *record, char *merge_key, int *total); void reclist_sort(struct reclist *l, struct reclist_sortparms *parms); struct record_cluster *reclist_read_record(struct reclist *l); -void reclist_rewind(struct reclist *l); +void reclist_enter(struct reclist *l); +void reclist_leave(struct reclist *l); struct reclist_sortparms *reclist_parse_sortparms(NMEM nmem, const char *parms, struct conf_service *service); diff --git a/src/record.h b/src/record.h index 57a4789..2a46c2b 100644 --- a/src/record.h +++ b/src/record.h @@ -112,7 +112,7 @@ struct record_cluster struct record_metadata **metadata; union data_types **sortkeys; char *merge_key; - int relevance; + int relevance_score; int *term_frequency_vec; int *term_frequency_vec_tmp; float *term_frequency_vecf; diff --git a/src/relevance.c b/src/relevance.c index a63abaf..b7d613b 100644 --- a/src/relevance.c +++ b/src/relevance.c @@ -186,7 +186,7 @@ void relevance_prepare_read(struct relevance *rel, struct reclist *reclist) int i; float *idfvec = xmalloc(rel->vec_len * sizeof(float)); - reclist_rewind(reclist); + reclist_enter(reclist); // Calculate document frequency vector for each term. for (i = 1; i < rel->vec_len; i++) { @@ -230,9 +230,9 @@ void relevance_prepare_read(struct relevance *rel, struct reclist *reclist) #endif relevance += 100000 * (termfreq * idfvec[t] + 0.0000005); } - rec->relevance = relevance; + rec->relevance_score = relevance; } - reclist_rewind(reclist); + reclist_leave(reclist); xfree(idfvec); } -- 1.7.10.4