/* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2010 Index Data
+ * Copyright (C) Index Data
* See the file LICENSE for details.
*/
/**
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)
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)
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;
*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 &&
+ npr->u.databaseRecord->which == Z_External_octet)
+ {
+ WRBUF k = wrbuf_alloc();
+ uint32_t flags = 0;
+ memcached_return_t rc;
+ time_t expiration = 36000;
+
+ 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),
+ npr->u.databaseRecord->u.octet_aligned->buf,
+ npr->u.databaseRecord->u.octet_aligned->len,
+ expiration, flags);
+
+ yaz_log(YLOG_LOG, "Store record key=%s rc=%u %s",
+ wrbuf_cstr(k), (unsigned) rc,
+ memcached_last_error_message(r->connection->mc_st));
+ 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;
+ 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 : "");
+
+ v = memcached_get(r->connection->mc_st, wrbuf_buf(k), wrbuf_len(k),
+ &v_len, &flags, &rc);
+ wrbuf_destroy(k);
+ if (v)
+ {
+ yaz_log(YLOG_LOG, "Building record from memcached!! syntax=%s",
+ syntax);
+ Z_NamePlusRecord *npr = (Z_NamePlusRecord *)
+ odr_malloc(r->odr, sizeof(Z_NamePlusRecord));
+ npr->databaseName = 0;
+ npr->which = Z_NamePlusRecord_databaseRecord;
+ npr->u.databaseRecord = (Z_External *)
+ odr_malloc(r->odr, sizeof(Z_External));
+ npr->u.databaseRecord->descriptor = 0;
+ npr->u.databaseRecord->direct_reference =
+ syntax ?
+ yaz_string_to_oid_odr(yaz_oid_std(), CLASS_RECSYN,
+ syntax, r->odr) : 0;
+ npr->u.databaseRecord->indirect_reference = 0;
+ npr->u.databaseRecord->which = Z_External_octet;
+ npr->u.databaseRecord->u.octet_aligned =
+ odr_create_Odr_oct(r->odr, v, v_len);
+ free(v);
+
+ if (v)
+ return record_cache_add(r, npr, pos, syntax, elementSetName,
+ schema, 0);
+ }
+ }
+#endif
return 0;
}
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
#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);
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;
const char **addinfo, const char **diagset)
{
Z_NamePlusRecord *npr;
-
+
if (!rec)
return 0;
{
Z_DefaultDiagFormat *ddf = diag_rec->u.defaultFormat;
oid_class oclass;
-
+
error = *ddf->condition;
switch (ddf->which)
{