YAZ 5.37.0
zoom-memcached.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
9#if HAVE_CONFIG_H
10#include <config.h>
11#endif
12
13#include <assert.h>
14#include <string.h>
15#include <errno.h>
16#include "zoom-p.h"
17
18#include <yaz/yaz-util.h>
19#include <yaz/xmalloc.h>
20#include <yaz/log.h>
21#include <yaz/diagbib1.h>
22#include <yaz/snprintf.h>
23
25{
26#if HAVE_LIBMEMCACHED
27 c->mc_st = 0;
28#endif
29#if HAVE_HIREDIS
30 c->redis_c = 0;
31#endif
32 c->expire_search = 600;
33 c->expire_record = 1200;
34}
35
37{
38#if HAVE_LIBMEMCACHED
39 if (c->mc_st)
40 memcached_free(c->mc_st);
41#endif
42#if HAVE_HIREDIS
43 if (c->redis_c)
44 redisFree(c->redis_c);
45#endif
46}
47
48#if HAVE_LIBMEMCACHED
49static memcached_st *create_memcached(const char *conf,
50 int *expire_search, int *expire_record)
51{
52 char **darray;
53 int i, num;
54 memcached_st *mc = memcached_create(0);
55 NMEM nmem = nmem_create();
56 memcached_return_t rc;
57
58 nmem_strsplit_blank(nmem, conf, &darray, &num);
59 for (i = 0; mc && i < num; i++)
60 {
61 if (!yaz_strncasecmp(darray[i], "--SERVER=", 9))
62 {
63 char *host = darray[i] + 9;
64 char *port = strchr(host, ':');
65 char *weight = strstr(host, "/?");
66 if (port)
67 *port++ = '\0';
68 if (weight)
69 {
70 *weight = '\0';
71 weight += 2;
72 }
73 rc = memcached_server_add(mc, host, port ? atoi(port) : 11211);
74 yaz_log(YLOG_LOG, "memcached_server_add host=%s rc=%u %s",
75 host, (unsigned) rc, memcached_strerror(mc, rc));
76 if (rc != MEMCACHED_SUCCESS)
77 {
78 memcached_free(mc);
79 mc = 0;
80 }
81 }
82 else if (!yaz_strncasecmp(darray[i], "--EXPIRE=", 9))
83 {
84 *expire_search = atoi(darray[i] + 9);
85 *expire_record = 600 + *expire_search;
86 }
87 else
88 {
89 /* bad directive */
90 memcached_free(mc);
91 mc = 0;
92 }
93 }
94 nmem_destroy(nmem);
95 return mc;
96}
97#endif
98
99#if HAVE_HIREDIS
100static redisContext *create_redis(const char *conf,
101 int *expire_search, int *expire_record)
102{
103 char **darray;
104 int i, num;
105 NMEM nmem = nmem_create();
106 redisContext *context = 0;
107
108 nmem_strsplit_blank(nmem, conf, &darray, &num);
109 for (i = 0; i < num; i++)
110 {
111 if (!yaz_strncasecmp(darray[i], "--SERVER=", 9))
112 {
113 struct timeval timeout = { 1, 500000 }; /* 1.5 seconds */
114 char *host = darray[i] + 9;
115 char *port = strchr(host, ':');
116 if (port)
117 *port++ = '\0';
118 context = redisConnectWithTimeout(host,
119 port ? atoi(port) : 6379,
120 timeout);
121 }
122 else if (!yaz_strncasecmp(darray[i], "--EXPIRE=", 9))
123 {
124 *expire_search = atoi(darray[i] + 9);
125 *expire_record = 600 + *expire_search;
126 }
127 }
128 nmem_destroy(nmem);
129 return context;
130}
131#endif
132
134{
135 const char *val;
136#if HAVE_HIREDIS
137 if (c->redis_c)
138 {
139 redisFree(c->redis_c);
140 c->redis_c = 0;
141 }
142#endif
143#if HAVE_LIBMEMCACHED
144 if (c->mc_st)
145 {
146 memcached_free(c->mc_st);
147 c->mc_st = 0;
148 }
149#endif
150
151 val = ZOOM_options_get(c->options, "redis");
152 if (val && *val)
153 {
154#if HAVE_HIREDIS
155 c->redis_c = create_redis(val,
157 if (c->redis_c == 0 || c->redis_c->err)
158 {
160 "could not create redis");
161 return -1;
162 }
163 return 0; /* don't bother with memcached if redis is enabled */
164#else
165 ZOOM_set_error(c, ZOOM_ERROR_MEMCACHED, "not enabled");
166 return -1;
167#endif
168 }
169 val = ZOOM_options_get(c->options, "memcached");
170 if (val && *val)
171 {
172#if HAVE_LIBMEMCACHED
173 c->mc_st = create_memcached(val, &c->expire_search, &c->expire_record);
174 if (!c->mc_st)
175 {
177 "could not create memcached");
178 return -1;
179 }
180 memcached_behavior_set(c->mc_st, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
181#else
182 ZOOM_set_error(c, ZOOM_ERROR_MEMCACHED, "not enabled");
183 return -1;
184#endif
185 }
186 return 0;
187}
188
189static void wrbuf_vary_puts(WRBUF w, const char *v)
190{
191 if (v)
192 {
193 if (strlen(v) > 40)
194 {
195 wrbuf_sha1_puts(w, v, 1);
196 }
197 else
198 {
199 wrbuf_puts(w, v);
200 }
201 }
202}
203
205{
207
208 r->mc_key = wrbuf_alloc();
209 wrbuf_puts(r->mc_key, "1;");
211 wrbuf_puts(r->mc_key, ";");
213 wrbuf_puts(r->mc_key, ";");
215 wrbuf_puts(r->mc_key, ";");
217 wrbuf_puts(r->mc_key, ";");
218 if (c->password)
220 wrbuf_puts(r->mc_key, ";");
221 {
222 WRBUF w = wrbuf_alloc();
225 wrbuf_destroy(w);
226 }
227 wrbuf_puts(r->mc_key, ";");
229}
230
232{
233#if HAVE_HIREDIS
234 if (c->redis_c && resultset->live_set == 0)
235 {
236 redisReply *reply;
237 const char *argv[2];
238
239 argv[0] = "GET";
240 argv[1] = wrbuf_cstr(resultset->mc_key);
241
242 reply = redisCommandArgv(c->redis_c, 2, argv, 0);
243 /* count;precision (ASCII) + '\0' + BER buffer for otherInformation */
244 if (reply && reply->type == REDIS_REPLY_STRING)
245 {
246 char *v = reply->str;
247 int v_len = reply->len;
248 ZOOM_Event event;
249 size_t lead_len = strlen(v) + 1;
250
251 resultset->size = odr_atoi(v);
252
253 yaz_log(YLOG_LOG, "For key %s got value %s lead_len=%d len=%d",
254 wrbuf_cstr(resultset->mc_key), v, (int) lead_len,
255 (int) v_len);
256 if (v_len > lead_len)
257 {
258 Z_OtherInformation *oi = 0;
259 int oi_len = v_len - lead_len;
260 odr_setbuf(resultset->odr, v + lead_len, oi_len, 0);
261 if (!z_OtherInformation(resultset->odr, &oi, 0, 0))
262 {
263 yaz_log(YLOG_WARN, "oi decoding failed");
264 freeReplyObject(reply);
265 return;
266 }
267 ZOOM_handle_search_result(c, resultset, oi);
268 ZOOM_handle_facet_result(c, resultset, oi);
269 }
272 resultset->live_set = 1;
273 }
274 if (reply)
275 freeReplyObject(reply);
276 }
277#endif
278#if HAVE_LIBMEMCACHED
279 if (c->mc_st && resultset->live_set == 0)
280 {
281 size_t v_len;
282 uint32_t flags;
283 memcached_return_t rc;
284 char *v = memcached_get(c->mc_st, wrbuf_buf(resultset->mc_key),
285 wrbuf_len(resultset->mc_key),
286 &v_len, &flags, &rc);
287 /* count;precision (ASCII) + '\0' + BER buffer for otherInformation */
288 if (v)
289 {
290 ZOOM_Event event;
291 size_t lead_len = strlen(v) + 1;
292
293 resultset->size = odr_atoi(v);
294
295 yaz_log(YLOG_LOG, "For key %s got value %s lead_len=%d len=%d",
296 wrbuf_cstr(resultset->mc_key), v, (int) lead_len,
297 (int) v_len);
298 if (v_len > lead_len)
299 {
300 Z_OtherInformation *oi = 0;
301 int oi_len = v_len - lead_len;
302 odr_setbuf(resultset->odr, v + lead_len, oi_len, 0);
303 if (!z_OtherInformation(resultset->odr, &oi, 0, 0))
304 {
305 yaz_log(YLOG_WARN, "oi decoding failed");
306 free(v);
307 return;
308 }
309 ZOOM_handle_search_result(c, resultset, oi);
310 ZOOM_handle_facet_result(c, resultset, oi);
311 }
312 free(v);
315 resultset->live_set = 1;
316 }
317 }
318#endif
319}
320
321#if HAVE_HIREDIS
322static void expire_redis(redisContext *redis_c,
323 const char *buf, size_t len, int exp)
324{
325 redisReply *reply;
326 const char *argv[3];
327 size_t argvlen[3];
328 char key_val[20];
329
330 yaz_snprintf(key_val, sizeof(key_val), "%d", exp);
331
332 argv[0] = "EXPIRE";
333 argvlen[0] = 6;
334 argv[1] = buf;
335 argvlen[1] = len;
336 argv[2] = key_val;
337 argvlen[2] = strlen(key_val);
338 reply = redisCommandArgv(redis_c, 3, argv, argvlen);
339 freeReplyObject(reply);
340}
341#endif
342
344 Z_OtherInformation *oi, const char *precision)
345{
346#if HAVE_HIREDIS
347 if (c->redis_c && resultset->live_set == 0)
348 {
349 char *str;
351 char *oi_buf = 0;
352 int oi_len = 0;
353 char *key;
354
355 str = odr_malloc(odr, 20 + strlen(precision));
356 /* count;precision (ASCII) + '\0' + BER buffer for otherInformation */
357 yaz_snprintf(str, 20 + strlen(precision), ODR_INT_PRINTF ";%s", resultset->size, precision);
358 if (oi)
359 {
360 z_OtherInformation(odr, &oi, 0, 0);
361 oi_buf = odr_getbuf(odr, &oi_len, 0);
362 }
363 key = odr_malloc(odr, strlen(str) + 1 + oi_len);
364 strcpy(key, str);
365 if (oi_len)
366 memcpy(key + strlen(str) + 1, oi_buf, oi_len);
367
368 {
369 redisReply *reply;
370 const char *argv[3];
371 size_t argvlen[3];
372 argv[0] = "SET";
373 argvlen[0] = 3;
374 argv[1] = wrbuf_buf(resultset->mc_key);
375 argvlen[1] = wrbuf_len(resultset->mc_key);
376 argv[2] = key;
377 argvlen[2] = strlen(str) + 1 + oi_len;
378 reply = redisCommandArgv(c->redis_c, 3, argv, argvlen);
379 freeReplyObject(reply);
380 }
381 expire_redis(c->redis_c,
382 wrbuf_buf(resultset->mc_key),
383 wrbuf_len(resultset->mc_key),
384 c->expire_search);
386 }
387#endif
388#if HAVE_LIBMEMCACHED
389 if (c->mc_st && resultset->live_set == 0)
390 {
391 uint32_t flags = 0;
392 memcached_return_t rc;
393 char *str;
395 char *oi_buf = 0;
396 int oi_len = 0;
397 char *key;
398
399 str = odr_malloc(odr, 20 + strlen(precision));
400 /* count;precision (ASCII) + '\0' + BER buffer for otherInformation */
401 yaz_snprintf(str, 20 + strlen(precision), ODR_INT_PRINTF ";%s", resultset->size, precision);
402 if (oi)
403 {
404 z_OtherInformation(odr, &oi, 0, 0);
405 oi_buf = odr_getbuf(odr, &oi_len, 0);
406 }
407 key = odr_malloc(odr, strlen(str) + 1 + oi_len);
408 strcpy(key, str);
409 if (oi_len)
410 memcpy(key + strlen(str) + 1, oi_buf, oi_len);
411
412 rc = memcached_set(c->mc_st,
413 wrbuf_buf(resultset->mc_key),
414 wrbuf_len(resultset->mc_key),
415 key, strlen(str) + 1 + oi_len,
416 c->expire_search, flags);
417 yaz_log(YLOG_LOG, "Store hit count key=%s value=%s oi_len=%d rc=%u %s",
418 wrbuf_cstr(resultset->mc_key), str, oi_len, (unsigned) rc,
419 memcached_strerror(c->mc_st, rc));
421 }
422#endif
423}
424
426 int pos,
427 const char *syntax, const char *elementSetName,
428 const char *schema,
429 Z_SRW_diagnostic *diag)
430{
431#if HAVE_HIREDIS
432 if (r->connection->redis_c &&
433 !diag && npr->which == Z_NamePlusRecord_databaseRecord)
434 {
435 WRBUF k = wrbuf_alloc();
436 WRBUF rec_sha1 = wrbuf_alloc();
438 char *rec_buf;
439 int rec_len;
440 const char *argv[3];
441 size_t argvlen[3];
442 redisReply *reply;
443
444 z_NamePlusRecord(odr, &npr, 0, 0);
445 rec_buf = odr_getbuf(odr, &rec_len, 0);
446
448 wrbuf_printf(k, ";%d;%s;%s;%s", pos,
449 syntax ? syntax : "",
450 elementSetName ? elementSetName : "",
451 schema ? schema : "");
452
453 wrbuf_sha1_write(rec_sha1, rec_buf, rec_len, 1);
454
455 argv[0] = "SET";
456 argvlen[0] = 3;
457 argv[1] = wrbuf_buf(k);
458 argvlen[1] = wrbuf_len(k);
459 argv[2] = wrbuf_buf(rec_sha1);
460 argvlen[2] = wrbuf_len(rec_sha1);
461
462 reply = redisCommandArgv(r->connection->redis_c, 3, argv, argvlen);
463 yaz_log(YLOG_LOG, "Store record key=%s val=%s",
464 wrbuf_cstr(k), wrbuf_cstr(rec_sha1));
465 freeReplyObject(reply);
466
467 expire_redis(r->connection->redis_c, argv[1], argvlen[1],
469
470 argv[1] = wrbuf_buf(rec_sha1);
471 argvlen[1] = wrbuf_len(rec_sha1);
472 argv[2] = rec_buf;
473 argvlen[2] = rec_len;
474
475 reply = redisCommandArgv(r->connection->redis_c, 3, argv, argvlen);
476 yaz_log(YLOG_LOG, "Add record key=%s rec_len=%d",
477 wrbuf_cstr(rec_sha1), rec_len);
478 freeReplyObject(reply);
479
480 expire_redis(r->connection->redis_c, argv[1], argvlen[1],
482
484 wrbuf_destroy(k);
485 wrbuf_destroy(rec_sha1);
486 }
487#endif
488#if HAVE_LIBMEMCACHED
489 if (r->connection->mc_st &&
490 !diag && npr->which == Z_NamePlusRecord_databaseRecord)
491 {
492 WRBUF k = wrbuf_alloc();
493 WRBUF rec_sha1 = wrbuf_alloc();
494 uint32_t flags = 0;
495 memcached_return_t rc;
497 char *rec_buf;
498 int rec_len;
499
500 z_NamePlusRecord(odr, &npr, 0, 0);
501 rec_buf = odr_getbuf(odr, &rec_len, 0);
502
504 wrbuf_printf(k, ";%d;%s;%s;%s", pos,
505 syntax ? syntax : "",
506 elementSetName ? elementSetName : "",
507 schema ? schema : "");
508
509 wrbuf_sha1_write(rec_sha1, rec_buf, rec_len, 1);
510
511 rc = memcached_set(r->connection->mc_st,
512 wrbuf_buf(k), wrbuf_len(k),
513 wrbuf_buf(rec_sha1), wrbuf_len(rec_sha1),
514 r->connection->expire_search, flags);
515
516 yaz_log(YLOG_LOG, "Store record key=%s val=%s rc=%u %s",
517 wrbuf_cstr(k), wrbuf_cstr(rec_sha1), (unsigned) rc,
518 memcached_strerror(r->connection->mc_st, rc));
519
520 rc = memcached_add(r->connection->mc_st,
521 wrbuf_buf(rec_sha1), wrbuf_len(rec_sha1),
522 rec_buf, rec_len,
523 r->connection->expire_record, flags);
524
525 yaz_log(YLOG_LOG, "Add record key=%s rec_len=%d rc=%u %s",
526 wrbuf_cstr(rec_sha1), rec_len, (unsigned) rc,
527 memcached_strerror(r->connection->mc_st, rc));
528
530 wrbuf_destroy(k);
531 wrbuf_destroy(rec_sha1);
532 }
533#endif
534}
535
537 const char *syntax,
538 const char *elementSetName,
539 const char *schema)
540{
541#if HAVE_HIREDIS
542 if (r->connection && r->connection->redis_c)
543 {
544 WRBUF k = wrbuf_alloc();
545 const char *argv[2];
546 size_t argvlen[2];
547 redisReply *reply1;
548
550 wrbuf_printf(k, ";%d;%s;%s;%s", pos,
551 syntax ? syntax : "",
552 elementSetName ? elementSetName : "",
553 schema ? schema : "");
554
555 yaz_log(YLOG_LOG, "Lookup record %s", wrbuf_cstr(k));
556 argv[0] = "GET";
557 argvlen[0] = 3;
558 argv[1] = wrbuf_buf(k);
559 argvlen[1] = wrbuf_len(k);
560 reply1 = redisCommandArgv(r->connection->redis_c, 2, argv, argvlen);
561
562 wrbuf_destroy(k);
563 if (reply1 && reply1->type == REDIS_REPLY_STRING)
564 {
565 redisReply *reply2;
566 char *sha1_buf = reply1->str;
567 int sha1_len = reply1->len;
568
569 yaz_log(YLOG_LOG, "Lookup record %.*s", (int) sha1_len, sha1_buf);
570
571 argv[0] = "GET";
572 argvlen[0] = 3;
573 argv[1] = sha1_buf;
574 argvlen[1] = sha1_len;
575
576 reply2 = redisCommandArgv(r->connection->redis_c, 2, argv, argvlen);
577 if (reply2 && reply2->type == REDIS_REPLY_STRING)
578 {
579 Z_NamePlusRecord *npr = 0;
580 char *v_buf = reply2->str;
581 int v_len = reply2->len;
582
583 odr_setbuf(r->odr, v_buf, v_len, 0);
584 z_NamePlusRecord(r->odr, &npr, 0, 0);
585 if (npr)
586 yaz_log(YLOG_LOG, "returned redis copy");
587 freeReplyObject(reply2);
588 freeReplyObject(reply1);
589 return npr;
590 }
591 freeReplyObject(reply2);
592 }
593 freeReplyObject(reply1);
594 }
595#endif
596#if HAVE_LIBMEMCACHED
597 if (r->connection && r->connection->mc_st)
598 {
599 WRBUF k = wrbuf_alloc();
600 char *sha1_buf;
601 size_t sha1_len;
602 uint32_t flags;
603 memcached_return_t rc;
604
606 wrbuf_printf(k, ";%d;%s;%s;%s", pos,
607 syntax ? syntax : "",
608 elementSetName ? elementSetName : "",
609 schema ? schema : "");
610
611 yaz_log(YLOG_LOG, "Lookup record %s", wrbuf_cstr(k));
612 sha1_buf = memcached_get(r->connection->mc_st,
613 wrbuf_buf(k), wrbuf_len(k),
614 &sha1_len, &flags, &rc);
615
616 wrbuf_destroy(k);
617 if (sha1_buf)
618 {
619 size_t v_len;
620 char *v_buf;
621
622 yaz_log(YLOG_LOG, "Lookup record %.*s", (int) sha1_len, sha1_buf);
623 v_buf = memcached_get(r->connection->mc_st, sha1_buf, sha1_len,
624 &v_len, &flags, &rc);
625 free(sha1_buf);
626 if (v_buf)
627 {
628 Z_NamePlusRecord *npr = 0;
629
630 odr_setbuf(r->odr, v_buf, v_len, 0);
631 z_NamePlusRecord(r->odr, &npr, 0, 0);
632 free(v_buf);
633 if (npr)
634 yaz_log(YLOG_LOG, "returned memcached copy");
635 return npr;
636 }
637 }
638 }
639#endif
640 return 0;
641
642}
643/*
644 * Local variables:
645 * c-basic-offset: 4
646 * c-file-style: "Stroustrup"
647 * indent-tabs-mode: nil
648 * End:
649 * vim: shiftwidth=4 tabstop=8 expandtab
650 */
651
void free(void *)
Diagnostics: Generated by csvtodiag.tcl from ./bib1.csv.
Header for errno utilities.
void yaz_log(int level, const char *fmt,...)
Writes log message.
Definition log.c:487
Logging utility.
#define YLOG_WARN
log level: warning
Definition log.h:46
#define YLOG_LOG
log level: log (regular)
Definition log.h:48
int yaz_strncasecmp(const char *s1, const char *s2, size_t n)
ala strncasecmp - no locale
Definition matchstr.c:26
NMEM nmem_create(void)
returns new NMEM handle
Definition nmem.c:181
void nmem_destroy(NMEM n)
destroys NMEM handle and memory associated with it
Definition nmem.c:204
struct nmem_control * NMEM
NMEM handle (an opaque pointer to memory).
Definition nmem.h:44
void nmem_strsplit_blank(NMEM nmem, const char *dstr, char ***darray, int *num)
splits string into sub strings delimited by blanks
Definition nmemsdup.c:56
char * odr_getbuf(ODR o, int *len, int *size)
Definition odr.c:275
ODR odr_createmem(int direction)
Definition odr.c:198
void odr_setbuf(ODR o, char *buf, int len, int can_grow)
Definition odr.c:265
void odr_destroy(ODR o)
Definition odr.c:251
#define ODR_INT_PRINTF
Definition odr.h:49
struct odr * ODR
Definition odr.h:121
#define ODR_ENCODE
Definition odr.h:96
void * odr_malloc(ODR o, size_t size)
Definition odr_mem.c:31
Odr_int odr_atoi(const char *s)
Definition odr_mem.c:146
void yaz_snprintf(char *buf, size_t size, const char *fmt,...)
Definition snprintf.c:31
Header for config file reading utilities.
char * password
Definition zoom-p.h:96
ZOOM_options options
Definition zoom-p.h:107
char * host_port
Definition zoom-p.h:68
char * req_facets
Definition zoom-p.h:152
Odr_int size
Definition zoom-p.h:137
ZOOM_connection connection
Definition zoom-p.h:144
Definition odr.h:125
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition wrbuf.c:38
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition wrbuf.c:299
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition wrbuf.c:25
void wrbuf_printf(WRBUF b, const char *fmt,...)
writes printf result to WRBUF
Definition wrbuf.c:189
void wrbuf_puts(WRBUF b, const char *buf)
appends C-string to WRBUF
Definition wrbuf.c:89
void wrbuf_write(WRBUF b, const char *buf, size_t size)
append constant size buffer to WRBUF
Definition wrbuf.c:68
#define wrbuf_buf(b)
Definition wrbuf.h:270
#define wrbuf_len(b)
Definition wrbuf.h:269
struct wrbuf * WRBUF
int wrbuf_sha1_puts(WRBUF b, const char *cp, int hexit)
writes SHA1 text to WRBUF
Definition wrbuf_sha1.c:214
int wrbuf_sha1_write(WRBUF b, const char *cp, size_t sz, int hexit)
writes SHA1 text to WRBUF
Definition wrbuf_sha1.c:194
Header for memory handling functions.
Header for common YAZ utilities.
#define Z_NamePlusRecord_databaseRecord
Definition z-core.h:713
int z_OtherInformation(ODR o, Z_OtherInformation **p, int opt, const char *name)
Definition z-core.c:1545
int z_NamePlusRecord(ODR o, Z_NamePlusRecord **p, int opt, const char *name)
Definition z-core.c:593
void ZOOM_set_error(ZOOM_connection c, int error, const char *addinfo)
Definition zoom-c.c:98
ZOOM_Event ZOOM_Event_create(int kind)
Definition zoom-event.c:42
void ZOOM_connection_put_event(ZOOM_connection c, ZOOM_Event event)
Definition zoom-event.c:73
void ZOOM_memcached_destroy(ZOOM_connection c)
int ZOOM_memcached_configure(ZOOM_connection c)
Z_NamePlusRecord * ZOOM_memcached_lookup(ZOOM_resultset r, int pos, const char *syntax, const char *elementSetName, const char *schema)
void ZOOM_memcached_hitcount(ZOOM_connection c, ZOOM_resultset resultset, Z_OtherInformation *oi, const char *precision)
void ZOOM_memcached_add(ZOOM_resultset r, Z_NamePlusRecord *npr, int pos, const char *syntax, const char *elementSetName, const char *schema, Z_SRW_diagnostic *diag)
static void wrbuf_vary_puts(WRBUF w, const char *v)
void ZOOM_memcached_resultset(ZOOM_resultset r, ZOOM_query q)
void ZOOM_memcached_init(ZOOM_connection c)
void ZOOM_memcached_search(ZOOM_connection c, ZOOM_resultset resultset)
Internal header for ZOOM implementation.
struct ZOOM_Event_p * ZOOM_Event
Definition zoom-p.h:48
void ZOOM_handle_search_result(ZOOM_connection c, ZOOM_resultset resultset, Z_OtherInformation *o)
void ZOOM_handle_facet_result(ZOOM_connection c, ZOOM_resultset r, Z_OtherInformation *o)
void ZOOM_query_get_hash(ZOOM_query s, WRBUF w)
Definition zoom-query.c:145
#define ZOOM_ERROR_MEMCACHED
Definition zoom.h:146
ZOOM_resultset_option_get(ZOOM_resultset r, const char *key)
Definition zoom-c.c:1832
struct ZOOM_query_p * ZOOM_query
Definition zoom.h:51
struct ZOOM_connection_p * ZOOM_connection
Definition zoom.h:52
ZOOM_options_get(ZOOM_options opt, const char *name)
Definition zoom-opt.c:217
#define ZOOM_EVENT_RECV_SEARCH
Definition zoom.h:160
struct ZOOM_resultset_p * ZOOM_resultset
Definition zoom.h:53