Permalink
Browse files

Add support via libcouchbase

Change-Id: I7d8f1c62f3846ed76f4bf2260acd674f5d9fb00a
  • Loading branch information...
1 parent 88ae3b3 commit eaf0f9f11c14166536e389b0c4bdd4c09d24f7c0 @trondn trondn committed with Aug 16, 2011
Showing with 247 additions and 1 deletion.
  1. +1 −1 Makefile.am
  2. +2 −0 configure.ac
  3. +41 −0 m4/pandora_have_libcouchbase.m4
  4. +66 −0 m4/pandora_have_libevent.m4
  5. +137 −0 main.c
View
@@ -10,5 +10,5 @@ memcachetest_SOURCES = \
metrics.c metrics.h \
timer.c \
vbucket.c vbucket.h
-memcachetest_LDADD = $(LIBMEMCACHED) $(LIBVBUCKET)
+memcachetest_LDADD = $(LTLIBMEMCACHED) $(LTLIBVBUCKET) $(LTLIBCOUCHBASE)
View
@@ -12,6 +12,8 @@ AM_CPPFLAGS="$AM_CPPFLAGS $NO_WERROR"
AM_CFLAGS="$AM_CFLAGS $NO_WERROR"
PANDORA_HAVE_LIBMEMCACHED
PANDORA_HAVE_LIBVBUCKET
+PANDORA_HAVE_LIBCOUCHBASE
+PANDORA_HAVE_LIBEVENT
AH_TOP([
#ifndef CONFIG_H
@@ -0,0 +1,41 @@
+dnl Copyright (C) 2011 Couchbase, Inc
+dnl This file is free software; Couchbase, Inc
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([_PANDORA_SEARCH_LIBCOUCHBASE],[
+ AC_REQUIRE([AC_LIB_PREFIX])
+
+ dnl --------------------------------------------------------------------
+ dnl Check for libcouchbase
+ dnl --------------------------------------------------------------------
+
+ AC_ARG_ENABLE([libcouchbase],
+ [AS_HELP_STRING([--disable-libcouchbase],
+ [Build with libcouchbase support @<:@default=on@:>@])],
+ [ac_enable_libcouchbase="$enableval"],
+ [ac_enable_libcouchbase="yes"])
+
+ AS_IF([test "x$ac_enable_libcouchbase" = "xyes"],[
+ AC_LIB_HAVE_LINKFLAGS(couchbase,,[
+ #include <sys/types.h>
+ #include <libcouchbase/couchbase.h>
+ ],[
+ libcouchbase_destroy(NULL);
+ ])
+ ],[
+ ac_cv_libcouchbase="no"
+ ])
+
+ AM_CONDITIONAL(HAVE_LIBCOUCHBASE, [test "x${ac_cv_libcouchbase}" = "xyes"])
+])
+
+AC_DEFUN([PANDORA_HAVE_LIBCOUCHBASE],[
+ AC_REQUIRE([_PANDORA_SEARCH_LIBCOUCHBASE])
+])
+
+AC_DEFUN([PANDORA_REQUIRE_LIBCOUCHBASE],[
+ AC_REQUIRE([PANDORA_HAVE_LIBCOUCHBASE])
+ AS_IF([test x$ac_cv_libcouchbase = xno],
+ AC_MSG_ERROR([libcouchbase is required for ${PACKAGE}]))
+])
@@ -0,0 +1,66 @@
+dnl Copyright (C) 2009 Sun Microsystems, Inc.
+dnl This file is free software; Sun Microsystems, Inc.
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+#--------------------------------------------------------------------
+# Check for libevent
+#--------------------------------------------------------------------
+
+
+AC_DEFUN([_PANDORA_SEARCH_LIBEVENT],[
+ AC_REQUIRE([AC_LIB_PREFIX])
+
+ AC_LIB_HAVE_LINKFLAGS(event,,
+ [
+ #include <sys/types.h>
+ #include <sys/time.h>
+ #include <stdlib.h>
+ #include <event.h>
+ ],[
+ struct bufferevent bev;
+ bufferevent_settimeout(&bev, 1, 1);
+ event_init();
+ event_loop(EVLOOP_ONCE);
+ ])
+
+ AM_CONDITIONAL(HAVE_LIBEVENT, [test "x${ac_cv_libevent}" = "xyes"])
+
+ AS_IF([test "x${ac_cv_libevent}" = "xyes"],[
+ save_LIBS="${LIBS}"
+ LIBS="${LIBS} ${LTLIBEVENT}"
+ AC_CHECK_FUNCS(event_base_new)
+ AC_CHECK_FUNCS(event_base_free)
+ AC_CHECK_FUNCS(event_base_get_method)
+ LIBS="$save_LIBS"
+ ])
+])
+
+AC_DEFUN([_PANDORA_HAVE_LIBEVENT],[
+
+ AC_ARG_ENABLE([libevent],
+ [AS_HELP_STRING([--disable-libevent],
+ [Build with libevent support @<:@default=on@:>@])],
+ [ac_enable_libevent="$enableval"],
+ [ac_enable_libevent="yes"])
+
+ _PANDORA_SEARCH_LIBEVENT
+])
+
+
+AC_DEFUN([PANDORA_HAVE_LIBEVENT],[
+ AC_REQUIRE([_PANDORA_HAVE_LIBEVENT])
+])
+
+AC_DEFUN([_PANDORA_REQUIRE_LIBEVENT],[
+ ac_enable_libevent="yes"
+ _PANDORA_SEARCH_LIBEVENT
+
+ AS_IF([test x$ac_cv_libevent = xno],[
+ AC_MSG_ERROR([libevent is required for ${PACKAGE}. On Debian this can be found in libevent-dev. On RedHat this can be found in libevent-devel.])
+ ])
+])
+
+AC_DEFUN([PANDORA_REQUIRE_LIBEVENT],[
+ AC_REQUIRE([_PANDORA_REQUIRE_LIBEVENT])
+])
View
137 main.c
@@ -46,6 +46,14 @@
#include "libmemcached/memcached.h"
#endif
+#ifdef HAVE_LIBEVENT
+#include <event.h>
+#endif
+
+#ifdef HAVE_LIBCOUCHBASE
+#include <libcouchbase/couchbase.h>
+#endif
+
#include "libmemc.h"
#include "metrics.h"
#include "memcachetest.h"
@@ -129,6 +137,9 @@ enum Libraries {
LIBMEMCACHED_TEXTUAL,
LIBMEMCACHED_BINARY,
#endif
+#ifdef HAVE_LIBCOUCHBASE
+ LIBCOUCHBASE,
+#endif
INVALID_LIBRARY
};
@@ -152,6 +163,47 @@ struct connection {
void *handle;
};
+
+#ifdef HAVE_LIBCOUCHBASE
+struct libcouchbase_callback {
+ libcouchbase_error_t error;
+ size_t size;
+ void *data;
+};
+
+static void storage_callback(libcouchbase_t instance,
+ const void *cookie,
+ libcouchbase_storage_t operation,
+ libcouchbase_error_t error,
+ const void *key, size_t nkey,
+ uint64_t cas)
+{
+ (void)instance; (void)operation; (void)key;
+ (void)nkey; (void)cas;
+ struct libcouchbase_callback *cb;
+ cb = (struct libcouchbase_callback *)cookie;
+ cb->error = error;
+}
+
+static void get_callback(libcouchbase_t instance,
+ const void *cookie,
+ libcouchbase_error_t error,
+ const void *key, size_t nkey,
+ const void *bytes, size_t nbytes,
+ uint32_t flags, uint64_t cas)
+{
+ (void)key; (void)nkey; (void)flags; (void)cas;
+ struct libcouchbase_callback *cb;
+ cb = (struct libcouchbase_callback *)cookie;
+ cb->error = error;
+ if (error == LIBCOUCHBASE_SUCCESS) {
+ cb->data = malloc(nbytes);
+ memcpy(cb->data, bytes, nbytes);
+ cb->size = nbytes;
+ }
+}
+#endif
+
/**
* Create a handle to a memcached library
*/
@@ -187,6 +239,41 @@ static void *create_memcached_handle(void) {
}
break;
#endif
+
+#ifdef HAVE_LIBCOUCHBASE
+ case LIBCOUCHBASE:
+ {
+ struct event_base *evbase = event_base_new();
+ if (evbase == NULL) {
+ fprintf(stderr, "Failed to create event base\n");
+ exit(1);
+ }
+
+ char rest_server[1024];
+ sprintf(rest_server, "%s:%d", hosts->hostname, hosts->port);
+ libcouchbase_t instance = libcouchbase_create(rest_server,
+ NULL, NULL, NULL,
+ evbase);
+ if (instance == NULL) {
+ fprintf(stderr, "Failed to create libcouchbase instance\n");
+ event_base_free(evbase);
+ exit(1);
+ }
+
+ if (libcouchbase_connect(instance) != LIBCOUCHBASE_SUCCESS) {
+ fprintf(stderr, "Failed to connect libcouchbase instance to server\n");
+ event_base_free(evbase);
+ exit(1);
+ }
+
+ (void)libcouchbase_set_storage_callback(instance, storage_callback);
+ (void)libcouchbase_set_get_callback(instance, get_callback);
+
+ ret->handle = instance;
+ }
+ break;
+#endif
+
case LIBMEMC_TEXTUAL:
{
struct Memcache* memcache = libmemc_create(Textual);
@@ -234,6 +321,12 @@ static void release_memcached_handle(void *handle) {
break;
#endif
+#ifdef HAVE_LIBCOUCHBASE
+ case LIBCOUCHBASE:
+ libcouchbase_destroy(lib->handle);
+ break;
+#endif
+
case LIBMEMC_BINARY:
case LIBMEMC_TEXTUAL:
libmemc_destroy(lib->handle);
@@ -242,6 +335,7 @@ static void release_memcached_handle(void *handle) {
default:
abort();
}
+ free(lib);
}
/**
@@ -269,6 +363,24 @@ static inline int memcached_set_wrapper(struct connection *connection,
}
break;
#endif
+
+#ifdef HAVE_LIBCOUCHBASE
+ case LIBCOUCHBASE:
+ {
+ libcouchbase_t instance = lib->handle;
+ libcouchbase_error_t e;
+ struct libcouchbase_callback cb;
+ e = libcouchbase_store(instance, &cb, LIBCOUCHBASE_SET, key,
+ nkey, data, size, 0, 0, 0);
+ assert(e == LIBCOUCHBASE_SUCCESS);
+ libcouchbase_execute(instance);
+ if (cb.error != LIBCOUCHBASE_SUCCESS) {
+ return -1;
+ }
+ }
+ break;
+#endif
+
case LIBMEMC_BINARY:
case LIBMEMC_TEXTUAL:
{
@@ -318,6 +430,31 @@ static inline bool memcached_get_wrapper(struct connection* connection,
}
break;
#endif
+
+#ifdef HAVE_LIBCOUCHBASE
+ case LIBCOUCHBASE:
+ {
+ libcouchbase_t instance = lib->handle;
+ libcouchbase_error_t e;
+ struct libcouchbase_callback cb;
+ char* keys[1];
+ keys[0] = key;
+ size_t nkeys[1];
+ nkeys[0] = nkey;
+
+ e = libcouchbase_mget(instance, &cb, 1,
+ (const void * const *)keys, nkeys, NULL);
+ assert(e == LIBCOUCHBASE_SUCCESS);
+ libcouchbase_execute(instance);
+ if (cb.error != LIBCOUCHBASE_SUCCESS) {
+ return false;
+ }
+ *size = cb.size;
+ *data = cb.data;
+ }
+ break;
+#endif
+
case LIBMEMC_BINARY:
case LIBMEMC_TEXTUAL:
{

0 comments on commit eaf0f9f

Please sign in to comment.