X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fzoom-record-cache.c;h=9e76d66b78d0ef14817ec4d96d63f5a49310698e;hp=e90ef028b7bd06bfbe82bdcf89a009ed8b7860e4;hb=503c86c1e635da2561cc4e16449257952f90ac4d;hpb=74682526ffcdc625f5d8e7adec296b0d6d23a8b5 diff --git a/src/zoom-record-cache.c b/src/zoom-record-cache.c index e90ef02..9e76d66 100644 --- a/src/zoom-record-cache.c +++ b/src/zoom-record-cache.c @@ -1,11 +1,14 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2010 Index Data + * Copyright (C) Index Data * See the file LICENSE for details. */ /** * \file zoom-record-cache.c * \brief Implements ZOOM record caching */ +#if HAVE_CONFIG_H +#include +#endif #include #include @@ -13,6 +16,7 @@ #include "zoom-p.h" #include +#include #include #if SHPTR @@ -45,16 +49,6 @@ struct ZOOM_record_cache_p { ZOOM_record_cache next; }; - -static int strcmp_null(const char *v1, const char *v2) -{ - if (!v1 && !v2) - return 0; - if (!v1 || !v2) - return -1; - return strcmp(v1, v2); -} - static size_t record_hash(int pos) { if (pos < 0) @@ -62,23 +56,25 @@ static size_t record_hash(int pos) return pos % RECORD_HASH_SIZE; } -void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr, - int pos, - const char *syntax, const char *elementSetName, - const char *schema, - Z_SRW_diagnostic *diag) +static ZOOM_record record_cache_add(ZOOM_resultset r, + Z_NamePlusRecord *npr, + int pos, + const char *syntax, + const char *elementSetName, + const char *schema, + Z_SRW_diagnostic *diag) { ZOOM_record_cache rc = 0; - + ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_RECV_RECORD); ZOOM_connection_put_event(r->connection, event); for (rc = r->record_hash[record_hash(pos)]; rc; rc = rc->next) { - if (pos == rc->pos - && strcmp_null(r->schema, rc->schema) == 0 - && strcmp_null(elementSetName,rc->elementSetName) == 0 - && strcmp_null(syntax, rc->syntax) == 0) + if (pos == rc->pos + && yaz_strcmp_null(schema, rc->schema) == 0 + && yaz_strcmp_null(elementSetName,rc->elementSetName) == 0 + && yaz_strcmp_null(syntax, rc->syntax) == 0) break; } if (!rc) @@ -92,15 +88,17 @@ void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr, rc->rec.wrbuf = 0; #endif rc->elementSetName = odr_strdup_null(r->odr, elementSetName); - + rc->syntax = odr_strdup_null(r->odr, syntax); - - rc->schema = odr_strdup_null(r->odr, r->schema); + + rc->schema = odr_strdup_null(r->odr, schema); rc->pos = pos; rc->next = r->record_hash[record_hash(pos)]; r->record_hash[record_hash(pos)] = rc; + } + rc->rec.npr = npr; rc->rec.schema = odr_strdup_null(r->odr, schema); rc->rec.diag_set = 0; @@ -117,30 +115,112 @@ void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr, *cp = '\0'; rc->rec.diag_uri = odr_strdup(r->odr, diag->uri); } - rc->rec.diag_message = odr_strdup_null(r->odr, diag->message); + rc->rec.diag_message = odr_strdup_null(r->odr, diag->message); rc->rec.diag_details = odr_strdup_null(r->odr, diag->details); } + return &rc->rec; } +void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr, + int pos, + const char *syntax, const char *elementSetName, + const char *schema, + Z_SRW_diagnostic *diag) +{ + record_cache_add(r, npr, pos, syntax, elementSetName, schema, diag); +#if HAVE_LIBMEMCACHED_MEMCACHED_H + if (r->connection->mc_st && + !diag && npr->which == Z_NamePlusRecord_databaseRecord) + { + WRBUF k = wrbuf_alloc(); + uint32_t flags = 0; + memcached_return_t rc; + time_t expiration = 36000; + ODR odr = odr_createmem(ODR_ENCODE); + char *rec_buf; + int rec_len; + + z_NamePlusRecord(odr, &npr, 0, 0); + rec_buf = odr_getbuf(odr, &rec_len, 0); + + wrbuf_write(k, wrbuf_buf(r->mc_key), wrbuf_len(r->mc_key)); + wrbuf_printf(k, ";%d;%s;%s;%s", pos, + syntax ? syntax : "", + elementSetName ? elementSetName : "", + schema ? schema : ""); + rc = memcached_set(r->connection->mc_st, + wrbuf_buf(k),wrbuf_len(k), + rec_buf, rec_len, + expiration, flags); + + yaz_log(YLOG_LOG, "Store record lkey=%s len=%d rc=%u %s", + wrbuf_cstr(k), rec_len, (unsigned) rc, + memcached_last_error_message(r->connection->mc_st)); + odr_destroy(odr); + wrbuf_destroy(k); + } +#endif +} + + ZOOM_record ZOOM_record_cache_lookup(ZOOM_resultset r, int pos, const char *syntax, - const char *elementSetName) + const char *elementSetName, + const char *schema) { ZOOM_record_cache rc; - + for (rc = r->record_hash[record_hash(pos)]; rc; rc = rc->next) { if (pos == rc->pos) { - if (strcmp_null(r->schema, rc->schema)) + if (yaz_strcmp_null(schema, rc->schema)) continue; - if (strcmp_null(elementSetName,rc->elementSetName)) + if (yaz_strcmp_null(elementSetName,rc->elementSetName)) continue; - if (strcmp_null(syntax, rc->syntax)) + if (yaz_strcmp_null(syntax, rc->syntax)) continue; return &rc->rec; } } +#if HAVE_LIBMEMCACHED_MEMCACHED_H + if (r->connection && r->connection->mc_st) + { + WRBUF k = wrbuf_alloc(); + size_t v_len; + char *v_buf; + uint32_t flags; + memcached_return_t rc; + + wrbuf_write(k, wrbuf_buf(r->mc_key), wrbuf_len(r->mc_key)); + wrbuf_printf(k, ";%d;%s;%s;%s", pos, + syntax ? syntax : "", + elementSetName ? elementSetName : "", + schema ? schema : ""); + + yaz_log(YLOG_LOG, "Lookup record %s", wrbuf_cstr(k)); + v_buf = memcached_get(r->connection->mc_st, wrbuf_buf(k), wrbuf_len(k), + &v_len, &flags, &rc); + wrbuf_destroy(k); + if (v_buf) + { + Z_NamePlusRecord *npr = 0; + + odr_setbuf(r->odr, v_buf, v_len, 0); + + z_NamePlusRecord(r->odr, &npr, 0, 0); + free(v_buf); + if (npr) + { + yaz_log(YLOG_LOG, "returned memcached copy"); + return record_cache_add(r, npr, pos, syntax, elementSetName, + schema, 0); + } + yaz_log(YLOG_WARN, "memcached_get npr failed v_len=%ld", + (long) v_len); + } + } +#endif return 0; } @@ -156,7 +236,7 @@ ZOOM_API(ZOOM_record) if (!z_NamePlusRecord(odr_enc, &srec->npr, 0, 0)) return 0; buf = odr_getbuf(odr_enc, &size, 0); - + nrec = (ZOOM_record) xmalloc(sizeof(*nrec)); nrec->odr = odr_createmem(ODR_DECODE); #if SHPTR @@ -166,7 +246,7 @@ ZOOM_API(ZOOM_record) #endif odr_setbuf(nrec->odr, buf, size, 0); z_NamePlusRecord(nrec->odr, &nrec->npr, 0, 0); - + nrec->schema = odr_strdup_null(nrec->odr, srec->schema); nrec->diag_uri = odr_strdup_null(nrec->odr, srec->diag_uri); nrec->diag_message = odr_strdup_null(nrec->odr, srec->diag_message); @@ -213,10 +293,10 @@ ZOOM_API(const char *) ZOOM_record_get(ZOOM_record rec, const char *type_spec, int *len) { WRBUF wrbuf; - + if (len) *len = 0; /* default return */ - + if (!rec || !rec->npr) return 0; @@ -232,7 +312,7 @@ ZOOM_API(const char *) rec->wrbuf = wrbuf_alloc(); wrbuf = rec->wrbuf; #endif - return ZOOM_npr_format(rec->npr, rec->schema, wrbuf, type_spec, len); + return yaz_record_render(rec->npr, rec->schema, wrbuf, type_spec, len); } ZOOM_API(int) @@ -240,7 +320,7 @@ ZOOM_API(int) const char **addinfo, const char **diagset) { Z_NamePlusRecord *npr; - + if (!rec) return 0; @@ -265,7 +345,7 @@ ZOOM_API(int) { Z_DefaultDiagFormat *ddf = diag_rec->u.defaultFormat; oid_class oclass; - + error = *ddf->condition; switch (ddf->which) {