*.OTHER
*.THIS
*.exe
+*.gz
*.lo
+*.orig
*.output
*.pop
+*.rej
*.rpm
+*.tar
*/*.l[oa]
*/*/*.l[oa]
*/*/.deps
*TAGS
.deps
.hg/
-.hgsub
.hgignore
+.hgsub
.hgsubstate
INSTALL
Makefile
TAGS
aclocal.m4
autom4te.cache
+autoscan.log
clients/memaslap
clients/memcapable
clients/memcat
clients/memstat
config.h
config.h.in
+config.in
config.log
config.status
config/compile
config/plugin.ac
config/top.h
configure
+configure.scan
docs/*.[13]
docs/*.html
docs/changes
docs/text
example/memcached_light
libhashkit/configure.h
-libmemcached-*.tar.gz
-libmemcached-0.30-1.src.rpm
-libmemcached-0.30-1.x86_64.rpm
-libmemcached-0.31-1.src.rpm
-libmemcached-0.31-1.x86_64.rpm
-libmemcached-0.37-1.src.rpm
-libmemcached-0.37-1.x86_64.rpm
libmemcached-?.??/
libmemcached/configure.h
libmemcached/dtrace_probes.h
ltsugar.m4
ltversion.m4
lt~obsolete.m4
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+out
patch
patch2
stamp-h1
support/libmemcached.spec
tags
tests/atomsmasher
+tests/c_test
tests/cycle
tests/hash_plus
tests/hashplus
+tests/internals
+tests/memcapable
tests/memplus
+tests/memslap
tests/output.cmp
tests/startservers
tests/testapp
tests/testudp
tests/var/
unittests/unittests
-out
-*.orig
-tests/memcapable
-tests/memslap
m4/po.m4 \
m4/progtest.m4
-include libtest/include.am
-include libmemcached/include.am
-include libmemcached/protocol/include.am
-include libmemcached/util/include.am
+libmemcached_libmemcached_la_LDFLAGS=
+
include clients/include.am
-include libhashkit/include.am
-include tests/include.am
+include docs/include.am
include example/include.am
-include support/include.am
+include libhashkit/include.am
+include libmemcached/include.am
+include libmemcached/util/include.am
+include libmemcached/protocol/include.am
+include libmemcachedinternal/include.am
+include libmemcachedinternal/util/include.am
+include libtest/include.am
include poll/include.am
+include support/include.am
+include tests/include.am
include util/include.am
include win32/include.am
-include docs/include.am
docs: html man
clients_memslap_SOURCES = clients/memslap.cc
clients_memslap_SOURCES+= clients/generator.cc clients/execute.cc
+clients_memslap_CXXFLAGS = ${PTHREAD_CFLAGS}
clients_memslap_LDADD = $(PTHREAD_LIBS) $(CLIENTS_LDADDS)
clients_memaslap_SOURCES= \
/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
#undef NDEBUG
-#include "config.h"
-#include <pthread.h>
-#include <sys/types.h>
+#include <config.h>
+
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#else
+#include "poll/poll.h"
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
+#include <pthread.h>
#include <signal.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
#include <string.h>
-#include <inttypes.h>
-#include <stdbool.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <ctype.h>
#include <libmemcached/memcached.h>
#include <libmemcached/memcached/protocol_binary.h>
#include <libmemcached/byteorder.h>
-#include "utilities.h"
+#include <clients/utilities.h>
#ifdef linux
/* /usr/include/netinet/in.h defines macros from ntohs() to _bswap_nn to
#include <config.h>
+#include <cstdio>
#include <iostream>
#include <libmemcached/memcached.h>
#!/bin/sh
-#
-# Copyright (C) 2006 Jan Kneschke
-# Copyright (C) 2009 Sun Microsystems, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# 3. The name of the author may not be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Run this to generate all the initial makefiles, etc.
-
-die() { echo "$@"; exit 1; }
-
-# --force means overwrite ltmain.sh script if it already exists
-LIBTOOLIZE_FLAGS=" --automake --copy --force"
-# --add-missing instructs automake to install missing auxiliary files
-# and --force to overwrite them if they already exist
-AUTOMAKE_FLAGS="--add-missing --copy --force --foreign"
-ACLOCAL_FLAGS="-I m4"
-
-ARGV0=$0
-ARGS="$@"
-
-run() {
- echo "$ARGV0: running \`$@' $ARGS"
- $@ $ARGS
-}
-
-# Try to locate a program by using which, and verify that the file is an
-# executable
-locate_binary() {
- for f in $@
- do
- file=`which $f 2>/dev/null | grep -v '^no '`
- if test -n "$file" -a -x "$file"; then
- echo $file
- return 0
- fi
- done
-
- echo ""
- return 1
-}
-
-
-if test -f config/pre_hook.sh
-then
- . config/pre_hook.sh
-fi
-
-# Try to detect the supported binaries if the user didn't
-# override that by pushing the environment variable
-if test x$LIBTOOLIZE = x; then
- LIBTOOLIZE=`locate_binary glibtoolize libtoolize-1.5 libtoolize`
- if test x$LIBTOOLIZE = x; then
- die "Did not find a supported libtoolize"
- fi
-fi
-
-if test x$ACLOCAL = x; then
- ACLOCAL=`locate_binary aclocal-1.11 aclocal-1.10 aclocal-1.9 aclocal19 aclocal`
- if test x$ACLOCAL = x; then
- die "Did not find a supported aclocal"
- fi
-fi
-
-if test x$AUTOMAKE = x; then
- AUTOMAKE=`locate_binary automake-1.11 automake-1.10 automake-1.9 automake19 automake`
- if test x$AUTOMAKE = x; then
- die "Did not find a supported automake"
- fi
-fi
-
-if test x$AUTOCONF = x; then
- AUTOCONF=`locate_binary autoconf-2.59 autoconf259 autoconf`
- if test x$AUTOCONF = x; then
- die "Did not find a supported autoconf"
- fi
-fi
-
-if test x$AUTOHEADER = x; then
- AUTOHEADER=`locate_binary autoheader-2.59 autoheader259 autoheader`
- if test x$AUTOHEADER = x; then
- die "Did not find a supported autoheader"
- fi
-fi
-
-run $LIBTOOLIZE $LIBTOOLIZE_FLAGS || die "Can't execute libtoolize"
-run $ACLOCAL $ACLOCAL_FLAGS || die "Can't execute aclocal"
-run $AUTOHEADER || die "Can't execute autoheader"
-run $AUTOMAKE $AUTOMAKE_FLAGS || die "Can't execute automake"
-run $AUTOCONF || die "Can't execute autoconf"
-
-if test -f config/post_hook.sh
-then
- . config/post_hook.sh
-fi
-
-echo "---"
-echo "Configured with the following tools:"
-echo " * `$LIBTOOLIZE --version | head -1`"
-echo " * `$ACLOCAL --version | head -1`"
-echo " * `$AUTOHEADER --version | head -1`"
-echo " * `$AUTOMAKE --version | head -1`"
-echo " * `$AUTOCONF --version | head -1`"
-echo "---"
+autoreconf -ivf
# Use and distribution licensed under the BSD license. See
# the COPYING file in this directory for full text.
-AC_PREREQ(2.59)
-AC_INIT([libmemcached],[0.51],[http://libmemcached.org/])
-AC_CONFIG_SRCDIR([libmemcached/memcached.cc])
+AC_INIT([libmemcached],[0.52],[http://libmemcached.org/])
+
AC_CONFIG_AUX_DIR(config)
+
+AC_CANONICAL_TARGET
+
+AM_INIT_AUTOMAKE
+
+AC_CANONICAL_HOST
+AC_CANONICAL_BUILD
+
+AC_PREREQ([2.61])
+
AC_CONFIG_MACRO_DIR(m4)
+AC_CONFIG_HEADERS([config.h:config.in])dnl Keep filename to 8.3 for MS-DOS.
+
+AC_CONFIG_SRCDIR([libmemcached/memcached.cc])
+
PANDORA_CANONICAL_TARGET(no-vc-changelog)
AC_CHECK_PROGS([YACC], ['bison'], [:])
AC_CHECK_PROGS([LEX], ['flex'], [:])
AC_DEFINE([HAVE_LIBMEMCACHED], [ 1 ], [dummy rule for libtest])
AC_SUBST(HAVE_LIBMEMCACHED, 1)
AM_CONDITIONAL(HAVE_LIBMEMCACHED, true)
-
-AH_TOP([
-#ifndef CONFIG_H
-#define CONFIG_H
-
-#ifdef _SYS_FEATURE_TESTS_H
-#error "You should include config.h as your first include file"
-#endif
-
-#ifdef WIN32
-#define _WIN32_WINNT 0x0501
-#endif
-])
-
-AH_BOTTOM([
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-#ifdef HAVE_FNMATCH_H
-#include <fnmatch.h>
-#endif
-
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#else
-#include "poll/poll.h"
-#endif
-
-/* To hide the platform differences between MS Windows and Unix, I am
- * going to use the Microsoft way and #define the Microsoft-specific
- * functions to the unix way. Microsoft use a separate subsystem for sockets,
- * but Unix normally just use a filedescriptor on the same functions. It is
- * a lot easier to map back to the unix way with macros than going the other
- * way without side effect ;-)
- */
-#ifdef WIN32
-#include "win32/wrappers.h"
-#define get_socket_errno() WSAGetLastError()
-#else
-#define INVALID_SOCKET -1
-#define SOCKET_ERROR -1
-#define closesocket(a) close(a)
-#define get_socket_errno() errno
-#endif
-
-#ifndef HAVE_MSG_NOSIGNAL
-#define MSG_NOSIGNAL 0
-#endif
-
-#ifndef HAVE_MSG_DONTWAIT
-#define MSG_DONTWAIT 0
-#endif
-
-#ifndef HAVE_MSG_MORE
-#define MSG_MORE 0
-#endif
-
-#endif
-])
+LT_INIT
AC_SEARCH_LIBS(getopt_long, gnugetopt)
AC_SEARCH_LIBS(gethostbyname, nsl)
-AC_CHECK_FUNCS([getline])
-
PANDORA_HAVE_LIBEVENT
my_saved_libs="$LIBS"
LIBS=
LIBS="$my_saved_libs"
dnl Specialty checks
+CONFIG_EXTRA
DETECT_BYTEORDER
ENABLE_UTILLIB
SETSOCKOPT_SANITY
PANDORA_HAVE_SASL
WITH_LIBGEARMAN
+AC_CHECK_FUNCS([alarm])
+AC_CHECK_FUNCS([dup2])
+AC_CHECK_FUNCS([getline])
+AC_CHECK_FUNCS([gettimeofday])
+AC_CHECK_FUNCS([memchr])
+AC_CHECK_FUNCS([memmove])
+AC_CHECK_FUNCS([memset])
+AC_CHECK_FUNCS([select])
+AC_CHECK_FUNCS([setenv])
+AC_CHECK_FUNCS([socket])
+AC_CHECK_FUNCS([sqrt])
+AC_CHECK_FUNCS([strcasecmp])
+AC_CHECK_FUNCS([strchr])
+AC_CHECK_FUNCS([strdup])
+AC_CHECK_FUNCS([strerror])
+AC_CHECK_FUNCS([strtol])
+AC_CHECK_FUNCS([strtoul])
+AC_CHECK_FUNCS([strtoull])
+AC_CHECK_HEADERS([arpa/inet.h])
+AC_CHECK_HEADERS([fcntl.h])
+AC_CHECK_HEADERS([libintl.h])
+AC_CHECK_HEADERS([limits.h])
+AC_CHECK_HEADERS([malloc.h])
+AC_CHECK_HEADERS([netdb.h])
+AC_CHECK_HEADERS([netinet/in.h])
+AC_CHECK_HEADERS([stddef.h])
+AC_CHECK_HEADERS([sys/time.h])
+AC_FUNC_ALLOCA
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_FORK
+AC_FUNC_MALLOC
+AC_FUNC_REALLOC
+AC_FUNC_STRERROR_R
+AC_HEADER_STDBOOL
+AC_TYPE_INT16_T
+AC_TYPE_INT32_T
+AC_TYPE_INT64_T
+AC_TYPE_INT8_T
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SSIZE_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT64_T
+AC_TYPE_UINT8_T
+
dnl The sasl functions should only be visible if we build with sasl support
AS_IF([test "x$ac_cv_sasl" = "xyes"],
[LIBMEMCACHED_WITH_SASL_SUPPORT="#define LIBMEMCACHED_WITH_SASL_SUPPORT 1"])
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <example/byteorder.h>
+
+/* Byte swap a 64-bit number. */
+#ifndef swap64
+static inline uint64_t swap64(uint64_t in)
+{
+#ifndef WORDS_BIGENDIAN
+ /* Little endian, flip the bytes around until someone makes a faster/better
+ * way to do this. */
+ uint64_t rv= 0;
+ for (uint8_t x= 0; x < 8; x++)
+ {
+ rv= (rv << 8) | (in & 0xff);
+ in >>= 8;
+ }
+ return rv;
+#else
+ /* big-endian machines don't need byte swapping */
+ return in;
+#endif // WORDS_BIGENDIAN
+}
+#endif
+
+#ifdef HAVE_HTONLL
+
+uint64_t example_ntohll(uint64_t value)
+{
+ return ntohll(value);
+}
+
+uint64_t example_htonll(uint64_t value)
+{
+ return htonll(value);
+}
+
+#else // HAVE_HTONLL
+
+uint64_t example_ntohll(uint64_t value)
+{
+ return swap64(value);
+}
+
+uint64_t example_htonll(uint64_t value)
+{
+ return swap64(value);
+}
+
+#endif // HAVE_HTONLL
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Byteorder for example
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint64_t example_ntohll(uint64_t);
+
+uint64_t example_htonll(uint64_t);
+
+#ifdef __cplusplus
+}
+#endif
noinst_PROGRAMS += example/memcached_light
endif
+noinst_HEADERS+= \
+ example/byteorder.h \
+ example/memcached_light.h \
+ example/storage.h
+
example_memcached_light_SOURCES= \
+ example/byteorder.cc \
example/interface_v0.c \
example/interface_v1.c \
- example/memcached_light.c \
- libmemcached/byteorder.cc \
- example/memcached_light.h \
- example/storage.h
+ example/memcached_light.c
example_memcached_light_LDADD= libmemcached/libmemcachedprotocol.la \
$(LIBINNODB) $(LTLIBEVENT)
#include <string.h>
#include <libmemcached/protocol_handler.h>
-#include <libmemcached/byteorder.h>
+#include <example/byteorder.h>
#include "storage.h"
#include "memcached_light.h"
msg.response.message.body.flags= htonl(item->flags);
char *ptr= (char*)(msg.response.bytes + sizeof(*header) + 4);
uint32_t bodysize= 4;
- msg.response.message.header.response.cas= memcached_htonll(item->cas);
+ msg.response.message.header.response.cas= example_htonll(item->cas);
if (opcode == PROTOCOL_BINARY_CMD_GETK || opcode == PROTOCOL_BINARY_CMD_GETKQ)
{
memcpy(ptr, item->key, item->nkey);
};
uint16_t keylen= ntohs(header->request.keylen);
- uint64_t initial= memcached_ntohll(req->message.body.initial);
- uint64_t delta= memcached_ntohll(req->message.body.delta);
+ uint64_t initial= example_ntohll(req->message.body.initial);
+ uint64_t delta= example_ntohll(req->message.body.delta);
uint32_t expiration= ntohl(req->message.body.expiration);
uint32_t flags= 0;
void *key= req->bytes + sizeof(req->bytes);
if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS)
{
response.message.header.response.bodylen= ntohl(8);
- response.message.body.value= memcached_ntohll((*(uint64_t*)item->data));
- response.message.header.response.cas= memcached_ntohll(item->cas);
+ response.message.body.value= example_ntohll((*(uint64_t*)item->data));
+ response.message.header.response.cas= example_ntohll(item->cas);
release_item(item);
if (header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENTQ ||
{
protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
uint16_t keylen= ntohs(header->request.keylen);
- uint64_t cas= memcached_ntohll(header->request.cas);
+ uint64_t cas= example_ntohll(header->request.cas);
void *key= header + 1;
uint32_t vallen= ntohl(header->request.bodylen) - keylen;
void *val= (char*)key + keylen;
.opcode= header->request.opcode,
.status= htons(rval),
.opaque= header->request.opaque,
- .cas= memcached_htonll(cas),
+ .cas= example_htonll(cas),
}
}
};
struct item* item= get_item(key, keylen);
if (item != NULL)
{
- if (item->cas != memcached_ntohll(header->request.cas))
+ if (item->cas != example_ntohll(header->request.cas))
{
release_item(item);
response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS);
/* SETQ shouldn't return a message */
if (header->request.opcode == PROTOCOL_BINARY_CMD_SET)
{
- response.message.header.response.cas= memcached_htonll(item->cas);
+ response.message.header.response.cas= example_htonll(item->cas);
release_item(item);
return response_handler(cookie, header, (void*)&response);
}
/* ADDQ shouldn't return a message */
if (header->request.opcode == PROTOCOL_BINARY_CMD_ADD)
{
- response.message.header.response.cas= memcached_htonll(item->cas);
+ response.message.header.response.cas= example_htonll(item->cas);
release_item(item);
return response_handler(cookie, header, (void*)&response);
}
{
response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_ENOENT);
}
- else if (header->request.cas == 0 || memcached_ntohll(header->request.cas) == item->cas)
+ else if (header->request.cas == 0 || example_ntohll(header->request.cas) == item->cas)
{
release_item(item);
delete_item(key, keylen);
/* REPLACEQ shouldn't return a message */
if (header->request.opcode == PROTOCOL_BINARY_CMD_REPLACE)
{
- response.message.header.response.cas= memcached_htonll(item->cas);
+ response.message.header.response.cas= example_htonll(item->cas);
release_item(item);
return response_handler(cookie, header, (void*)&response);
}
#include <string.h>
#include <libmemcached/protocol_handler.h>
-#include <libmemcached/byteorder.h>
+#include <example/byteorder.h>
#include "storage.h"
static protocol_binary_response_status add_handler(const void *cookie,
#include <event.h>
#include <libmemcached/protocol_handler.h>
-#include <libmemcached/byteorder.h>
+#include <example/byteorder.h>
#include "storage.h"
#include "memcached_light.h"
#include <libhashkit/common.h>
/* FNV hash'es lifted from Dustin Sallings work */
-static uint64_t FNV_64_INIT= UINT64_C(0xcbf29ce484222325);
-static uint64_t FNV_64_PRIME= UINT64_C(0x100000001b3);
+static uint64_t FNV_64_INIT= uint64_t(0xcbf29ce484222325);
+static uint64_t FNV_64_PRIME= uint64_t(0x100000001b3);
static uint32_t FNV_32_INIT= 2166136261UL;
static uint32_t FNV_32_PRIME= 16777619;
libhashkit_libhashkit_la_SOURCES+= libhashkit/murmur.cc
endif
+libhashkit_libhashkit_la_CPPFLAGS= \
+ ${AM_CPPFLAGS} \
+ -DBUILDING_HASHKIT
+
+libhashkit_libhashkit_la_CFLAGS= \
+ ${AM_CFLAGS} \
+ -DBUILDING_HASHKIT
+
libhashkit_libhashkit_la_CXXFLAGS= \
${AM_CXXFLAGS} \
-DBUILDING_HASHKIT
$(LIBM) \
-version-info $(HASHKIT_LIBRARY_VERSION)
+# library used for testing
noinst_LTLIBRARIES+= libhashkit/libhashkitinc.la
libhashkit_libhashkitinc_la_SOURCES= ${libhashkit_libhashkit_la_SOURCES}
*
*/
-#include <config.h>
-
-#include <sys/types.h>
-
-#include <libmemcached/visibility.h>
-#include <libmemcached/byteorder.h>
+#include <libmemcached/common.h>
/* Byte swap a 64-bit number. */
#ifndef swap64
#include <libmemcached/is.h>
#include <libmemcached/namespace.h>
+#include <libmemcached/server_instance.h>
+
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#else
+#include "poll/poll.h"
+#endif
+
+
#ifdef __cplusplus
extern "C" {
#endif
-typedef struct memcached_server_st * memcached_server_write_instance_st;
-
typedef memcached_return_t (*memcached_server_execute_fn)(memcached_st *ptr, memcached_server_write_instance_st server, void *context);
LIBMEMCACHED_LOCAL
#include <libmemcached/error.hpp>
#include <libmemcached/memory.h>
#include <libmemcached/io.h>
+#ifdef __cplusplus
+#include <libmemcached/string.hpp>
+#include <libmemcached/io.hpp>
#include <libmemcached/do.hpp>
+#endif
#include <libmemcached/internal.h>
#include <libmemcached/array.h>
#include <libmemcached/libmemcached_probes.h>
#include <libmemcached/assert.hpp>
#endif
-/* string value */
-struct memcached_continuum_item_st
-{
- uint32_t index;
- uint32_t value;
-};
+#include <libmemcached/continuum.hpp>
#if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
if ((connect(ptr->fd, ptr->address_info_next->ai_addr, ptr->address_info_next->ai_addrlen) != SOCKET_ERROR))
{
ptr->state= MEMCACHED_SERVER_STATE_CONNECTED;
- break; // Success
+ return MEMCACHED_SUCCESS;
}
/* An error occurred */
/* We need to clean up the multi startup piece */
switch (ptr->type)
{
- case MEMCACHED_CONNECTION_UNKNOWN:
- WATCHPOINT_ASSERT(0);
- rc= MEMCACHED_NOT_SUPPORTED;
- break;
-
case MEMCACHED_CONNECTION_UDP:
case MEMCACHED_CONNECTION_TCP:
rc= network_connect(ptr);
case MEMCACHED_CONNECTION_UNIX_SOCKET:
rc= unix_socket_connect(ptr);
break;
-
- case MEMCACHED_CONNECTION_MAX:
- default:
- WATCHPOINT_ASSERT(0);
}
if (memcached_success(rc))
#endif
enum memcached_connection_t {
- MEMCACHED_CONNECTION_UNKNOWN,
MEMCACHED_CONNECTION_TCP,
MEMCACHED_CONNECTION_UDP,
- MEMCACHED_CONNECTION_UNIX_SOCKET,
- MEMCACHED_CONNECTION_MAX
+ MEMCACHED_CONNECTION_UNIX_SOCKET
+};
+
+enum {
+ MEMCACHED_CONNECTION_UNKNOWN= 0,
+ MEMCACHED_CONNECTION_MAX= 0
};
#ifndef __cplusplus
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * LibMemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+/* string value */
+struct memcached_continuum_item_st
+{
+ uint32_t index;
+ uint32_t value;
+};
return MEMCACHED_WRITE_FAILURE;
if (send_length + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
+ {
memcached_io_write(instance, NULL, 0, true);
+ }
}
rc= memcached_do(instance, buffer, (size_t)send_length, to_write);
memcached_return_t memcached_server_error_return(memcached_server_instance_st ptr)
{
+ if (ptr == NULL)
+ {
+ return MEMCACHED_INVALID_ARGUMENTS;
+ }
+
if (ptr and ptr->error_messages)
{
return ptr->error_messages->rc;
}
- return MEMCACHED_FAILURE;
+ return MEMCACHED_SUCCESS;
}
}
if (value_length)
+ {
*value_length= memcached_string_length(&result_buffer->value);
+ }
if (key)
{
libmemcached/backtrace.hpp \
libmemcached/byteorder.h \
libmemcached/common.h \
+ libmemcached/continuum.hpp \
libmemcached/do.hpp \
libmemcached/error.hpp \
libmemcached/initialize_query.h \
libmemcached/internal.h \
libmemcached/io.h \
+ libmemcached/io.hpp \
libmemcached/is.h \
libmemcached/libmemcached_probes.h \
libmemcached/memory.h \
libmemcached/protocol/binary_handler.h \
libmemcached/protocol/common.h \
libmemcached/response.h \
+ libmemcached/server_instance.h \
+ libmemcached/string.hpp \
libmemcached/virtual_bucket.h
nobase_include_HEADERS+= \
libmemcached/visibility.h \
libmemcached/watchpoint.h
-# This noinst lib contains things we want to be ABI private but still want to
-# either use in client programs or be able to test in test cases
-# These symbols will not be exposed in the shipped .so
-noinst_LTLIBRARIES+= libmemcached/libmemcachedinternal.la
-libmemcached_libmemcachedinternal_la_SOURCES= \
- libmemcached/array.c \
- libmemcached/backtrace.cc \
- libmemcached/error.cc \
- libmemcached/string.cc
-libmemcached_libmemcachedinternal_la_CFLAGS= \
- ${AM_CFLAGS} \
- ${NO_CONVERSION} \
- -DBUILDING_LIBMEMCACHED
-
-libmemcached_libmemcachedinternal_la_CXXFLAGS= \
- ${AM_CXXFLAGS} \
- ${NO_CONVERSION} \
- -DBUILDING_LIBMEMCACHED
-
lib_LTLIBRARIES+= libmemcached/libmemcached.la
libmemcached_libmemcached_la_CFLAGS= \
${AM_CFLAGS} \
libmemcached_libmemcached_la_DEPENDENCIES=
libmemcached_libmemcached_la_LIBADD= $(LIBM)
-libmemcached_libmemcached_la_LDFLAGS= ${AM_LDFLAGS} -version-info ${MEMCACHED_LIBRARY_VERSION}
+libmemcached_libmemcached_la_LDFLAGS+= ${AM_LDFLAGS} -version-info ${MEMCACHED_LIBRARY_VERSION}
if HAVE_SASL
libmemcached_libmemcached_la_LDFLAGS+= $(LTLIBSASL) $(LTLIBSASL2)
if HAVE_DTRACE
BUILT_SOURCES+= libmemcached/dtrace_probes.h
CLEANFILES+= libmemcached/dtrace_probes.h
-endif
+CLEANFILES+= libmemcached/libmemcached_probes.o
-if DTRACE_NEEDS_OBJECTS
-libmemcached_libmemcached_la_SOURCES += libmemcached/libmemcached_probes.d
libmemcached_libmemcached_la_DEPENDENCIES += libmemcached/libmemcached_probes.o
libmemcached_libmemcached_la_LIBADD += libmemcached/libmemcached_probes.o
-CLEANFILES+= libmemcached/libmemcached_probes.o
+libmemcached_libmemcached_la_SOURCES += libmemcached/libmemcached_probes.d
endif
SUFFIXES+= .d
libmemcached/dtrace_probes.h: libmemcached/libmemcached_probes.d
- $(DTRACE) $(DTRACEFLAGS) -h -o libmemcached/dtrace_probes.h -s ${top_srcdir}/libmemcached/libmemcached_probes.d
+ $(DTRACE) $(DTRACEFLAGS) -h -o ${top_srcdir}/libmemcached/dtrace_probes.h -s ${top_srcdir}/libmemcached/libmemcached_probes.d
libmemcached/libmemcached_probes.o: libmemcached/libmemcached_probes.d ${libmemcached_libmemcached_la_OBJECTS} config.h
.d.o:
- $(DTRACE) $(DTRACEFLAGS) -o $@ -G -s $< `grep '^pic_object' ${top_builddir}/libmemcached/*.lo | cut -f 2 -d\' | sed "s/^/${top_builddir}\/libmemcached\//"`
-
+ $(DTRACE) $(DTRACEFLAGS) -o $@ -G -s libmemcached/libmemcached_probes.d
MEM_WRITE
};
-static ssize_t io_flush(memcached_server_write_instance_st ptr,
- const bool with_flush,
- memcached_return_t *error);
-static void increment_udp_message_id(memcached_server_write_instance_st ptr);
+/*
+ * The udp request id consists of two seperate sections
+ * 1) The thread id
+ * 2) The message number
+ * The thread id should only be set when the memcached_st struct is created
+ * and should not be changed.
+ *
+ * The message num is incremented for each new message we send, this function
+ * extracts the message number from message_id, increments it and then
+ * writes the new value back into the header
+ */
+static void increment_udp_message_id(memcached_server_write_instance_st ptr)
+{
+ struct udp_datagram_header_st *header= (struct udp_datagram_header_st *)ptr->write_buffer;
+ uint16_t cur_req= get_udp_datagram_request_id(header);
+ int msg_num= get_msg_num_from_request_id(cur_req);
+ int thread_id= get_thread_id_from_request_id(cur_req);
+
+ if (((++msg_num) & UDP_REQUEST_ID_THREAD_MASK) != 0)
+ msg_num= 0;
+
+ header->request_id= htons((uint16_t) (thread_id | msg_num));
+}
+
+/**
+ * Try to fill the input buffer for a server with as much
+ * data as possible.
+ *
+ * @param ptr the server to pack
+ */
+static bool repack_input_buffer(memcached_server_write_instance_st ptr)
+{
+ if (ptr->read_ptr != ptr->read_buffer)
+ {
+ /* Move all of the data to the beginning of the buffer so
+ ** that we can fit more data into the buffer...
+ */
+ memmove(ptr->read_buffer, ptr->read_ptr, ptr->read_buffer_length);
+ ptr->read_ptr= ptr->read_buffer;
+ ptr->read_data_length= ptr->read_buffer_length;
+ }
+
+ /* There is room in the buffer, try to fill it! */
+ if (ptr->read_buffer_length != MEMCACHED_MAX_BUFFER)
+ {
+ do {
+ /* Just try a single read to grab what's available */
+ ssize_t nr= recv(ptr->fd,
+ ptr->read_ptr + ptr->read_data_length,
+ MEMCACHED_MAX_BUFFER - ptr->read_data_length,
+ MSG_DONTWAIT);
+
+ switch (nr)
+ {
+ case SOCKET_ERROR:
+ {
+ switch (get_socket_errno())
+ {
+ case EINTR:
+ continue;
+
+ case EWOULDBLOCK:
+#ifdef USE_EAGAIN
+ case EAGAIN:
+#endif
+#ifdef TARGET_OS_LINUX
+ case ERESTART:
+#endif
+ break; // No IO is fine, we can just move on
+
+ default:
+ memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
+ }
+ }
+ break;
+
+ case 0: // Shutdown on the socket has occurred
+ {
+ memcached_set_error(*ptr, MEMCACHED_CONNECTION_FAILURE, MEMCACHED_AT);
+ }
+ break;
+
+ default:
+ {
+ ptr->read_data_length+= size_t(nr);
+ ptr->read_buffer_length+= size_t(nr);
+ return true;
+ }
+ break;
+ }
+ } while (0);
+ }
+ return false;
+}
+
+/**
+ * If the we have callbacks connected to this server structure
+ * we may start process the input queue and fire the callbacks
+ * for the incomming messages. This function is _only_ called
+ * when the input buffer is full, so that we _know_ that we have
+ * at least _one_ message to process.
+ *
+ * @param ptr the server to star processing iput messages for
+ * @return true if we processed anything, false otherwise
+ */
+static bool process_input_buffer(memcached_server_write_instance_st ptr)
+{
+ /*
+ ** We might be able to process some of the response messages if we
+ ** have a callback set up
+ */
+ if (ptr->root->callbacks != NULL && ptr->root->flags.use_udp == false)
+ {
+ /*
+ * We might have responses... try to read them out and fire
+ * callbacks
+ */
+ memcached_callback_st cb= *ptr->root->callbacks;
+
+ memcached_set_processing_input((memcached_st *)ptr->root, true);
+
+ char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+ memcached_return_t error;
+ memcached_st *root= (memcached_st *)ptr->root;
+ error= memcached_response(ptr, buffer, sizeof(buffer),
+ &root->result);
+
+ memcached_set_processing_input(root, false);
+
+ if (error == MEMCACHED_SUCCESS)
+ {
+ for (unsigned int x= 0; x < cb.number_of_callback; x++)
+ {
+ error= (*cb.callback[x])(ptr->root, &root->result, cb.context);
+ if (error != MEMCACHED_SUCCESS)
+ break;
+ }
+
+ /* @todo what should I do with the error message??? */
+ }
+ /* @todo what should I do with other error messages?? */
+ return true;
+ }
+
+ return false;
+}
static memcached_return_t io_wait(memcached_server_write_instance_st ptr,
memc_read_or_write read_or_write)
return memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
}
-memcached_return_t memcached_io_wait_for_write(memcached_server_write_instance_st ptr)
+static ssize_t io_flush(memcached_server_write_instance_st ptr,
+ const bool with_flush,
+ memcached_return_t *error)
{
- return io_wait(ptr, MEM_WRITE);
-}
-
-/**
- * Try to fill the input buffer for a server with as much
- * data as possible.
- *
- * @param ptr the server to pack
+ /*
+ ** We might want to purge the input buffer if we haven't consumed
+ ** any output yet... The test for the limits is the purge is inline
+ ** in the purge function to avoid duplicating the logic..
*/
-static bool repack_input_buffer(memcached_server_write_instance_st ptr)
-{
- if (ptr->read_ptr != ptr->read_buffer)
{
- /* Move all of the data to the beginning of the buffer so
- ** that we can fit more data into the buffer...
- */
- memmove(ptr->read_buffer, ptr->read_ptr, ptr->read_buffer_length);
- ptr->read_ptr= ptr->read_buffer;
- ptr->read_data_length= ptr->read_buffer_length;
+ memcached_return_t rc;
+ WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
+ rc= memcached_purge(ptr);
+
+ if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_STORED)
+ {
+ return -1;
+ }
}
+ ssize_t sent_length;
+ size_t return_length;
+ char *local_write_ptr= ptr->write_buffer;
+ size_t write_length= ptr->write_buffer_offset;
- /* There is room in the buffer, try to fill it! */
- if (ptr->read_buffer_length != MEMCACHED_MAX_BUFFER)
+ *error= MEMCACHED_SUCCESS;
+
+ WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
+
+ // UDP Sanity check, make sure that we are not sending somthing too big
+ if (ptr->type == MEMCACHED_CONNECTION_UDP && write_length > MAX_UDP_DATAGRAM_LENGTH)
{
- do {
- /* Just try a single read to grab what's available */
- ssize_t nr= recv(ptr->fd,
- ptr->read_ptr + ptr->read_data_length,
- MEMCACHED_MAX_BUFFER - ptr->read_data_length,
- MSG_DONTWAIT);
+ *error= MEMCACHED_WRITE_FAILURE;
+ return -1;
+ }
- switch (nr)
+ if (ptr->write_buffer_offset == 0 || (ptr->type == MEMCACHED_CONNECTION_UDP
+ && ptr->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH))
+ {
+ return 0;
+ }
+
+ /* Looking for memory overflows */
+#if defined(DEBUG)
+ if (write_length == MEMCACHED_MAX_BUFFER)
+ WATCHPOINT_ASSERT(ptr->write_buffer == local_write_ptr);
+ WATCHPOINT_ASSERT((ptr->write_buffer + MEMCACHED_MAX_BUFFER) >= (local_write_ptr + write_length));
+#endif
+
+ return_length= 0;
+ while (write_length)
+ {
+ WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
+ WATCHPOINT_ASSERT(write_length > 0);
+ sent_length= 0;
+ if (ptr->type == MEMCACHED_CONNECTION_UDP)
+ increment_udp_message_id(ptr);
+
+ WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
+ if (with_flush)
+ {
+ sent_length= send(ptr->fd, local_write_ptr, write_length, MSG_NOSIGNAL|MSG_DONTWAIT);
+ }
+ else
+ {
+ sent_length= send(ptr->fd, local_write_ptr, write_length, MSG_NOSIGNAL|MSG_DONTWAIT|MSG_MORE);
+ }
+
+ if (sent_length == SOCKET_ERROR)
+ {
+ memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
+#if 0 // @todo I should look at why we hit this bit of code hard frequently
+ WATCHPOINT_ERRNO(get_socket_errno());
+ WATCHPOINT_NUMBER(get_socket_errno());
+#endif
+ switch (get_socket_errno())
{
- case SOCKET_ERROR:
+ case ENOBUFS:
+ continue;
+ case EWOULDBLOCK:
+#ifdef USE_EAGAIN
+ case EAGAIN:
+#endif
{
- switch (get_socket_errno())
+ /*
+ * We may be blocked on write because the input buffer
+ * is full. Let's check if we have room in our input
+ * buffer for more data and retry the write before
+ * waiting..
+ */
+ if (repack_input_buffer(ptr) or
+ process_input_buffer(ptr))
{
- case EINTR:
continue;
-
- case EWOULDBLOCK:
-#ifdef USE_EAGAIN
- case EAGAIN:
-#endif
-#ifdef TARGET_OS_LINUX
- case ERESTART:
-#endif
- break; // No IO is fine, we can just move on
-
- default:
- memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
}
- }
- break;
- case 0: // Shutdown on the socket has occurred
- {
- memcached_set_error(*ptr, MEMCACHED_CONNECTION_FAILURE, MEMCACHED_AT);
- }
- break;
+ memcached_return_t rc= io_wait(ptr, MEM_WRITE);
+ if (memcached_success(rc))
+ {
+ continue;
+ }
+ else if (rc == MEMCACHED_TIMEOUT)
+ {
+ *error= memcached_set_error(*ptr, MEMCACHED_TIMEOUT, MEMCACHED_AT);
+ return -1;
+ }
- default:
- {
- ptr->read_data_length+= size_t(nr);
- ptr->read_buffer_length+= size_t(nr);
- return true;
+ memcached_quit_server(ptr, true);
+ *error= memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
+ return -1;
}
- break;
+ case ENOTCONN:
+ case EPIPE:
+ default:
+ memcached_quit_server(ptr, true);
+ *error= memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
+ WATCHPOINT_ASSERT(ptr->fd == -1);
+ return -1;
}
- } while (0);
- }
- return false;
-}
+ }
-/**
- * If the we have callbacks connected to this server structure
- * we may start process the input queue and fire the callbacks
- * for the incomming messages. This function is _only_ called
- * when the input buffer is full, so that we _know_ that we have
- * at least _one_ message to process.
- *
- * @param ptr the server to star processing iput messages for
- * @return true if we processed anything, false otherwise
- */
-static bool process_input_buffer(memcached_server_write_instance_st ptr)
-{
- /*
- ** We might be able to process some of the response messages if we
- ** have a callback set up
- */
- if (ptr->root->callbacks != NULL && ptr->root->flags.use_udp == false)
- {
- /*
- * We might have responses... try to read them out and fire
- * callbacks
- */
- memcached_callback_st cb= *ptr->root->callbacks;
+ if (ptr->type == MEMCACHED_CONNECTION_UDP and
+ (size_t)sent_length != write_length)
+ {
+ memcached_quit_server(ptr, true);
+ *error= memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
+ return -1;
+ }
- memcached_set_processing_input((memcached_st *)ptr->root, true);
+ ptr->io_bytes_sent += (uint32_t) sent_length;
- char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
- memcached_return_t error;
- memcached_st *root= (memcached_st *)ptr->root;
- error= memcached_response(ptr, buffer, sizeof(buffer),
- &root->result);
+ local_write_ptr+= sent_length;
+ write_length-= (uint32_t) sent_length;
+ return_length+= (uint32_t) sent_length;
+ }
- memcached_set_processing_input(root, false);
+ WATCHPOINT_ASSERT(write_length == 0);
+ // Need to study this assert() WATCHPOINT_ASSERT(return_length ==
+ // ptr->write_buffer_offset);
- if (error == MEMCACHED_SUCCESS)
- {
- for (unsigned int x= 0; x < cb.number_of_callback; x++)
- {
- error= (*cb.callback[x])(ptr->root, &root->result, cb.context);
- if (error != MEMCACHED_SUCCESS)
- break;
- }
+ // if we are a udp server, the begining of the buffer is reserverd for
+ // the upd frame header
+ if (ptr->type == MEMCACHED_CONNECTION_UDP)
+ ptr->write_buffer_offset= UDP_DATAGRAM_HEADER_LENGTH;
+ else
+ ptr->write_buffer_offset= 0;
- /* @todo what should I do with the error message??? */
- }
- /* @todo what should I do with other error messages?? */
- return true;
- }
+ return (ssize_t) return_length;
+}
- return false;
+memcached_return_t memcached_io_wait_for_write(memcached_server_write_instance_st ptr)
+{
+ return io_wait(ptr, MEM_WRITE);
}
memcached_return_t memcached_io_read(memcached_server_write_instance_st ptr,
return NULL;
}
-static ssize_t io_flush(memcached_server_write_instance_st ptr,
- const bool with_flush,
- memcached_return_t *error)
-{
- /*
- ** We might want to purge the input buffer if we haven't consumed
- ** any output yet... The test for the limits is the purge is inline
- ** in the purge function to avoid duplicating the logic..
- */
- {
- memcached_return_t rc;
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
- rc= memcached_purge(ptr);
-
- if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_STORED)
- {
- return -1;
- }
- }
- ssize_t sent_length;
- size_t return_length;
- char *local_write_ptr= ptr->write_buffer;
- size_t write_length= ptr->write_buffer_offset;
-
- *error= MEMCACHED_SUCCESS;
-
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
-
- // UDP Sanity check, make sure that we are not sending somthing too big
- if (ptr->type == MEMCACHED_CONNECTION_UDP && write_length > MAX_UDP_DATAGRAM_LENGTH)
- {
- *error= MEMCACHED_WRITE_FAILURE;
- return -1;
- }
-
- if (ptr->write_buffer_offset == 0 || (ptr->type == MEMCACHED_CONNECTION_UDP
- && ptr->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH))
- {
- return 0;
- }
-
- /* Looking for memory overflows */
-#if defined(DEBUG)
- if (write_length == MEMCACHED_MAX_BUFFER)
- WATCHPOINT_ASSERT(ptr->write_buffer == local_write_ptr);
- WATCHPOINT_ASSERT((ptr->write_buffer + MEMCACHED_MAX_BUFFER) >= (local_write_ptr + write_length));
-#endif
-
- return_length= 0;
- while (write_length)
- {
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
- WATCHPOINT_ASSERT(write_length > 0);
- sent_length= 0;
- if (ptr->type == MEMCACHED_CONNECTION_UDP)
- increment_udp_message_id(ptr);
-
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
- if (with_flush)
- {
- sent_length= send(ptr->fd, local_write_ptr, write_length, MSG_NOSIGNAL|MSG_DONTWAIT);
- }
- else
- {
- sent_length= send(ptr->fd, local_write_ptr, write_length, MSG_NOSIGNAL|MSG_DONTWAIT|MSG_MORE);
- }
-
- if (sent_length == SOCKET_ERROR)
- {
- memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
-#if 0 // @todo I should look at why we hit this bit of code hard frequently
- WATCHPOINT_ERRNO(get_socket_errno());
- WATCHPOINT_NUMBER(get_socket_errno());
-#endif
- switch (get_socket_errno())
- {
- case ENOBUFS:
- continue;
- case EWOULDBLOCK:
-#ifdef USE_EAGAIN
- case EAGAIN:
-#endif
- {
- /*
- * We may be blocked on write because the input buffer
- * is full. Let's check if we have room in our input
- * buffer for more data and retry the write before
- * waiting..
- */
- if (repack_input_buffer(ptr) or
- process_input_buffer(ptr))
- {
- continue;
- }
-
- memcached_return_t rc= io_wait(ptr, MEM_WRITE);
- if (memcached_success(rc))
- {
- continue;
- }
- else if (rc == MEMCACHED_TIMEOUT)
- {
- *error= memcached_set_error(*ptr, MEMCACHED_TIMEOUT, MEMCACHED_AT);
- return -1;
- }
-
- memcached_quit_server(ptr, true);
- *error= memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
- return -1;
- }
- case ENOTCONN:
- case EPIPE:
- default:
- memcached_quit_server(ptr, true);
- *error= memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
- WATCHPOINT_ASSERT(ptr->fd == -1);
- return -1;
- }
- }
-
- if (ptr->type == MEMCACHED_CONNECTION_UDP and
- (size_t)sent_length != write_length)
- {
- memcached_quit_server(ptr, true);
- *error= memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
- return -1;
- }
-
- ptr->io_bytes_sent += (uint32_t) sent_length;
-
- local_write_ptr+= sent_length;
- write_length-= (uint32_t) sent_length;
- return_length+= (uint32_t) sent_length;
- }
-
- WATCHPOINT_ASSERT(write_length == 0);
- // Need to study this assert() WATCHPOINT_ASSERT(return_length ==
- // ptr->write_buffer_offset);
-
- // if we are a udp server, the begining of the buffer is reserverd for
- // the upd frame header
- if (ptr->type == MEMCACHED_CONNECTION_UDP)
- ptr->write_buffer_offset= UDP_DATAGRAM_HEADER_LENGTH;
- else
- ptr->write_buffer_offset= 0;
-
- return (ssize_t) return_length;
-}
-
/*
Eventually we will just kill off the server with the problem.
*/
memcached_return_t memcached_io_readline(memcached_server_write_instance_st ptr,
char *buffer_ptr,
- size_t size)
+ size_t size,
+ size_t& total_nr)
{
+ total_nr= 0;
bool line_complete= false;
- size_t total_nr= 0;
while (not line_complete)
{
return MEMCACHED_SUCCESS;
}
-/*
- * The udp request id consists of two seperate sections
- * 1) The thread id
- * 2) The message number
- * The thread id should only be set when the memcached_st struct is created
- * and should not be changed.
- *
- * The message num is incremented for each new message we send, this function
- * extracts the message number from message_id, increments it and then
- * writes the new value back into the header
- */
-static void increment_udp_message_id(memcached_server_write_instance_st ptr)
-{
- struct udp_datagram_header_st *header= (struct udp_datagram_header_st *)ptr->write_buffer;
- uint16_t cur_req= get_udp_datagram_request_id(header);
- int msg_num= get_msg_num_from_request_id(cur_req);
- int thread_id= get_thread_id_from_request_id(cur_req);
-
- if (((++msg_num) & UDP_REQUEST_ID_THREAD_MASK) != 0)
- msg_num= 0;
-
- header->request_id= htons((uint16_t) (thread_id | msg_num));
-}
-
memcached_return_t memcached_io_init_udp_header(memcached_server_write_instance_st ptr, uint16_t thread_id)
{
if (thread_id > UDP_REQUEST_ID_MAX_THREAD_ID)
#pragma once
-#include <libmemcached/memcached.h>
-
#define MAX_UDP_DATAGRAM_LENGTH 1400
#define UDP_DATAGRAM_HEADER_LENGTH 8
#define UDP_REQUEST_ID_MSG_SIG_DIGITS 10
#endif
LIBMEMCACHED_LOCAL
-memcached_return_t memcached_io_wait_for_write(memcached_server_write_instance_st ptr);
+ssize_t memcached_io_write(memcached_server_write_instance_st ptr,
+ const void *buffer, size_t length, bool with_flush);
LIBMEMCACHED_LOCAL
ssize_t memcached_io_writev(memcached_server_write_instance_st ptr,
const struct libmemcached_io_vector_st *vector,
size_t number_of, bool with_flush);
-LIBMEMCACHED_LOCAL
-ssize_t memcached_io_write(memcached_server_write_instance_st ptr,
- const void *buffer, size_t length, bool with_flush);
-
-LIBMEMCACHED_LOCAL
-void memcached_io_reset(memcached_server_write_instance_st ptr);
-
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_io_read(memcached_server_write_instance_st ptr,
- void *buffer, size_t length, ssize_t *nread);
-
-/* Read a line (terminated by '\n') into the buffer */
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_io_readline(memcached_server_write_instance_st ptr,
- char *buffer_ptr,
- size_t size);
-
-LIBMEMCACHED_LOCAL
-void memcached_io_close(memcached_server_write_instance_st ptr);
-
-/* Read n bytes of data from the server and store them in dta */
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_safe_read(memcached_server_write_instance_st ptr,
- void *dta,
- size_t size);
-
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_io_init_udp_header(memcached_server_write_instance_st ptr,
- uint16_t thread_id);
-
-LIBMEMCACHED_LOCAL
-memcached_server_write_instance_st memcached_io_get_readable_server(memcached_st *memc);
-
-LIBMEMCACHED_LOCAL
-memcached_return_t memcached_io_slurp(memcached_server_write_instance_st ptr);
-
#ifdef __cplusplus
}
#endif
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * LibMemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_io_wait_for_write(memcached_server_write_instance_st ptr);
+
+LIBMEMCACHED_LOCAL
+void memcached_io_reset(memcached_server_write_instance_st ptr);
+
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_io_read(memcached_server_write_instance_st ptr,
+ void *buffer, size_t length, ssize_t *nread);
+
+/* Read a line (terminated by '\n') into the buffer */
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_io_readline(memcached_server_write_instance_st ptr,
+ char *buffer_ptr,
+ size_t size,
+ size_t& total);
+
+LIBMEMCACHED_LOCAL
+void memcached_io_close(memcached_server_write_instance_st ptr);
+
+/* Read n bytes of data from the server and store them in dta */
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_safe_read(memcached_server_write_instance_st ptr,
+ void *dta,
+ size_t size);
+
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_io_init_udp_header(memcached_server_write_instance_st ptr,
+ uint16_t thread_id);
+
+LIBMEMCACHED_LOCAL
+memcached_server_write_instance_st memcached_io_get_readable_server(memcached_st *memc);
+
+LIBMEMCACHED_LOCAL
+memcached_return_t memcached_io_slurp(memcached_server_write_instance_st ptr);
*/
#include <libmemcached/common.h>
+#include <libmemcached/string.hpp>
static memcached_return_t textual_read_one_response(memcached_server_write_instance_st ptr,
char *buffer, size_t buffer_length,
char *buffer, size_t buffer_length,
memcached_result_st *result)
{
- memcached_return_t rc= memcached_io_readline(ptr, buffer, buffer_length);
+ size_t total_read;
+ memcached_return_t rc= memcached_io_readline(ptr, buffer, buffer_length, total_read);
+
if (memcached_failed(rc))
{
return rc;
}
else if (buffer[1] == 'E') /* SERVER_ERROR */
{
- char *startptr= buffer + 13, *endptr= startptr;
+ if (total_read == memcached_literal_param_size("SERVER_ERROR"))
+ {
+ return MEMCACHED_SERVER_ERROR;
+ }
+
+ if (total_read > memcached_literal_param_size("SERVER_ERROR object too large for cache") and
+ (memcmp(buffer, memcached_literal_param("SERVER_ERROR object too large for cache")) == 0))
+ {
+ return MEMCACHED_E2BIG;
+ }
+
+ // Move past the basic error message and whitespace
+ char *startptr= buffer + memcached_literal_param_size("SERVER_ERROR");
+ if (startptr[0] == ' ')
+ {
+ startptr++;
+ }
+ char *endptr= startptr;
while (*endptr != '\r' && *endptr != '\n') endptr++;
return memcached_set_error(*ptr, MEMCACHED_SERVER_ERROR, MEMCACHED_AT, startptr, size_t(endptr - startptr));
case PROTOCOL_BINARY_RESPONSE_KEY_ENOENT:
rc= MEMCACHED_NOTFOUND;
break;
+
case PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS:
rc= MEMCACHED_DATA_EXISTS;
break;
+
case PROTOCOL_BINARY_RESPONSE_NOT_STORED:
rc= MEMCACHED_NOTSTORED;
break;
+
case PROTOCOL_BINARY_RESPONSE_E2BIG:
rc= MEMCACHED_E2BIG;
break;
+
case PROTOCOL_BINARY_RESPONSE_ENOMEM:
rc= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
break;
+
case PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE:
rc= MEMCACHED_AUTH_CONTINUE;
break;
+
case PROTOCOL_BINARY_RESPONSE_AUTH_ERROR:
rc= MEMCACHED_AUTH_FAILURE;
break;
+
case PROTOCOL_BINARY_RESPONSE_EINVAL:
case PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND:
default:
typedef enum memcached_return_t memcached_return_t;
#endif
+static inline bool memcached_success(memcached_return_t rc)
+{
+ return (rc == MEMCACHED_BUFFERED ||
+ rc == MEMCACHED_DELETED ||
+ rc == MEMCACHED_END ||
+ rc == MEMCACHED_ITEM ||
+ rc == MEMCACHED_STAT ||
+ rc == MEMCACHED_STORED ||
+ rc == MEMCACHED_SUCCESS ||
+ rc == MEMCACHED_VALUE);
+}
-#define memcached_success(__memcached_return_t) ((__memcached_return_t) == MEMCACHED_SUCCESS or (__memcached_return_t) == MEMCACHED_END)
-#define memcached_failed(__memcached_return_t) ((__memcached_return_t) != MEMCACHED_SUCCESS and (__memcached_return_t) != MEMCACHED_END)
-#define memcached_continue(__memcached_return_t) ((__memcached_return_t) == MEMCACHED_IN_PROGRESS)
+static inline bool memcached_failed(memcached_return_t rc)
+{
+ return (rc != MEMCACHED_SUCCESS &&
+ rc != MEMCACHED_END &&
+ rc != MEMCACHED_STORED &&
+ rc != MEMCACHED_STAT &&
+ rc != MEMCACHED_DELETED &&
+ rc != MEMCACHED_BUFFERED &&
+ rc != MEMCACHED_VALUE);
+}
+#define memcached_continue(__memcached_return_t) ((__memcached_return_t) == MEMCACHED_IN_PROGRESS)
case MEMCACHED_CONNECTION_UNIX_SOCKET:
return "SOCKET";
-
- case MEMCACHED_CONNECTION_MAX:
- case MEMCACHED_CONNECTION_UNKNOWN:
- break;
}
}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * LibMemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct memcached_server_st * memcached_server_write_instance_st;
+
+#ifdef __cplusplus
+}
+#endif
{
switch (verb)
{
- case SET_OP:
- return "set ";
case REPLACE_OP:
return "replace ";
+
case ADD_OP:
return "add ";
+
case PREPEND_OP:
return "prepend ";
+
case APPEND_OP:
return "append ";
+
case CAS_OP:
return "cas ";
- default:
- return "tosserror"; /* This is impossible, fixes issue for compiler warning in VisualStudio */
+
+ case SET_OP:
+ break;
}
- /* NOTREACHED */
+ return "set ";
+}
+
+static inline uint8_t get_com_code(memcached_storage_action_t verb, bool noreply)
+{
+ /* 0 isn't a value we want, but GCC 4.2 seems to think ret can otherwise
+ * be used uninitialized in this function. FAIL */
+ uint8_t ret= 0;
+
+ if (noreply)
+ switch (verb)
+ {
+ case SET_OP:
+ ret=PROTOCOL_BINARY_CMD_SETQ;
+ break;
+ case ADD_OP:
+ ret=PROTOCOL_BINARY_CMD_ADDQ;
+ break;
+ case CAS_OP: /* FALLTHROUGH */
+ case REPLACE_OP:
+ ret=PROTOCOL_BINARY_CMD_REPLACEQ;
+ break;
+ case APPEND_OP:
+ ret=PROTOCOL_BINARY_CMD_APPENDQ;
+ break;
+ case PREPEND_OP:
+ ret=PROTOCOL_BINARY_CMD_PREPENDQ;
+ break;
+ default:
+ WATCHPOINT_ASSERT(verb);
+ break;
+ }
+ else
+ switch (verb)
+ {
+ case SET_OP:
+ ret=PROTOCOL_BINARY_CMD_SET;
+ break;
+ case ADD_OP:
+ ret=PROTOCOL_BINARY_CMD_ADD;
+ break;
+ case CAS_OP: /* FALLTHROUGH */
+ case REPLACE_OP:
+ ret=PROTOCOL_BINARY_CMD_REPLACE;
+ break;
+ case APPEND_OP:
+ ret=PROTOCOL_BINARY_CMD_APPEND;
+ break;
+ case PREPEND_OP:
+ ret=PROTOCOL_BINARY_CMD_PREPEND;
+ break;
+ default:
+ WATCHPOINT_ASSERT(verb);
+ break;
+ }
+
+ return ret;
}
static memcached_return_t memcached_send_binary(memcached_st *ptr,
time_t expiration,
uint32_t flags,
uint64_t cas,
- memcached_storage_action_t verb);
-
-static inline memcached_return_t memcached_send(memcached_st *ptr,
- const char *group_key, size_t group_key_length,
- const char *key, size_t key_length,
- const char *value, size_t value_length,
- time_t expiration,
- uint32_t flags,
- uint64_t cas,
memcached_storage_action_t verb)
{
- bool to_write;
- size_t write_length;
- char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+ bool flush;
+ protocol_binary_request_set request= {};
+ size_t send_length= sizeof(request.bytes);
- WATCHPOINT_ASSERT(!(value == NULL && value_length > 0));
+ bool noreply= server->root->flags.no_reply;
- memcached_return_t rc;
- if (memcached_failed(rc= initialize_query(ptr)))
+ request.message.header.request.magic= PROTOCOL_BINARY_REQ;
+ request.message.header.request.opcode= get_com_code(verb, noreply);
+ request.message.header.request.keylen= htons((uint16_t)(key_length + memcached_array_size(ptr->_namespace)));
+ request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
+ if (verb == APPEND_OP || verb == PREPEND_OP)
+ send_length -= 8; /* append & prepend does not contain extras! */
+ else
{
- return rc;
+ request.message.header.request.extlen= 8;
+ request.message.body.flags= htonl(flags);
+ request.message.body.expiration= htonl((uint32_t)expiration);
}
- if (memcached_failed(rc= memcached_validate_key_length(key_length, ptr->flags.binary_protocol)))
- {
- return rc;
- }
+ request.message.header.request.bodylen= htonl((uint32_t) (key_length + memcached_array_size(ptr->_namespace) + value_length +
+ request.message.header.request.extlen));
- if (memcached_failed(memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
+ if (cas)
+ request.message.header.request.cas= memcached_htonll(cas);
+
+ flush= (bool) ((server->root->flags.buffer_requests && verb == SET_OP) ? 0 : 1);
+
+ if (server->root->flags.use_udp && ! flush)
{
- return MEMCACHED_BAD_KEY_PROVIDED;
- }
+ size_t cmd_size= send_length + key_length + value_length;
- uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
- memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
+ if (cmd_size > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH)
+ {
+ return MEMCACHED_WRITE_FAILURE;
+ }
+ if (cmd_size + server->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
+ {
+ memcached_io_write(server, NULL, 0, true);
+ }
+ }
- WATCHPOINT_SET(instance->io_wait_count.read= 0);
- WATCHPOINT_SET(instance->io_wait_count.write= 0);
+ struct libmemcached_io_vector_st vector[]=
+ {
+ { send_length, request.bytes },
+ { memcached_array_size(ptr->_namespace), memcached_array_string(ptr->_namespace) },
+ { key_length, key },
+ { value_length, value }
+ };
- if (ptr->flags.binary_protocol)
+ /* write the header */
+ memcached_return_t rc;
+ if ((rc= memcached_vdo(server, vector, 4, flush)) != MEMCACHED_SUCCESS)
{
- rc= memcached_send_binary(ptr, instance, server_key,
- key, key_length,
- value, value_length, expiration,
- flags, cas, verb);
- WATCHPOINT_IF_LABELED_NUMBER(instance->io_wait_count.read > 2, "read IO_WAIT", instance->io_wait_count.read);
- WATCHPOINT_IF_LABELED_NUMBER(instance->io_wait_count.write > 2, "write_IO_WAIT", instance->io_wait_count.write);
+ memcached_io_reset(server);
+ return (rc == MEMCACHED_SUCCESS) ? MEMCACHED_WRITE_FAILURE : rc;
}
- else
+
+ if (verb == SET_OP && ptr->number_of_replicas > 0)
{
+ request.message.header.request.opcode= PROTOCOL_BINARY_CMD_SETQ;
+ WATCHPOINT_STRING("replicating");
- if (cas)
+ for (uint32_t x= 0; x < ptr->number_of_replicas; x++)
{
- int check_length;
- check_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
- "%s %.*s%.*s %u %llu %lu %llu%s\r\n",
- storage_op_string(verb),
- memcached_print_array(ptr->_namespace),
- (int)key_length, key, flags,
- (unsigned long long)expiration, (unsigned long)value_length,
- (unsigned long long)cas,
- (ptr->flags.no_reply) ? " noreply" : "");
- if (check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || check_length < 0)
+ memcached_server_write_instance_st instance;
+
+ ++server_key;
+ if (server_key == memcached_server_count(ptr))
+ server_key= 0;
+
+ instance= memcached_server_instance_fetch(ptr, server_key);
+
+ if (memcached_vdo(instance, vector, 4, false) != MEMCACHED_SUCCESS)
{
- rc= memcached_set_error(*instance, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
- memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)"));
memcached_io_reset(instance);
-
- return rc;
}
- write_length= check_length;
- }
- else
- {
- char *buffer_ptr= buffer;
- const char *command= storage_op_string(verb);
-
- /* Copy in the command, no space needed, we handle that in the command function*/
- memcpy(buffer_ptr, command, strlen(command));
-
- /* Copy in the key prefix, switch to the buffer_ptr */
- buffer_ptr= (char *)memcpy((char *)(buffer_ptr + strlen(command)), (char *)memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace));
-
- /* Copy in the key, adjust point if a key prefix was used. */
- buffer_ptr= (char *)memcpy(buffer_ptr + memcached_array_size(ptr->_namespace),
- key, key_length);
- buffer_ptr+= key_length;
- buffer_ptr[0]= ' ';
- buffer_ptr++;
-
- write_length= (size_t)(buffer_ptr - buffer);
- int check_length= snprintf(buffer_ptr, MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer),
- "%u %llu %lu%s\r\n",
- flags,
- (unsigned long long)expiration, (unsigned long)value_length,
- ptr->flags.no_reply ? " noreply" : "");
- if ((size_t)check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE -size_t(buffer_ptr - buffer) || check_length < 0)
+ else
{
- rc= memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
- memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)"));
- memcached_io_reset(instance);
-
- return rc;
+ memcached_server_response_decrement(instance);
}
-
- write_length+= (size_t)check_length;
- WATCHPOINT_ASSERT(write_length < MEMCACHED_DEFAULT_COMMAND_SIZE);
}
+ }
+
+ if (flush == false)
+ {
+ return MEMCACHED_BUFFERED;
+ }
- if (ptr->flags.use_udp && ptr->flags.buffer_requests)
+ if (noreply)
+ {
+ return MEMCACHED_SUCCESS;
+ }
+
+ return memcached_response(server, NULL, 0, NULL);
+}
+
+static memcached_return_t memcached_send_ascii(memcached_st *ptr,
+ memcached_server_write_instance_st instance,
+ const char *key,
+ size_t key_length,
+ const char *value,
+ size_t value_length,
+ time_t expiration,
+ uint32_t flags,
+ uint64_t cas,
+ memcached_storage_action_t verb)
+{
+ bool to_write;
+ size_t write_length;
+ char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+ memcached_return_t rc;
+
+ if (cas)
+ {
+ int check_length;
+ check_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
+ "%s %.*s%.*s %u %llu %lu %llu%s\r\n",
+ storage_op_string(verb),
+ memcached_print_array(ptr->_namespace),
+ (int)key_length, key, flags,
+ (unsigned long long)expiration, (unsigned long)value_length,
+ (unsigned long long)cas,
+ (ptr->flags.no_reply) ? " noreply" : "");
+ if (check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || check_length < 0)
{
- size_t cmd_size= write_length + value_length +2;
- if (cmd_size > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH)
- return memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
+ rc= memcached_set_error(*instance, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
+ memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)"));
+ memcached_io_reset(instance);
- if (cmd_size + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
- memcached_io_write(instance, NULL, 0, true);
+ return rc;
}
+ write_length= check_length;
+ }
+ else
+ {
+ char *buffer_ptr= buffer;
+ const char *command= storage_op_string(verb);
+
+ /* Copy in the command, no space needed, we handle that in the command function*/
+ memcpy(buffer_ptr, command, strlen(command));
+
+ /* Copy in the key prefix, switch to the buffer_ptr */
+ buffer_ptr= (char *)memcpy((char *)(buffer_ptr + strlen(command)), (char *)memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace));
+
+ /* Copy in the key, adjust point if a key prefix was used. */
+ buffer_ptr= (char *)memcpy(buffer_ptr + memcached_array_size(ptr->_namespace),
+ key, key_length);
+ buffer_ptr+= key_length;
+ buffer_ptr[0]= ' ';
+ buffer_ptr++;
+
+ write_length= (size_t)(buffer_ptr - buffer);
+ int check_length= snprintf(buffer_ptr, MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer),
+ "%u %llu %lu%s\r\n",
+ flags,
+ (unsigned long long)expiration, (unsigned long)value_length,
+ ptr->flags.no_reply ? " noreply" : "");
+ if ((size_t)check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE -size_t(buffer_ptr - buffer) || check_length < 0)
+ {
+ rc= memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
+ memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)"));
+ memcached_io_reset(instance);
+
+ return rc;
+ }
+
+ write_length+= (size_t)check_length;
+ WATCHPOINT_ASSERT(write_length < MEMCACHED_DEFAULT_COMMAND_SIZE);
+ }
+
+ if (ptr->flags.use_udp && ptr->flags.buffer_requests)
+ {
+ size_t cmd_size= write_length + value_length +2;
+ if (cmd_size > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH)
+ return memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
+
+ if (cmd_size + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
+ memcached_io_write(instance, NULL, 0, true);
+ }
+
+ if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
+ {
+ rc= memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
+ }
+ else
+ {
+ struct libmemcached_io_vector_st vector[]=
+ {
+ { write_length, buffer },
+ { value_length, value },
+ { 2, "\r\n" }
+ };
- if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
+ if (ptr->flags.buffer_requests && verb == SET_OP)
{
- rc= memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
+ to_write= false;
}
else
{
- struct libmemcached_io_vector_st vector[]=
- {
- { write_length, buffer },
- { value_length, value },
- { 2, "\r\n" }
- };
+ to_write= true;
+ }
- if (ptr->flags.buffer_requests && verb == SET_OP)
+ /* Send command header */
+ rc= memcached_vdo(instance, vector, 3, to_write);
+ if (rc == MEMCACHED_SUCCESS)
+ {
+
+ if (ptr->flags.no_reply)
{
- to_write= false;
+ rc= (to_write == false) ? MEMCACHED_BUFFERED : MEMCACHED_SUCCESS;
}
- else
+ else if (to_write == false)
{
- to_write= true;
+ rc= MEMCACHED_BUFFERED;
}
-
- /* Send command header */
- rc= memcached_vdo(instance, vector, 3, to_write);
- if (rc == MEMCACHED_SUCCESS)
+ else
{
+ rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
- if (ptr->flags.no_reply)
- {
- rc= (to_write == false) ? MEMCACHED_BUFFERED : MEMCACHED_SUCCESS;
- }
- else if (to_write == false)
- {
- rc= MEMCACHED_BUFFERED;
- }
- else
- {
- rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
-
- if (rc == MEMCACHED_STORED)
- rc= MEMCACHED_SUCCESS;
- }
+ if (rc == MEMCACHED_STORED)
+ rc= MEMCACHED_SUCCESS;
}
}
+ }
- if (rc == MEMCACHED_WRITE_FAILURE)
- memcached_io_reset(instance);
+ if (rc == MEMCACHED_WRITE_FAILURE)
+ memcached_io_reset(instance);
+
+ return rc;
+}
+
+static inline memcached_return_t memcached_send(memcached_st *ptr,
+ const char *group_key, size_t group_key_length,
+ const char *key, size_t key_length,
+ const char *value, size_t value_length,
+ time_t expiration,
+ uint32_t flags,
+ uint64_t cas,
+ memcached_storage_action_t verb)
+{
+ WATCHPOINT_ASSERT(!(value == NULL && value_length > 0));
+
+ memcached_return_t rc;
+ if (memcached_failed(rc= initialize_query(ptr)))
+ {
+ return rc;
}
- WATCHPOINT_IF_LABELED_NUMBER(instance->io_wait_count.read > 2, "read IO_WAIT", instance->io_wait_count.read);
- WATCHPOINT_IF_LABELED_NUMBER(instance->io_wait_count.write > 2, "write_IO_WAIT", instance->io_wait_count.write);
+ if (memcached_failed(rc= memcached_validate_key_length(key_length, ptr->flags.binary_protocol)))
+ {
+ return rc;
+ }
+
+ if (memcached_failed(memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
+ {
+ return MEMCACHED_BAD_KEY_PROVIDED;
+ }
+
+ uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
+ memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
+
+ WATCHPOINT_SET(instance->io_wait_count.read= 0);
+ WATCHPOINT_SET(instance->io_wait_count.write= 0);
+
+ if (ptr->flags.binary_protocol)
+ {
+ rc= memcached_send_binary(ptr, instance, server_key,
+ key, key_length,
+ value, value_length, expiration,
+ flags, cas, verb);
+ }
+ else
+ {
+ rc= memcached_send_ascii(ptr, instance,
+ key, key_length,
+ value, value_length, expiration,
+ flags, cas, verb);
+ }
return rc;
}
return rc;
}
-static inline uint8_t get_com_code(memcached_storage_action_t verb, bool noreply)
-{
- /* 0 isn't a value we want, but GCC 4.2 seems to think ret can otherwise
- * be used uninitialized in this function. FAIL */
- uint8_t ret= 0;
-
- if (noreply)
- switch (verb)
- {
- case SET_OP:
- ret=PROTOCOL_BINARY_CMD_SETQ;
- break;
- case ADD_OP:
- ret=PROTOCOL_BINARY_CMD_ADDQ;
- break;
- case CAS_OP: /* FALLTHROUGH */
- case REPLACE_OP:
- ret=PROTOCOL_BINARY_CMD_REPLACEQ;
- break;
- case APPEND_OP:
- ret=PROTOCOL_BINARY_CMD_APPENDQ;
- break;
- case PREPEND_OP:
- ret=PROTOCOL_BINARY_CMD_PREPENDQ;
- break;
- default:
- WATCHPOINT_ASSERT(verb);
- break;
- }
- else
- switch (verb)
- {
- case SET_OP:
- ret=PROTOCOL_BINARY_CMD_SET;
- break;
- case ADD_OP:
- ret=PROTOCOL_BINARY_CMD_ADD;
- break;
- case CAS_OP: /* FALLTHROUGH */
- case REPLACE_OP:
- ret=PROTOCOL_BINARY_CMD_REPLACE;
- break;
- case APPEND_OP:
- ret=PROTOCOL_BINARY_CMD_APPEND;
- break;
- case PREPEND_OP:
- ret=PROTOCOL_BINARY_CMD_PREPEND;
- break;
- default:
- WATCHPOINT_ASSERT(verb);
- break;
- }
-
- return ret;
-}
-
-
-
-static memcached_return_t memcached_send_binary(memcached_st *ptr,
- memcached_server_write_instance_st server,
- uint32_t server_key,
- const char *key,
- size_t key_length,
- const char *value,
- size_t value_length,
- time_t expiration,
- uint32_t flags,
- uint64_t cas,
- memcached_storage_action_t verb)
-{
- bool flush;
- protocol_binary_request_set request= {};
- size_t send_length= sizeof(request.bytes);
-
- bool noreply= server->root->flags.no_reply;
-
- request.message.header.request.magic= PROTOCOL_BINARY_REQ;
- request.message.header.request.opcode= get_com_code(verb, noreply);
- request.message.header.request.keylen= htons((uint16_t)(key_length + memcached_array_size(ptr->_namespace)));
- request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
- if (verb == APPEND_OP || verb == PREPEND_OP)
- send_length -= 8; /* append & prepend does not contain extras! */
- else
- {
- request.message.header.request.extlen= 8;
- request.message.body.flags= htonl(flags);
- request.message.body.expiration= htonl((uint32_t)expiration);
- }
-
- request.message.header.request.bodylen= htonl((uint32_t) (key_length + memcached_array_size(ptr->_namespace) + value_length +
- request.message.header.request.extlen));
-
- if (cas)
- request.message.header.request.cas= memcached_htonll(cas);
-
- flush= (bool) ((server->root->flags.buffer_requests && verb == SET_OP) ? 0 : 1);
-
- if (server->root->flags.use_udp && ! flush)
- {
- size_t cmd_size= send_length + key_length + value_length;
-
- if (cmd_size > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH)
- {
- return MEMCACHED_WRITE_FAILURE;
- }
- if (cmd_size + server->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
- {
- memcached_io_write(server, NULL, 0, true);
- }
- }
-
- struct libmemcached_io_vector_st vector[]=
- {
- { send_length, request.bytes },
- { memcached_array_size(ptr->_namespace), memcached_array_string(ptr->_namespace) },
- { key_length, key },
- { value_length, value }
- };
-
- /* write the header */
- memcached_return_t rc;
- if ((rc= memcached_vdo(server, vector, 4, flush)) != MEMCACHED_SUCCESS)
- {
- memcached_io_reset(server);
- return (rc == MEMCACHED_SUCCESS) ? MEMCACHED_WRITE_FAILURE : rc;
- }
-
- if (verb == SET_OP && ptr->number_of_replicas > 0)
- {
- request.message.header.request.opcode= PROTOCOL_BINARY_CMD_SETQ;
- WATCHPOINT_STRING("replicating");
-
- for (uint32_t x= 0; x < ptr->number_of_replicas; x++)
- {
- memcached_server_write_instance_st instance;
-
- ++server_key;
- if (server_key == memcached_server_count(ptr))
- server_key= 0;
-
- instance= memcached_server_instance_fetch(ptr, server_key);
-
- if (memcached_vdo(instance, vector, 4, false) != MEMCACHED_SUCCESS)
- {
- memcached_io_reset(instance);
- }
- else
- {
- memcached_server_response_decrement(instance);
- }
- }
- }
-
- if (flush == false)
- {
- return MEMCACHED_BUFFERED;
- }
-
- if (noreply)
- {
- return MEMCACHED_SUCCESS;
- }
-
- return memcached_response(server, NULL, 0, NULL);
-}
-
void memcached_string_free(memcached_string_st *ptr)
{
if (not ptr)
+ {
return;
+ }
if (ptr->string)
{
size_t memcached_string_length(const memcached_string_st *self)
{
- return (size_t)(self->end - self->string);
+ return size_t(self->end -self->string);
}
size_t memcached_string_size(const memcached_string_st *self)
} options;
};
-#ifdef BUILDING_LIBMEMCACHED
-
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
-
-#ifdef __cplusplus
-#define memcached_literal_param(X) (X), (static_cast<size_t>((sizeof(X) - 1)))
-#else
-#define memcached_literal_param(X) (X), ((size_t)((sizeof(X) - 1)))
-#endif
-
-#define memcached_string_make_from_cstr(X) (X), ((X) ? strlen(X) : 0)
-
-#endif
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libmcachedd client library.
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#include "util/string.hpp"
+
+#define memcached_literal_param util_literal_param
+#define memcached_literal_param_size util_literal_param_size
+#define memcached_string_make_from_cstr util_string_make_from_cstr
+#define memcached_array_length util_array_length
+
+
# included from Top Level Makefile.am
# All paths should be given relative to the root
-if BUILD_LIBMEMCACHEDUTIL
nobase_include_HEADERS+= \
libmemcached/memcached_util.h \
libmemcached/util.h \
libmemcached/util/pool.h \
libmemcached/util/version.h
lib_LTLIBRARIES+= libmemcached/libmemcachedutil.la
-endif
libmemcached_libmemcachedutil_la_SOURCES= \
libmemcached/backtrace.cc \
${NO_CONVERSION} \
${PTHREAD_CFLAGS} \
-DBUILDING_LIBMEMCACHED
-libmemcached_libmemcachedutil_la_LIBADD= libmemcached/libmemcached.la
-libmemcached_libmemcachedutil_la_LDFLAGS= ${AM_LDFLAGS} ${PTHREAD_LIBS} -version-info ${MEMCACHED_UTIL_LIBRARY_VERSION}
+libmemcached_libmemcachedutil_la_LIBADD= libmemcached/libmemcached.la ${PTHREAD_LIBS}
+libmemcached_libmemcachedutil_la_LDFLAGS= ${AM_LDFLAGS} -version-info ${MEMCACHED_UTIL_LIBRARY_VERSION}
libmemcached_libmemcachedutil_la_DEPENDENCIES= libmemcached/libmemcached.la
* LIBMEMCACHED_LOCAL is used for non-api symbols.
*/
-#if defined(BUILDING_LIBMEMCACHED)
+#if defined(BUILDING_LIBMEMCACHEDINTERNAL)
# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
# define LIBMEMCACHED_API __attribute__ ((visibility("default")))
-# define LIBMEMCACHED_LOCAL __attribute__ ((visibility("hidden")))
+# define LIBMEMCACHED_LOCAL __attribute__ ((visibility("default")))
# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
# define LIBMEMCACHED_API __global
-# define LIBMEMCACHED_LOCAL __hidden
+# define LIBMEMCACHED_LOCAL __global
# elif defined(_MSC_VER)
# define LIBMEMCACHED_API extern __declspec(dllexport)
-# define LIBMEMCACHED_LOCAL
-# else
-# define LIBMEMCACHED_API
-# define LIBMEMCACHED_LOCAL
-# endif /* defined(HAVE_VISIBILITY) */
-#else /* defined(BUILDING_LIBMEMCACHED) */
-# if defined(_MSC_VER)
-# define LIBMEMCACHED_API extern __declspec(dllimport)
-# define LIBMEMCACHED_LOCAL
+# define LIBMEMCACHED_LOCAL extern __declspec(dllexport)
# else
# define LIBMEMCACHED_API
# define LIBMEMCACHED_LOCAL
-# endif /* defined(_MSC_VER) */
-#endif /* defined(BUILDING_LIBMEMCACHED) */
+# endif
+#else
+# if defined(BUILDING_LIBMEMCACHED)
+# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
+# define LIBMEMCACHED_API __attribute__ ((visibility("default")))
+# define LIBMEMCACHED_LOCAL __attribute__ ((visibility("hidden")))
+# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+# define LIBMEMCACHED_API __global
+# define LIBMEMCACHED_LOCAL __hidden
+# elif defined(_MSC_VER)
+# define LIBMEMCACHED_API extern __declspec(dllexport)
+# define LIBMEMCACHED_LOCAL
+# else
+# define LIBMEMCACHED_API
+# define LIBMEMCACHED_LOCAL
+# endif /* defined(HAVE_VISIBILITY) */
+# else /* defined(BUILDING_LIBMEMCACHED) */
+# if defined(_MSC_VER)
+# define LIBMEMCACHED_API extern __declspec(dllimport)
+# define LIBMEMCACHED_LOCAL
+# else
+# define LIBMEMCACHED_API
+# define LIBMEMCACHED_LOCAL
+# endif /* defined(_MSC_VER) */
+# endif /* defined(BUILDING_LIBMEMCACHED) */
+#endif /* defined(BUILDING_LIBMEMCACHEDINTERNAL) */
--- /dev/null
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+# This noinst lib contains things we want to be ABI private but still want to
+# either use in client programs or be able to test in test cases These symbols
+# will not be exposed in the shipped .so
+noinst_LTLIBRARIES+= libmemcachedinternal/libmemcachedinternal.la
+
+libmemcachedinternal_libmemcachedinternal_la_SOURCES= $(libmemcached_libmemcached_la_SOURCES)
+libmemcachedinternal_libmemcachedinternal_la_CFLAGS= \
+ ${AM_CFLAGS} \
+ ${NO_CONVERSION} \
+ -DBUILDING_LIBMEMCACHEDINTERNAL
+libmemcachedinternal_libmemcachedinternal_la_CPPFLAGS= \
+ ${AM_CPPFLAGS} \
+ ${NO_CONVERSION} \
+ -DBUILDING_LIBMEMCACHEDINTERNAL
+libmemcachedinternal_libmemcachedinternal_la_CXXFLAGS= \
+ ${AM_CXXFLAGS} \
+ ${NO_CONVERSION} \
+ -DBUILDING_LIBMEMCACHEDINTERNAL
+libmemcachedinternal_libmemcachedinternal_la_LDFLAGS= ${AM_LDFLAGS}
+libmemcachedinternal_libmemcachedinternal_la_LIBADD= $(libmemcached_libmemcached_la_LIBADD)
+libmemcachedinternal_libmemcachedinternal_la_DEPENDENCIES= $(libmemcached_libmemcached_la_DEPENDENCIES)
--- /dev/null
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+# This noinst lib contains things we want to be ABI private but still want to
+# either use in client programs or be able to test in test cases These symbols
+# will not be exposed in the shipped .so
+noinst_LTLIBRARIES+= libmemcachedinternal/libmemcachedutilinternal.la
+
+libmemcachedinternal_libmemcachedutilinternal_la_SOURCES= $(libmemcached_libmemcachedutil_la_SOURCES)
+libmemcachedinternal_libmemcachedutilinternal_la_CFLAGS= \
+ ${AM_CFLAGS} \
+ ${NO_CONVERSION} \
+ ${PTHREAD_CFLAGS} \
+ -DBUILDING_LIBMEMCACHEDINTERNAL
+libmemcachedinternal_libmemcachedutilinternal_la_CXXFLAGS= \
+ ${AM_CXXFLAGS} \
+ ${NO_CONVERSION} \
+ ${PTHREAD_CFLAGS} \
+ -DBUILDING_LIBMEMCACHEDINTERNAL
+libmemcachedinternal_libmemcachedutilinternal_la_LIBADD= libmemcachedinternal/libmemcachedinternal.la ${PTHREAD_LIBS}
+libmemcachedinternal_libmemcachedutilinternal_la_LDFLAGS= ${AM_LDFLAGS} -version-info ${MEMCACHED_UTIL_LIBRARY_VERSION}
+libmemcachedinternal_libmemcachedutilinternal_la_DEPENDENCIES= libmemcached/libmemcached.la
+
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
/*
Common include file for libmemached
*/
#include <config.h>
-#include <inttypes.h>
-#include <cstdlib>
-#include <sys/types.h>
-
-#include <cerrno>
#include <cassert>
+#include <cerrno>
+#include <cstdlib>
#include <sstream>
#include <string>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif
+
#include <libtest/test.hpp>
libtest/signal.cc \
libtest/test.cc
-libtest_libtest_la_CFLAGS= ${AM_CFLAGS} ${NO_CONVERSION} -DBUILDING_LIBTEST
-libtest_libtest_la_CXXFLAGS= ${AM_CXXFLAGS} ${NO_CONVERSION} -DBUILDING_LIBTEST
+libtest_libtest_la_CFLAGS= ${AM_CFLAGS}
+libtest_libtest_la_CFLAGS+= ${NO_CONVERSION}
+libtest_libtest_la_CFLAGS+= $(PTHREAD_CFLAGS)
+libtest_libtest_la_CFLAGS+= -DBUILDING_LIBTEST
+libtest_libtest_la_CPPFLAGS= ${AM_CPPFLAGS}
+libtest_libtest_la_CPPFLAGS+= ${NO_CONVERSION}
+libtest_libtest_la_CPPFLAGS+= $(PTHREAD_LIBS)
+libtest_libtest_la_CPPFLAGS+= -DBUILDING_LIBTEST
+libtest_libtest_la_CXXFLAGS= ${AM_CXXFLAGS}
+libtest_libtest_la_CXXFLAGS+= ${NO_CONVERSION}
+libtest_libtest_la_CXXFLAGS+= -DBUILDING_LIBTEST
+libtest_libtest_la_CXXFLAGS+= $(PTHREAD_CFLAGS)
libtest_libtest_la_LIBADD=
+libtest_libtest_la_LIBADD+= $(PTHREAD_LIBS)
LIBTEST_LDADD= libtest/libtest.la
if HAVE_LIBMEMCACHED
-if BUILD_LIBMEMCACHEDUTIL
-LIBTEST_LDADD+= libmemcached/libmemcached.la
-LIBTEST_LDADD+= libmemcached/libmemcachedutil.la
-else
-LIBTEST_LDADD+= $(libmemcached_LIBS)
-endif
+libtest_libtest_la_LIBADD+= libmemcached/libmemcached.la
+libtest_libtest_la_LIBADD+= libmemcached/libmemcachedutil.la
libtest_libtest_la_SOURCES+= libtest/memcached.cc
endif
}
arg_buffer << " -l 127.0.0.1 ";
+ arg_buffer << " -m 128 ";
+ arg_buffer << " -M ";
for (int x= 1 ; x < argc ; x++)
{
#include <libtest/memcached.h>
#endif
+extern "C" {
+ static bool exited_successfully(int status)
+ {
+ if (WEXITSTATUS(status) == 0)
+ {
+ return true;
+ }
+
+ return true;
+ }
+}
+
+
namespace libtest {
std::ostream& operator<<(std::ostream& output, const Server &arg)
_running+= " &";
}
- if (system(_running.c_str()) == -1)
+ int ret= system(_running.c_str());
+ if (not exited_successfully(ret))
{
Error << "system() failed:" << strerror(errno);
_running.clear();
bool server_startup(server_startup_st& construct, const std::string& server_type, in_port_t try_port, int argc, const char *argv[])
{
Outn();
+ (void)try_port;
// Look to see if we are being provided ports to use
{
--- /dev/null
+AC_DEFUN([CONFIG_EXTRA], [
+
+AH_BOTTOM([
+
+#if defined(__cplusplus)
+#include CSTDINT_H
+#include CINTTYPES_H
+#else
+#include <stdint.h>
+#include <inttypes.h>
+#endif
+
+#if !defined(HAVE_ULONG) && !defined(__USE_MISC)
+# define HAVE_ULONG 1
+typedef unsigned long int ulong;
+#endif
+
+])
+
+AH_BOTTOM([
+#ifdef WIN32
+#define _WIN32_WINNT 0x0501
+#endif
+
+/* To hide the platform differences between MS Windows and Unix, I am
+ * going to use the Microsoft way and #define the Microsoft-specific
+ * functions to the unix way. Microsoft use a separate subsystem for sockets,
+ * but Unix normally just use a filedescriptor on the same functions. It is
+ * a lot easier to map back to the unix way with macros than going the other
+ * way without side effect ;-)
+ */
+#ifdef WIN32
+#include "win32/wrappers.h"
+#define get_socket_errno() WSAGetLastError()
+#else
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR -1
+#define closesocket(a) close(a)
+#define get_socket_errno() errno
+#endif
+
+#ifndef HAVE_MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+#ifndef HAVE_MSG_DONTWAIT
+#define MSG_DONTWAIT 0
+#endif
+
+#ifndef HAVE_MSG_MORE
+#define MSG_MORE 0
+#endif
+
+])
+])dnl CONFIG_EXTRA
])
])
- AC_CONFIG_MACRO_DIR([m4])
-
- m4_if(m4_substr(m4_esyscmd(test -d src && echo 0),0,1),0,[
- AC_CONFIG_HEADERS([src/config.h])
- ],[
- AC_CONFIG_HEADERS([config.h])
- ])
-
PANDORA_BLOCK_BAD_OPTIONS
# We need to prevent canonical target
AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],
[CXXFLAGS=""])
- AC_CANONICAL_TARGET
-
m4_if(PCT_DONT_SUPRESS_INCLUDE,yes,[
AM_INIT_AUTOMAKE(-Wall -Werror -Wno-portability subdir-objects foreign tar-ustar)
],[
PANDORA_USE_PIPE
- AH_TOP([
-#ifndef __CONFIG_H__
-#define __CONFIG_H__
-
-/* _SYS_FEATURE_TESTS_H is Solaris, _FEATURES_H is GCC */
-#if defined( _SYS_FEATURE_TESTS_H) || defined(_FEATURES_H)
-#error "You should include config.h as your first include file"
-#endif
-
-#include <config/top.h>
-])
- mkdir -p config
- cat > config/top.h.stamp <<EOF_CONFIG_TOP
-
-#if defined(i386) && !defined(__i386__)
-#define __i386__
-#endif
-
-#if defined(_FILE_OFFSET_BITS)
-# undef _FILE_OFFSET_BITS
-#endif
-EOF_CONFIG_TOP
-
- diff config/top.h.stamp config/top.h >/dev/null 2>&1 || mv config/top.h.stamp config/top.h
- rm -f config/top.h.stamp
-
- AH_BOTTOM([
-#if defined(__cplusplus)
-# include CSTDINT_H
-# include CINTTYPES_H
-#else
-# include <stdint.h>
-# include <inttypes.h>
-#endif
-
-#if !defined(HAVE_ULONG) && !defined(__USE_MISC)
-# define HAVE_ULONG 1
-typedef unsigned long int ulong;
-#endif
-
-/* To hide the platform differences between MS Windows and Unix, I am
- * going to use the Microsoft way and #define the Microsoft-specific
- * functions to the unix way. Microsoft use a separate subsystem for sockets,
- * but Unix normally just use a filedescriptor on the same functions. It is
- * a lot easier to map back to the unix way with macros than going the other
- * way without side effect ;-)
- */
-#ifdef TARGET_OS_WINDOWS
-#define random() rand()
-#define srandom(a) srand(a)
-#define get_socket_errno() WSAGetLastError()
-#else
-#define INVALID_SOCKET -1
-#define SOCKET_ERROR -1
-#define closesocket(a) close(a)
-#define get_socket_errno() errno
-#endif
-
-#if defined(__cplusplus)
-# if defined(DEBUG)
-# include <cassert>
-# include <cstddef>
-# endif
-template<typename To, typename From>
-inline To implicit_cast(From const &f) {
- return f;
-}
-template<typename To, typename From> // use like this: down_cast<T*>(foo);
-inline To down_cast(From* f) { // so we only accept pointers
- // Ensures that To is a sub-type of From *. This test is here only
- // for compile-time type checking, and has no overhead in an
- // optimized build at run-time, as it will be optimized away
- // completely.
- if (false) {
- implicit_cast<From*, To>(0);
- }
-
-#if defined(DEBUG)
- assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only!
-#endif
- return static_cast<To>(f);
-}
-#endif /* defined(__cplusplus) */
-
-#endif /* __CONFIG_H__ */
- ])
-
AM_CFLAGS="${AM_CFLAGS} ${CC_WARNINGS} ${CC_PROFILING} ${CC_COVERAGE}"
AM_CXXFLAGS="${AM_CXXFLAGS} ${CXX_WARNINGS} ${CC_PROFILING} ${CC_COVERAGE}"
dnl ---------------------------------------------------------------------------
AC_DEFUN([PANDORA_ENABLE_DTRACE],[
AC_ARG_ENABLE([dtrace],
- [AS_HELP_STRING([--disable-dtrace],
- [Build with support for the DTRACE. @<:@default=on@:>@])],
+ [AS_HELP_STRING([--enable-dtrace],
+ [Build with support for the DTRACE. @<:@default=no@:>@])],
[ac_cv_enable_dtrace="$enableval"],
- [ac_cv_enable_dtrace="yes"])
+ [ac_cv_enable_dtrace="no"])
AS_IF([test "$ac_cv_enable_dtrace" = "yes"],[
AC_CHECK_PROGS([DTRACE], [dtrace])
+++ /dev/null
-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.
-
-dnl Try to define a macro to dump the current callstack.
-AC_DEFUN([PANDORA_PRINT_CALLSTACK],[
- AC_CHECK_HEADERS([ucontext.h])
- AS_IF([test "x$ac_cv_header_ucontext_h" = "xyes"],
- [ AC_CHECK_FUNCS([printstack]) ])
-
-
- AS_IF([ test "x$ac_cv_func_printstack" != "xyes"],
- [ AC_CHECK_HEADERS([dlfcn.h])
- AC_CHECK_HEADERS([execinfo.h])
- AC_CHECK_FUNCS([backtrace])
- AC_CHECK_FUNCS([backtrace_symbols_fd]) ])
-
- AH_BOTTOM([
-#ifdef __cplusplus
-#include <cstdio>
-#define PANDORA_PRINTSTACK_STD_PREFIX std::
-#else
-#include <stdio.h>
-#define PANDORA_PRINTSTACK_STD_PREFIX
-#endif
-
-#if defined(HAVE_UCONTEXT_H) && defined(HAVE_PRINTSTACK)
-#include <ucontext.h>
-#define pandora_print_callstack(a) \
-printstack(PANDORA_PRINTSTACK_STD_PREFIX fileno(a))
-#elif defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS_FD)
-
-#include <execinfo.h>
-
-#define pandora_print_callstack(a) \
-{ \
- void *stack[100]; \
- int depth = backtrace(stack, 100); \
- backtrace_symbols_fd(stack, depth, PANDORA_PRINTSTACK_STD_PREFIX fileno(a)); \
-}
-#elif defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) && !defined(HAVE_BACKTRACE_SYMBOLS_FD)
-
-#include <execinfo.h>
-
-#define pandora_print_callstack(a) \
-{ \
- void *stack[100]; \
- int depth= backtrace(stack, 100); \
- char **symbol= backtrace_symbols(stack, depth); \
- for (int x= 0; x < size; ++x) \
- PANDORA_PRINTSTACK_STD_PREFIX fprintf(a, "%s\n", symbol[x]); \
-}
-#else
-#define pandora_print_callstack(a) \
- PANDORA_PRINTSTACK_STD_PREFIX fprintf(a, \
- "Stackdump not supported for this platform\n");
-#endif
- ])
-
-])
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached C test app
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * @file @brief C dummy test, aka testing C linking, etc
+ */
+
+#include <stdlib.h>
+
+#include <libmemcached/memcached.h>
+
+int main(void)
+{
+ (void)memcached_success(MEMCACHED_SUCCESS);
+ (void)memcached_failed(MEMCACHED_SUCCESS);
+ (void)memcached_continue(MEMCACHED_SUCCESS);
+
+ memcached_st *memc= memcached_create(NULL);
+ memcached_free(memc);
+
+ return EXIT_SUCCESS;
+}
+
TESTS_LDADDS= \
libmemcached/libmemcached.la \
+ libmemcached/libmemcachedutil.la \
libtest/libtest.la
DEBUG_COMMAND= $(LIBTOOL) --mode=execute gdb
PAHOLE_COMMAND= $(LIBTOOL) --mode=execute pahole
-if BUILD_LIBMEMCACHEDUTIL
-TESTS_LDADDS+= libmemcached/libmemcachedutil.la
-endif
-
EXTRA_DIST+= \
tests/cpp_example.cc \
tests/output_plus.res
tests/debug.h \
tests/error_conditions.h \
tests/hash_results.h \
+ tests/ketama.h \
tests/ketama_test_cases.h \
tests/ketama_test_cases_spy.h \
tests/libmemcached_world.h \
# Cycle should always run first
tests_cycle_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
+tests_cycle_CXXFLAGS = $(AM_CXXFLAGS) ${PTHREAD_CFLAGS}
tests_cycle_SOURCES= tests/cycle.cc
tests_cycle_DEPENDENCIES= $(TESTS_LDADDS)
tests_cycle_LDADD= $(tests_cycle_DEPENDENCIES)
+tests_cycle_LDADD+= ${PTHREAD_LIBS}
check_PROGRAMS+= tests/cycle
noinst_PROGRAMS+= tests/cycle
+# Test internals
+tests_internals_SOURCES= tests/internals.cc
+tests_internals_SOURCES+= tests/string.cc
+tests_internals_CXXFLAGS = $(AM_CXXFLAGS) ${PTHREAD_CFLAGS}
+tests_internals_DEPENDENCIES= libmemcachedinternal/libmemcachedinternal.la libtest/libtest.la libmemcachedinternal/libmemcachedutilinternal.la
+tests_internals_LDADD= libmemcachedinternal/libmemcachedinternal.la
+tests_internals_LDADD+= ${PTHREAD_LIBS}
+tests_internals_LDADD+= libmemcachedinternal/libmemcachedutilinternal.la
+tests_internals_LDADD+= libtest/libtest.la
+check_PROGRAMS+= tests/internals
+noinst_PROGRAMS+= tests/internals
+
+tests_testapp_CXXFLAGS = $(AM_CXXFLAGS) ${PTHREAD_CFLAGS}
tests_testapp_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
tests_testapp_SOURCES= \
tests/basic.cc \
tests/debug.cc \
tests/deprecated.cc \
tests/error_conditions.cc \
+ tests/ketama.cc \
tests/mem_functions.cc \
tests/namespace.cc \
tests/parser.cc \
tests/pool.cc \
tests/print.cc \
tests/replication.cc \
- tests/string.cc \
tests/virtual_buckets.cc
tests_testapp_SOURCES+= clients/generator.cc clients/execute.cc
-
tests_testapp_DEPENDENCIES= \
- $(BUILT_SOURCES) \
- $(TESTS_LDADDS) \
+ libmemcached/libmemcached.la \
+ libtest/libtest.la
libhashkit/libhashkit.la \
- libmemcached/libmemcachedinternal.la
-
+ libmemcached/libmemcachedutil.la
tests_testapp_LDADD= \
$(LIBSASL) \
- $(TESTS_LDADDS) \
- libhashkit/libhashkit.la \
- libmemcached/libmemcachedinternal.la
+ ${PTHREAD_LIBS} \
+ libmemcached/libmemcached.la \
+ libmemcached/libmemcachedutil.la \
+ libtest/libtest.la \
+ libhashkit/libhashkit.la
check_PROGRAMS+= tests/testapp
noinst_PROGRAMS+= tests/testapp
tests_memslap_LDADD= $(tests_memslap_DEPENDENCIES)
check_PROGRAMS+= tests/memslap
noinst_PROGRAMS+= tests/memslap
+
+# Test linking with C application
+tests_c_test_SOURCES= tests/c_test.c
+tests_c_test_LDADD= libmemcached/libmemcached.la
+tests_c_test_DEPENDENCIES= libmemcached/libmemcached.la
+check_PROGRAMS+=tests/c_test
+noinst_PROGRAMS+=tests/c_test
test: check
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached internals test
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include <libtest/test.hpp>
+
+using namespace libtest;
+
+#include "tests/string.h"
+
+/*
+ Test cases
+*/
+test_st string_tests[] ={
+ {"string static with null", false, string_static_null },
+ {"string alloc with null", false, string_alloc_null },
+ {"string alloc with 1K", false, string_alloc_with_size },
+ {"string alloc with malloc failure", false, string_alloc_with_size_toobig },
+ {"string append", false, string_alloc_append },
+ {"string append failure (too big)", false, string_alloc_append_toobig },
+ {"string_alloc_append_multiple", false, string_alloc_append_multiple },
+ {0, 0, 0}
+};
+
+
+collection_st collection[] ={
+ {"string", 0, 0, string_tests},
+ {0, 0, 0, 0}
+};
+
+void get_world(Framework *frame)
+{
+ frame->collections= collection;
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include <libtest/test.hpp>
+
+#include <libmemcached/memcached.h>
+#include <libmemcached/server_instance.h>
+#include <libmemcached/continuum.hpp>
+
+#include <tests/ketama.h>
+#include <tests/ketama_test_cases.h>
+
+test_return_t ketama_compatibility_libmemcached(memcached_st *)
+{
+ memcached_st *memc= memcached_create(NULL);
+ test_true(memc);
+
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1));
+
+ test_compare(uint64_t(1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
+
+ test_compare(MEMCACHED_SUCCESS, memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
+ test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA, memcached_behavior_get_distribution(memc));
+
+ memcached_server_st *server_pool= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
+ memcached_server_push(memc, server_pool);
+
+ /* verify that the server list was parsed okay. */
+ test_compare(8U, memcached_server_count(memc));
+ test_strcmp(server_pool[0].hostname, "10.0.1.1");
+ test_compare(in_port_t(11211), server_pool[0].port);
+ test_compare(600U, server_pool[0].weight);
+ test_strcmp(server_pool[2].hostname, "10.0.1.3");
+ test_compare(in_port_t(11211), server_pool[2].port);
+ test_compare(200U, server_pool[2].weight);
+ test_strcmp(server_pool[7].hostname, "10.0.1.8");
+ test_compare(in_port_t(11211), server_pool[7].port);
+ test_compare(100U, server_pool[7].weight);
+
+ /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
+ * us test the boundary wraparound.
+ */
+ test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
+
+ /* verify the standard ketama set. */
+ for (uint32_t x= 0; x < 99; x++)
+ {
+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, server_idx);
+ const char *hostname = memcached_server_name(instance);
+
+ test_strcmp(hostname, ketama_test_cases[x].server);
+ }
+
+ memcached_server_list_free(server_pool);
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t user_supplied_bug18(memcached_st *trash)
+{
+ memcached_return_t rc;
+ uint64_t value;
+ int x;
+ memcached_st *memc;
+
+ (void)trash;
+
+ memc= memcached_create(NULL);
+ test_true(memc);
+
+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
+ test_compare(MEMCACHED_SUCCESS, rc);
+
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
+ test_true(value == 1);
+
+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
+ test_compare(MEMCACHED_SUCCESS, rc);
+
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
+ test_true(value == MEMCACHED_HASH_MD5);
+
+ memcached_server_st *server_pool= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
+ memcached_server_push(memc, server_pool);
+
+ /* verify that the server list was parsed okay. */
+ test_true(memcached_server_count(memc) == 8);
+ test_strcmp(server_pool[0].hostname, "10.0.1.1");
+ test_true(server_pool[0].port == 11211);
+ test_true(server_pool[0].weight == 600);
+ test_strcmp(server_pool[2].hostname, "10.0.1.3");
+ test_true(server_pool[2].port == 11211);
+ test_true(server_pool[2].weight == 200);
+ test_strcmp(server_pool[7].hostname, "10.0.1.8");
+ test_true(server_pool[7].port == 11211);
+ test_true(server_pool[7].weight == 100);
+
+ /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
+ * us test the boundary wraparound.
+ */
+ test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
+
+ /* verify the standard ketama set. */
+ for (x= 0; x < 99; x++)
+ {
+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
+
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, server_idx);
+
+ const char *hostname = memcached_server_name(instance);
+ test_strcmp(hostname, ketama_test_cases[x].server);
+ }
+
+ memcached_server_list_free(server_pool);
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t auto_eject_hosts(memcached_st *trash)
+{
+ (void) trash;
+ memcached_server_instance_st instance;
+
+ memcached_return_t rc;
+ memcached_st *memc= memcached_create(NULL);
+ test_true(memc);
+
+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
+ test_compare(MEMCACHED_SUCCESS, rc);
+
+ uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
+ test_true(value == 1);
+
+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
+ test_compare(MEMCACHED_SUCCESS, rc);
+
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
+ test_true(value == MEMCACHED_HASH_MD5);
+
+ /* server should be removed when in delay */
+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
+ test_compare(MEMCACHED_SUCCESS, rc);
+
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
+ test_true(value == 1);
+
+ memcached_server_st *server_pool;
+ server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
+ memcached_server_push(memc, server_pool);
+
+ /* verify that the server list was parsed okay. */
+ test_true(memcached_server_count(memc) == 8);
+ test_strcmp(server_pool[0].hostname, "10.0.1.1");
+ test_true(server_pool[0].port == 11211);
+ test_true(server_pool[0].weight == 600);
+ test_strcmp(server_pool[2].hostname, "10.0.1.3");
+ test_true(server_pool[2].port == 11211);
+ test_true(server_pool[2].weight == 200);
+ test_strcmp(server_pool[7].hostname, "10.0.1.8");
+ test_true(server_pool[7].port == 11211);
+ test_true(server_pool[7].weight == 100);
+
+ instance= memcached_server_instance_by_position(memc, 2);
+ ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) + 15;
+ memc->ketama.next_distribution_rebuild= time(NULL) - 1;
+
+ /*
+ This would not work if there were only two hosts.
+ */
+ for (size_t x= 0; x < 99; x++)
+ {
+ memcached_autoeject(memc);
+ uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
+ test_true(server_idx != 2);
+ }
+
+ /* and re-added when it's back. */
+ ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) - 1;
+ memc->ketama.next_distribution_rebuild= time(NULL) - 1;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
+ memc->distribution);
+ for (size_t x= 0; x < 99; x++)
+ {
+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
+ // We re-use instance from above.
+ instance=
+ memcached_server_instance_by_position(memc, server_idx);
+ const char *hostname = memcached_server_name(instance);
+ test_strcmp(hostname, ketama_test_cases[x].server);
+ }
+
+ memcached_server_list_free(server_pool);
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t ketama_compatibility_spymemcached(memcached_st *)
+{
+ memcached_st *memc= memcached_create(NULL);
+ test_true(memc);
+
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1));
+
+ test_compare(UINT64_C(1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
+
+ test_compare(MEMCACHED_SUCCESS, memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY));
+ test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY, memcached_behavior_get_distribution(memc));
+
+ memcached_server_st *server_pool= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
+ test_true(server_pool);
+ memcached_server_push(memc, server_pool);
+
+ /* verify that the server list was parsed okay. */
+ test_compare(8U, memcached_server_count(memc));
+ test_strcmp(server_pool[0].hostname, "10.0.1.1");
+ test_compare(in_port_t(11211), server_pool[0].port);
+ test_compare(600U, server_pool[0].weight);
+ test_strcmp(server_pool[2].hostname, "10.0.1.3");
+ test_compare(in_port_t(11211), server_pool[2].port);
+ test_compare(200U, server_pool[2].weight);
+ test_strcmp(server_pool[7].hostname, "10.0.1.8");
+ test_compare(in_port_t(11211), server_pool[7].port);
+ test_compare(100U, server_pool[7].weight);
+
+ /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
+ * us test the boundary wraparound.
+ */
+ test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
+
+ /* verify the standard ketama set. */
+ for (uint32_t x= 0; x < 99; x++)
+ {
+ uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
+
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, server_idx);
+
+ const char *hostname= memcached_server_name(instance);
+
+ test_strcmp(hostname, ketama_test_cases_spy[x].server);
+ }
+
+ memcached_server_list_free(server_pool);
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+test_return_t auto_eject_hosts(memcached_st *);
+test_return_t ketama_compatibility_libmemcached(memcached_st *);
+test_return_t ketama_compatibility_spymemcached(memcached_st *);
+test_return_t user_supplied_bug18(memcached_st *);
* the COPYING file in the parent directory for full text.
*/
-#ifndef TESTS_KETAMA_TEST_CASES_H
-#define TESTS_KETAMA_TEST_CASES_H
+#pragma once
static struct {
const char *key;
};
#include "ketama_test_cases_spy.h"
-
-#endif
* the COPYING file in the parent directory for full text.
*/
-#ifndef TESTS_KETAMA_TEST_CASES_SPY_H
-#define TESTS_KETAMA_TEST_CASES_SPY_H
+#pragma once
static struct {
const char *key;
{ "\\MQ_XNT7L-", 1259349383UL, 1259509450UL, "10.0.1.5" },
{ "VD6D0]ba_\\", 3842502950UL, 3842588691UL, "10.0.1.7" },
};
-#endif
Test cases
*/
-#define BUILDING_LIBMEMCACHED
-// !NEVER use common.h, always use memcached.h in your own apps
-#include <libmemcached/common.h>
+#include <libmemcached/memcached.h>
+#include <libmemcached/is.h>
+#include <libmemcached/server_instance.h>
+
+#include <libhashkit/hashkit.h>
#include <cassert>
+#include <cerrno>
#include <memory>
+#include <pthread.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <libtest/test.hpp>
#include "tests/deprecated.h"
#include "tests/parser.h"
+#include "tests/ketama.h"
#include "tests/pool.h"
#include "tests/namespace.h"
-#include "tests/string.h"
#include "tests/replication.h"
#include "tests/debug.h"
#include "tests/basic.h"
using namespace libtest;
-#ifdef HAVE_LIBMEMCACHEDUTIL
-#include <pthread.h>
-#include "libmemcached/memcached_util.h"
-#endif
+#include <libmemcached/memcached_util.h>
#include "hash_results.h"
return TEST_SUCCESS;
}
-#include "ketama_test_cases.h"
-static test_return_t user_supplied_bug18(memcached_st *trash)
-{
- memcached_return_t rc;
- uint64_t value;
- int x;
- memcached_st *memc;
-
- (void)trash;
-
- memc= memcached_create(NULL);
- test_true(memc);
-
- rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
- test_compare(MEMCACHED_SUCCESS, rc);
-
- value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
- test_true(value == 1);
-
- rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
- test_compare(MEMCACHED_SUCCESS, rc);
-
- value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
- test_true(value == MEMCACHED_HASH_MD5);
-
- memcached_server_st *server_pool= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
- memcached_server_push(memc, server_pool);
-
- /* verify that the server list was parsed okay. */
- test_true(memcached_server_count(memc) == 8);
- test_strcmp(server_pool[0].hostname, "10.0.1.1");
- test_true(server_pool[0].port == 11211);
- test_true(server_pool[0].weight == 600);
- test_strcmp(server_pool[2].hostname, "10.0.1.3");
- test_true(server_pool[2].port == 11211);
- test_true(server_pool[2].weight == 200);
- test_strcmp(server_pool[7].hostname, "10.0.1.8");
- test_true(server_pool[7].port == 11211);
- test_true(server_pool[7].weight == 100);
-
- /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
- * us test the boundary wraparound.
- */
- test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
-
- /* verify the standard ketama set. */
- for (x= 0; x < 99; x++)
- {
- uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
-
- memcached_server_instance_st instance=
- memcached_server_instance_by_position(memc, server_idx);
-
- const char *hostname = memcached_server_name(instance);
- test_strcmp(hostname, ketama_test_cases[x].server);
- }
-
- memcached_server_list_free(server_pool);
- memcached_free(memc);
-
- return TEST_SUCCESS;
-}
-
/* Large mget() of missing keys with binary proto
*
* If many binary quiet commands (such as getq's in an mget) fill the output
return TEST_SUCCESS;
}
-static test_return_t auto_eject_hosts(memcached_st *trash)
-{
- (void) trash;
- memcached_server_instance_st instance;
-
- memcached_return_t rc;
- memcached_st *memc= memcached_create(NULL);
- test_true(memc);
-
- rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
- test_compare(MEMCACHED_SUCCESS, rc);
-
- uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
- test_true(value == 1);
-
- rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
- test_compare(MEMCACHED_SUCCESS, rc);
-
- value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
- test_true(value == MEMCACHED_HASH_MD5);
-
- /* server should be removed when in delay */
- rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
- test_compare(MEMCACHED_SUCCESS, rc);
-
- value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
- test_true(value == 1);
-
- memcached_server_st *server_pool;
- server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
- memcached_server_push(memc, server_pool);
-
- /* verify that the server list was parsed okay. */
- test_true(memcached_server_count(memc) == 8);
- test_strcmp(server_pool[0].hostname, "10.0.1.1");
- test_true(server_pool[0].port == 11211);
- test_true(server_pool[0].weight == 600);
- test_strcmp(server_pool[2].hostname, "10.0.1.3");
- test_true(server_pool[2].port == 11211);
- test_true(server_pool[2].weight == 200);
- test_strcmp(server_pool[7].hostname, "10.0.1.8");
- test_true(server_pool[7].port == 11211);
- test_true(server_pool[7].weight == 100);
-
- instance= memcached_server_instance_by_position(memc, 2);
- ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) + 15;
- memc->ketama.next_distribution_rebuild= time(NULL) - 1;
-
- /*
- This would not work if there were only two hosts.
- */
- for (size_t x= 0; x < 99; x++)
- {
- memcached_autoeject(memc);
- uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
- test_true(server_idx != 2);
- }
-
- /* and re-added when it's back. */
- ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) - 1;
- memc->ketama.next_distribution_rebuild= time(NULL) - 1;
- memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
- memc->distribution);
- for (size_t x= 0; x < 99; x++)
- {
- uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
- // We re-use instance from above.
- instance=
- memcached_server_instance_by_position(memc, server_idx);
- const char *hostname = memcached_server_name(instance);
- test_strcmp(hostname, ketama_test_cases[x].server);
- }
-
- memcached_server_list_free(server_pool);
- memcached_free(memc);
-
- return TEST_SUCCESS;
-}
-
static test_return_t output_ketama_weighted_keys(memcached_st *trash)
{
(void) trash;
{
count++;
if (return_value)
+ {
free(return_value);
+ }
}
}
}
test_compare(MEMCACHED_SUCCESS, rc);
*/
if (rc == MEMCACHED_SUCCESS && return_value)
+ {
free(return_value);
+ }
}
return TEST_SUCCESS;
unsigned int keys_returned;
test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, MEMCACHED_SUCCESS));
test_true(keys_returned > 0);
- test_compare(global_count, keys_returned);
+ test_compare_got(global_count, keys_returned, "Possible false, positive, memcached may have ejected key/value based on memory needs");
}
return TEST_SUCCESS;
return TEST_SUCCESS;
}
-
-static test_return_t ketama_compatibility_libmemcached(memcached_st *)
-{
- memcached_st *memc= memcached_create(NULL);
- test_true(memc);
-
- test_compare(MEMCACHED_SUCCESS,
- memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1));
-
- test_compare(uint64_t(1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
-
- test_compare(MEMCACHED_SUCCESS, memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
- test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA, memcached_behavior_get_distribution(memc));
-
- memcached_server_st *server_pool= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
- memcached_server_push(memc, server_pool);
-
- /* verify that the server list was parsed okay. */
- test_compare(8U, memcached_server_count(memc));
- test_strcmp(server_pool[0].hostname, "10.0.1.1");
- test_compare(in_port_t(11211), server_pool[0].port);
- test_compare(600U, server_pool[0].weight);
- test_strcmp(server_pool[2].hostname, "10.0.1.3");
- test_compare(in_port_t(11211), server_pool[2].port);
- test_compare(200U, server_pool[2].weight);
- test_strcmp(server_pool[7].hostname, "10.0.1.8");
- test_compare(in_port_t(11211), server_pool[7].port);
- test_compare(100U, server_pool[7].weight);
-
- /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
- * us test the boundary wraparound.
- */
- test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
-
- /* verify the standard ketama set. */
- for (uint32_t x= 0; x < 99; x++)
- {
- uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
- memcached_server_instance_st instance=
- memcached_server_instance_by_position(memc, server_idx);
- const char *hostname = memcached_server_name(instance);
-
- test_strcmp(hostname, ketama_test_cases[x].server);
- }
-
- memcached_server_list_free(server_pool);
- memcached_free(memc);
-
- return TEST_SUCCESS;
-}
-
-static test_return_t ketama_compatibility_spymemcached(memcached_st *)
-{
- memcached_st *memc= memcached_create(NULL);
- test_true(memc);
-
- test_compare(MEMCACHED_SUCCESS,
- memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1));
-
- test_compare(UINT64_C(1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
-
- test_compare(MEMCACHED_SUCCESS, memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY));
- test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY, memcached_behavior_get_distribution(memc));
-
- memcached_server_st *server_pool= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
- test_true(server_pool);
- memcached_server_push(memc, server_pool);
-
- /* verify that the server list was parsed okay. */
- test_compare(8U, memcached_server_count(memc));
- test_strcmp(server_pool[0].hostname, "10.0.1.1");
- test_compare(in_port_t(11211), server_pool[0].port);
- test_compare(600U, server_pool[0].weight);
- test_strcmp(server_pool[2].hostname, "10.0.1.3");
- test_compare(in_port_t(11211), server_pool[2].port);
- test_compare(200U, server_pool[2].weight);
- test_strcmp(server_pool[7].hostname, "10.0.1.8");
- test_compare(in_port_t(11211), server_pool[7].port);
- test_compare(100U, server_pool[7].weight);
-
- /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
- * us test the boundary wraparound.
- */
- test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
-
- /* verify the standard ketama set. */
- for (uint32_t x= 0; x < 99; x++)
- {
- uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
-
- memcached_server_instance_st instance=
- memcached_server_instance_by_position(memc, server_idx);
-
- const char *hostname= memcached_server_name(instance);
-
- test_strcmp(hostname, ketama_test_cases_spy[x].server);
- }
-
- memcached_server_list_free(server_pool);
- memcached_free(memc);
-
- return TEST_SUCCESS;
-}
-
static test_return_t regression_bug_434484(memcached_st *memc)
{
test_return_t test_rc;
{
fprintf(stderr, "Iteration #%u: ", it);
- if(error == MEMCACHED_ERRNO)
+ if (error == MEMCACHED_ERRNO)
{
fprintf(stderr, "system error %d from %s: %s\n",
errno, what, strerror(errno));
/* Clean the server before beginning testing */
test_st tests[] ={
- {"util_version", 1, (test_callback_fn*)util_version_test },
- {"flush", 0, (test_callback_fn*)flush_test },
- {"init", 0, (test_callback_fn*)init_test },
- {"allocation", 0, (test_callback_fn*)allocation_test },
- {"server_list_null_test", 0, (test_callback_fn*)server_list_null_test},
- {"server_unsort", 0, (test_callback_fn*)server_unsort_test},
- {"server_sort", 0, (test_callback_fn*)server_sort_test},
- {"server_sort2", 0, (test_callback_fn*)server_sort2_test},
- {"memcached_server_remove", 0, (test_callback_fn*)memcached_server_remove_test},
- {"clone_test", 0, (test_callback_fn*)clone_test },
- {"connection_test", 0, (test_callback_fn*)connection_test},
- {"callback_test", 0, (test_callback_fn*)callback_test},
- {"userdata_test", 0, (test_callback_fn*)userdata_test},
- {"error", 0, (test_callback_fn*)error_test },
- {"set", 0, (test_callback_fn*)set_test },
- {"set2", 0, (test_callback_fn*)set_test2 },
- {"set3", 0, (test_callback_fn*)set_test3 },
- {"dump", 1, (test_callback_fn*)dump_test},
- {"add", 1, (test_callback_fn*)add_test },
- {"memcached_fetch_result(MEMCACHED_NOTFOUND)", 1, (test_callback_fn*)memcached_fetch_result_NOT_FOUND },
- {"replace", 1, (test_callback_fn*)replace_test },
- {"delete", 1, (test_callback_fn*)delete_test },
- {"get", 1, (test_callback_fn*)get_test },
- {"get2", 0, (test_callback_fn*)get_test2 },
- {"get3", 0, (test_callback_fn*)get_test3 },
- {"get4", 0, (test_callback_fn*)get_test4 },
- {"partial mget", 0, (test_callback_fn*)get_test5 },
- {"stats_servername", 0, (test_callback_fn*)stats_servername_test },
- {"increment", 0, (test_callback_fn*)increment_test },
- {"increment_with_initial", 1, (test_callback_fn*)increment_with_initial_test },
- {"decrement", 0, (test_callback_fn*)decrement_test },
- {"decrement_with_initial", 1, (test_callback_fn*)decrement_with_initial_test },
- {"increment_by_key", 0, (test_callback_fn*)increment_by_key_test },
- {"increment_with_initial_by_key", 1, (test_callback_fn*)increment_with_initial_by_key_test },
- {"decrement_by_key", 0, (test_callback_fn*)decrement_by_key_test },
- {"decrement_with_initial_by_key", 1, (test_callback_fn*)decrement_with_initial_by_key_test },
- {"quit", 0, (test_callback_fn*)quit_test },
- {"mget", 1, (test_callback_fn*)mget_test },
- {"mget_result", 1, (test_callback_fn*)mget_result_test },
- {"mget_result_alloc", 1, (test_callback_fn*)mget_result_alloc_test },
- {"mget_result_function", 1, (test_callback_fn*)mget_result_function },
- {"mget_execute", 1, (test_callback_fn*)mget_execute },
- {"mget_end", 0, (test_callback_fn*)mget_end },
- {"get_stats", 0, (test_callback_fn*)get_stats },
- {"add_host_test", 0, (test_callback_fn*)add_host_test },
- {"add_host_test_1", 0, (test_callback_fn*)add_host_test1 },
- {"get_stats_keys", 0, (test_callback_fn*)get_stats_keys },
- {"version_string_test", 0, (test_callback_fn*)version_string_test},
- {"bad_key", 1, (test_callback_fn*)bad_key_test },
- {"memcached_server_cursor", 1, (test_callback_fn*)memcached_server_cursor_test },
- {"read_through", 1, (test_callback_fn*)read_through },
- {"delete_through", 1, (test_callback_fn*)delete_through },
- {"noreply", 1, (test_callback_fn*)noreply_test},
- {"analyzer", 1, (test_callback_fn*)analyzer_test},
- {"connectionpool", 1, (test_callback_fn*)connection_pool_test },
- {"memcached_pool_test", 1, (test_callback_fn*)memcached_pool_test },
- {"test_get_last_disconnect", 1, (test_callback_fn*)test_get_last_disconnect},
- {"verbosity", 1, (test_callback_fn*)test_verbosity},
- {"test_server_failure", 1, (test_callback_fn*)test_server_failure},
- {"cull_servers", 1, (test_callback_fn*)test_cull_servers},
- {"memcached_stat_execute", 1, (test_callback_fn*)memcached_stat_execute_test},
+ {"util_version", true, (test_callback_fn*)util_version_test },
+ {"flush", false, (test_callback_fn*)flush_test },
+ {"init", false, (test_callback_fn*)init_test },
+ {"allocation", false, (test_callback_fn*)allocation_test },
+ {"server_list_null_test", false, (test_callback_fn*)server_list_null_test},
+ {"server_unsort", false, (test_callback_fn*)server_unsort_test},
+ {"server_sort", false, (test_callback_fn*)server_sort_test},
+ {"server_sort2", false, (test_callback_fn*)server_sort2_test},
+ {"memcached_server_remove", false, (test_callback_fn*)memcached_server_remove_test},
+ {"clone_test", false, (test_callback_fn*)clone_test },
+ {"connection_test", false, (test_callback_fn*)connection_test},
+ {"callback_test", false, (test_callback_fn*)callback_test},
+ {"userdata_test", false, (test_callback_fn*)userdata_test},
+ {"error", false, (test_callback_fn*)error_test },
+ {"set", false, (test_callback_fn*)set_test },
+ {"set2", false, (test_callback_fn*)set_test2 },
+ {"set3", false, (test_callback_fn*)set_test3 },
+ {"dump", true, (test_callback_fn*)dump_test},
+ {"add", true, (test_callback_fn*)add_test },
+ {"memcached_fetch_result(MEMCACHED_NOTFOUND)", true, (test_callback_fn*)memcached_fetch_result_NOT_FOUND },
+ {"replace", true, (test_callback_fn*)replace_test },
+ {"delete", true, (test_callback_fn*)delete_test },
+ {"get", true, (test_callback_fn*)get_test },
+ {"get2", false, (test_callback_fn*)get_test2 },
+ {"get3", false, (test_callback_fn*)get_test3 },
+ {"get4", false, (test_callback_fn*)get_test4 },
+ {"partial mget", false, (test_callback_fn*)get_test5 },
+ {"stats_servername", false, (test_callback_fn*)stats_servername_test },
+ {"increment", false, (test_callback_fn*)increment_test },
+ {"increment_with_initial", true, (test_callback_fn*)increment_with_initial_test },
+ {"decrement", false, (test_callback_fn*)decrement_test },
+ {"decrement_with_initial", true, (test_callback_fn*)decrement_with_initial_test },
+ {"increment_by_key", false, (test_callback_fn*)increment_by_key_test },
+ {"increment_with_initial_by_key", true, (test_callback_fn*)increment_with_initial_by_key_test },
+ {"decrement_by_key", false, (test_callback_fn*)decrement_by_key_test },
+ {"decrement_with_initial_by_key", true, (test_callback_fn*)decrement_with_initial_by_key_test },
+ {"quit", false, (test_callback_fn*)quit_test },
+ {"mget", true, (test_callback_fn*)mget_test },
+ {"mget_result", true, (test_callback_fn*)mget_result_test },
+ {"mget_result_alloc", true, (test_callback_fn*)mget_result_alloc_test },
+ {"mget_result_function", true, (test_callback_fn*)mget_result_function },
+ {"mget_execute", true, (test_callback_fn*)mget_execute },
+ {"mget_end", false, (test_callback_fn*)mget_end },
+ {"get_stats", false, (test_callback_fn*)get_stats },
+ {"add_host_test", false, (test_callback_fn*)add_host_test },
+ {"add_host_test_1", false, (test_callback_fn*)add_host_test1 },
+ {"get_stats_keys", false, (test_callback_fn*)get_stats_keys },
+ {"version_string_test", false, (test_callback_fn*)version_string_test},
+ {"bad_key", true, (test_callback_fn*)bad_key_test },
+ {"memcached_server_cursor", true, (test_callback_fn*)memcached_server_cursor_test },
+ {"read_through", true, (test_callback_fn*)read_through },
+ {"delete_through", true, (test_callback_fn*)delete_through },
+ {"noreply", true, (test_callback_fn*)noreply_test},
+ {"analyzer", true, (test_callback_fn*)analyzer_test},
+ {"connectionpool", true, (test_callback_fn*)connection_pool_test },
+ {"memcached_pool_test", true, (test_callback_fn*)memcached_pool_test },
+ {"test_get_last_disconnect", true, (test_callback_fn*)test_get_last_disconnect},
+ {"verbosity", true, (test_callback_fn*)test_verbosity},
+ {"test_server_failure", true, (test_callback_fn*)test_server_failure},
+ {"cull_servers", true, (test_callback_fn*)test_cull_servers},
+ {"memcached_stat_execute", true, (test_callback_fn*)memcached_stat_execute_test},
{0, 0, 0}
};
test_st behavior_tests[] ={
- {"libmemcached_string_behavior()", 0, (test_callback_fn*)libmemcached_string_behavior_test},
- {"libmemcached_string_distribution()", 0, (test_callback_fn*)libmemcached_string_distribution_test},
- {"behavior_test", 0, (test_callback_fn*)behavior_test},
- {"MEMCACHED_BEHAVIOR_CORK", 0, (test_callback_fn*)MEMCACHED_BEHAVIOR_CORK_test},
- {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", 0, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
- {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", 0, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
+ {"libmemcached_string_behavior()", false, (test_callback_fn*)libmemcached_string_behavior_test},
+ {"libmemcached_string_distribution()", false, (test_callback_fn*)libmemcached_string_distribution_test},
+ {"behavior_test", false, (test_callback_fn*)behavior_test},
+ {"MEMCACHED_BEHAVIOR_CORK", false, (test_callback_fn*)MEMCACHED_BEHAVIOR_CORK_test},
+ {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", false, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
+ {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", false, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
{0, 0, 0}
};
test_st libmemcachedutil_tests[] ={
- {"libmemcached_util_ping()", 1, (test_callback_fn*)ping_test },
- {"libmemcached_util_getpid()", 1, (test_callback_fn*)getpid_test },
- {"libmemcached_util_getpid(MEMCACHED_CONNECTION_FAILURE)", 1, (test_callback_fn*)getpid_connection_failure_test },
+ {"libmemcached_util_ping()", true, (test_callback_fn*)ping_test },
+ {"libmemcached_util_getpid()", true, (test_callback_fn*)getpid_test },
+ {"libmemcached_util_getpid(MEMCACHED_CONNECTION_FAILURE)", true, (test_callback_fn*)getpid_connection_failure_test },
{0, 0, 0}
};
test_st basic_tests[] ={
- {"init", 1, (test_callback_fn*)basic_init_test},
- {"clone", 1, (test_callback_fn*)basic_clone_test},
- {"reset", 1, (test_callback_fn*)basic_reset_stack_test},
- {"reset heap", 1, (test_callback_fn*)basic_reset_heap_test},
- {"reset stack clone", 1, (test_callback_fn*)basic_reset_stack_clone_test},
- {"reset heap clone", 1, (test_callback_fn*)basic_reset_heap_clone_test},
+ {"init", true, (test_callback_fn*)basic_init_test},
+ {"clone", true, (test_callback_fn*)basic_clone_test},
+ {"reset", true, (test_callback_fn*)basic_reset_stack_test},
+ {"reset heap", true, (test_callback_fn*)basic_reset_heap_test},
+ {"reset stack clone", true, (test_callback_fn*)basic_reset_stack_clone_test},
+ {"reset heap clone", true, (test_callback_fn*)basic_reset_heap_clone_test},
{0, 0, 0}
};
test_st regression_binary_vs_block[] ={
- {"block add", 1, (test_callback_fn*)block_add_regression},
- {"binary add", 1, (test_callback_fn*)binary_add_regression},
+ {"block add", true, (test_callback_fn*)block_add_regression},
+ {"binary add", true, (test_callback_fn*)binary_add_regression},
{0, 0, 0}
};
test_st async_tests[] ={
- {"add", 1, (test_callback_fn*)add_wrapper },
+ {"add", true, (test_callback_fn*)add_wrapper },
{0, 0, 0}
};
-test_st string_tests[] ={
- {"string static with null", 0, (test_callback_fn*)string_static_null },
- {"string alloc with null", 0, (test_callback_fn*)string_alloc_null },
- {"string alloc with 1K", 0, (test_callback_fn*)string_alloc_with_size },
- {"string alloc with malloc failure", 0, (test_callback_fn*)string_alloc_with_size_toobig },
- {"string append", 0, (test_callback_fn*)string_alloc_append },
- {"string append failure (too big)", 0, (test_callback_fn*)string_alloc_append_toobig },
- {"string_alloc_append_multiple", 0, (test_callback_fn*)string_alloc_append_multiple },
- {0, 0, (test_callback_fn*)0}
-};
-
test_st memcached_server_get_last_disconnect_tests[] ={
- {"memcached_server_get_last_disconnect()", 0, (test_callback_fn*)test_multiple_get_last_disconnect},
+ {"memcached_server_get_last_disconnect()", false, (test_callback_fn*)test_multiple_get_last_disconnect},
{0, 0, (test_callback_fn*)0}
};
test_st result_tests[] ={
- {"result static", 0, (test_callback_fn*)result_static},
- {"result alloc", 0, (test_callback_fn*)result_alloc},
+ {"result static", false, (test_callback_fn*)result_static},
+ {"result alloc", false, (test_callback_fn*)result_alloc},
{0, 0, (test_callback_fn*)0}
};
test_st version_1_2_3[] ={
- {"append", 0, (test_callback_fn*)append_test },
- {"prepend", 0, (test_callback_fn*)prepend_test },
- {"cas", 0, (test_callback_fn*)cas_test },
- {"cas2", 0, (test_callback_fn*)cas2_test },
- {"append_binary", 0, (test_callback_fn*)append_binary_test },
+ {"append", false, (test_callback_fn*)append_test },
+ {"prepend", false, (test_callback_fn*)prepend_test },
+ {"cas", false, (test_callback_fn*)cas_test },
+ {"cas2", false, (test_callback_fn*)cas2_test },
+ {"append_binary", false, (test_callback_fn*)append_binary_test },
{0, 0, (test_callback_fn*)0}
};
test_st haldenbrand_tests[] ={
- {"memcached_set", 0, (test_callback_fn*)user_supplied_bug1 },
- {"memcached_get()", 0, (test_callback_fn*)user_supplied_bug2 },
- {"memcached_mget()", 0, (test_callback_fn*)user_supplied_bug3 },
+ {"memcached_set", false, (test_callback_fn*)user_supplied_bug1 },
+ {"memcached_get()", false, (test_callback_fn*)user_supplied_bug2 },
+ {"memcached_mget()", false, (test_callback_fn*)user_supplied_bug3 },
{0, 0, (test_callback_fn*)0}
};
test_st user_tests[] ={
{"user_supplied_bug4", true, (test_callback_fn*)user_supplied_bug4 },
- {"user_supplied_bug5", 1, (test_callback_fn*)user_supplied_bug5 },
- {"user_supplied_bug6", 1, (test_callback_fn*)user_supplied_bug6 },
- {"user_supplied_bug7", 1, (test_callback_fn*)user_supplied_bug7 },
- {"user_supplied_bug8", 1, (test_callback_fn*)user_supplied_bug8 },
- {"user_supplied_bug9", 1, (test_callback_fn*)user_supplied_bug9 },
- {"user_supplied_bug10", 1, (test_callback_fn*)user_supplied_bug10 },
- {"user_supplied_bug11", 1, (test_callback_fn*)user_supplied_bug11 },
- {"user_supplied_bug12", 1, (test_callback_fn*)user_supplied_bug12 },
- {"user_supplied_bug13", 1, (test_callback_fn*)user_supplied_bug13 },
- {"user_supplied_bug14", 1, (test_callback_fn*)user_supplied_bug14 },
- {"user_supplied_bug15", 1, (test_callback_fn*)user_supplied_bug15 },
- {"user_supplied_bug16", 1, (test_callback_fn*)user_supplied_bug16 },
+ {"user_supplied_bug5", true, (test_callback_fn*)user_supplied_bug5 },
+ {"user_supplied_bug6", true, (test_callback_fn*)user_supplied_bug6 },
+ {"user_supplied_bug7", true, (test_callback_fn*)user_supplied_bug7 },
+ {"user_supplied_bug8", true, (test_callback_fn*)user_supplied_bug8 },
+ {"user_supplied_bug9", true, (test_callback_fn*)user_supplied_bug9 },
+ {"user_supplied_bug10", true, (test_callback_fn*)user_supplied_bug10 },
+ {"user_supplied_bug11", true, (test_callback_fn*)user_supplied_bug11 },
+ {"user_supplied_bug12", true, (test_callback_fn*)user_supplied_bug12 },
+ {"user_supplied_bug13", true, (test_callback_fn*)user_supplied_bug13 },
+ {"user_supplied_bug14", true, (test_callback_fn*)user_supplied_bug14 },
+ {"user_supplied_bug15", true, (test_callback_fn*)user_supplied_bug15 },
+ {"user_supplied_bug16", true, (test_callback_fn*)user_supplied_bug16 },
#if !defined(__sun) && !defined(__OpenBSD__)
/*
** It seems to be something weird with the character sets..
** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
** so just disable the code for now...).
*/
- {"user_supplied_bug17", 1, (test_callback_fn*)user_supplied_bug17 },
+ {"user_supplied_bug17", true, (test_callback_fn*)user_supplied_bug17 },
#endif
- {"user_supplied_bug18", 1, (test_callback_fn*)user_supplied_bug18 },
- {"user_supplied_bug19", 1, (test_callback_fn*)user_supplied_bug19 },
- {"user_supplied_bug20", 1, (test_callback_fn*)user_supplied_bug20 },
- {"user_supplied_bug21", 1, (test_callback_fn*)user_supplied_bug21 },
- {"wrong_failure_counter_test", 1, (test_callback_fn*)wrong_failure_counter_test},
- {"wrong_failure_counter_two_test", 1, (test_callback_fn*)wrong_failure_counter_two_test},
+ {"user_supplied_bug18", true, (test_callback_fn*)user_supplied_bug18 },
+ {"user_supplied_bug19", true, (test_callback_fn*)user_supplied_bug19 },
+ {"user_supplied_bug20", true, (test_callback_fn*)user_supplied_bug20 },
+ {"user_supplied_bug21", true, (test_callback_fn*)user_supplied_bug21 },
+ {"wrong_failure_counter_test", true, (test_callback_fn*)wrong_failure_counter_test},
+ {"wrong_failure_counter_two_test", true, (test_callback_fn*)wrong_failure_counter_two_test},
{0, 0, (test_callback_fn*)0}
};
test_st replication_tests[]= {
- {"set", 1, (test_callback_fn*)replication_set_test },
- {"get", 0, (test_callback_fn*)replication_get_test },
- {"mget", 0, (test_callback_fn*)replication_mget_test },
+ {"set", true, (test_callback_fn*)replication_set_test },
+ {"get", false, (test_callback_fn*)replication_get_test },
+ {"mget", false, (test_callback_fn*)replication_mget_test },
{"delete", true, (test_callback_fn*)replication_delete_test },
- {"rand_mget", 0, (test_callback_fn*)replication_randomize_mget_test },
- {"fail", 0, (test_callback_fn*)replication_randomize_mget_fail_test },
+ {"rand_mget", false, (test_callback_fn*)replication_randomize_mget_test },
+ {"fail", false, (test_callback_fn*)replication_randomize_mget_fail_test },
{0, 0, (test_callback_fn*)0}
};
* http://bugs.launchpad.net/libmemcached
*/
test_st regression_tests[]= {
- {"lp:434484", 1, (test_callback_fn*)regression_bug_434484 },
- {"lp:434843", 1, (test_callback_fn*)regression_bug_434843 },
- {"lp:434843-buffered", 1, (test_callback_fn*)regression_bug_434843_buffered },
- {"lp:421108", 1, (test_callback_fn*)regression_bug_421108 },
- {"lp:442914", 1, (test_callback_fn*)regression_bug_442914 },
- {"lp:447342", 1, (test_callback_fn*)regression_bug_447342 },
- {"lp:463297", 1, (test_callback_fn*)regression_bug_463297 },
- {"lp:490486", 1, (test_callback_fn*)regression_bug_490486 },
- {"lp:583031", 1, (test_callback_fn*)regression_bug_583031 },
- {"lp:?", 1, (test_callback_fn*)regression_bug_ },
- {"lp:728286", 1, (test_callback_fn*)regression_bug_728286 },
- {"lp:581030", 1, (test_callback_fn*)regression_bug_581030 },
- {"lp:71231153 connect()", 1, (test_callback_fn*)regression_bug_71231153_connect },
- {"lp:71231153 poll()", 1, (test_callback_fn*)regression_bug_71231153_poll },
- {"lp:655423", 1, (test_callback_fn*)regression_bug_655423 },
- {"lp:490520", 1, (test_callback_fn*)regression_bug_490520 },
- {0, 0, (test_callback_fn*)0}
+ {"lp:434484", true, (test_callback_fn*)regression_bug_434484 },
+ {"lp:434843", true, (test_callback_fn*)regression_bug_434843 },
+ {"lp:434843-buffered", true, (test_callback_fn*)regression_bug_434843_buffered },
+ {"lp:421108", true, (test_callback_fn*)regression_bug_421108 },
+ {"lp:442914", true, (test_callback_fn*)regression_bug_442914 },
+ {"lp:447342", true, (test_callback_fn*)regression_bug_447342 },
+ {"lp:463297", true, (test_callback_fn*)regression_bug_463297 },
+ {"lp:490486", true, (test_callback_fn*)regression_bug_490486 },
+ {"lp:583031", true, (test_callback_fn*)regression_bug_583031 },
+ {"lp:?", true, (test_callback_fn*)regression_bug_ },
+ {"lp:728286", true, (test_callback_fn*)regression_bug_728286 },
+ {"lp:581030", true, (test_callback_fn*)regression_bug_581030 },
+ {"lp:71231153 connect()", true, (test_callback_fn*)regression_bug_71231153_connect },
+ {"lp:71231153 poll()", true, (test_callback_fn*)regression_bug_71231153_poll },
+ {"lp:655423", true, (test_callback_fn*)regression_bug_655423 },
+ {"lp:490520", true, (test_callback_fn*)regression_bug_490520 },
+ {0, false, (test_callback_fn*)0}
};
test_st sasl_auth_tests[]= {
- {"sasl_auth", 1, (test_callback_fn*)sasl_auth_test },
+ {"sasl_auth", true, (test_callback_fn*)sasl_auth_test },
{0, 0, (test_callback_fn*)0}
};
test_st ketama_compatibility[]= {
- {"libmemcached", 1, (test_callback_fn*)ketama_compatibility_libmemcached },
- {"spymemcached", 1, (test_callback_fn*)ketama_compatibility_spymemcached },
+ {"libmemcached", true, (test_callback_fn*)ketama_compatibility_libmemcached },
+ {"spymemcached", true, (test_callback_fn*)ketama_compatibility_spymemcached },
{0, 0, (test_callback_fn*)0}
};
test_st generate_tests[] ={
- {"generate_pairs", 1, (test_callback_fn*)generate_pairs },
- {"generate_data", 1, (test_callback_fn*)generate_data },
- {"get_read", 0, (test_callback_fn*)get_read },
- {"delete_generate", 0, (test_callback_fn*)delete_generate },
- {"generate_buffer_data", 1, (test_callback_fn*)generate_buffer_data },
- {"delete_buffer", 0, (test_callback_fn*)delete_buffer_generate},
- {"generate_data", 1, (test_callback_fn*)generate_data },
- {"mget_read", 0, (test_callback_fn*)mget_read },
- {"mget_read_result", 0, (test_callback_fn*)mget_read_result },
- {"memcached_fetch_result() use internal result", 0, (test_callback_fn*)mget_read_internal_result },
- {"memcached_fetch_result() partial read", 0, (test_callback_fn*)mget_read_partial_result },
- {"mget_read_function", 0, (test_callback_fn*)mget_read_function },
- {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
- {"generate_large_pairs", 1, (test_callback_fn*)generate_large_pairs },
- {"generate_data", 1, (test_callback_fn*)generate_data },
- {"generate_buffer_data", 1, (test_callback_fn*)generate_buffer_data },
- {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
+ {"generate_pairs", true, (test_callback_fn*)generate_pairs },
+ {"generate_data", true, (test_callback_fn*)generate_data },
+ {"get_read", false, (test_callback_fn*)get_read },
+ {"delete_generate", false, (test_callback_fn*)delete_generate },
+ {"generate_buffer_data", true, (test_callback_fn*)generate_buffer_data },
+ {"delete_buffer", false, (test_callback_fn*)delete_buffer_generate},
+ {"generate_data", true, (test_callback_fn*)generate_data },
+ {"mget_read", false, (test_callback_fn*)mget_read },
+ {"mget_read_result", false, (test_callback_fn*)mget_read_result },
+ {"memcached_fetch_result() use internal result", false, (test_callback_fn*)mget_read_internal_result },
+ {"memcached_fetch_result() partial read", false, (test_callback_fn*)mget_read_partial_result },
+ {"mget_read_function", false, (test_callback_fn*)mget_read_function },
+ {"cleanup", true, (test_callback_fn*)cleanup_pairs },
+ {"generate_large_pairs", true, (test_callback_fn*)generate_large_pairs },
+ {"generate_data", true, (test_callback_fn*)generate_data },
+ {"generate_buffer_data", true, (test_callback_fn*)generate_buffer_data },
+ {"cleanup", true, (test_callback_fn*)cleanup_pairs },
{0, 0, (test_callback_fn*)0}
};
test_st consistent_tests[] ={
- {"generate_pairs", 1, (test_callback_fn*)generate_pairs },
- {"generate_data", 1, (test_callback_fn*)generate_data },
+ {"generate_pairs", true, (test_callback_fn*)generate_pairs },
+ {"generate_data", true, (test_callback_fn*)generate_data },
{"get_read", 0, (test_callback_fn*)get_read_count },
- {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
+ {"cleanup", true, (test_callback_fn*)cleanup_pairs },
{0, 0, (test_callback_fn*)0}
};
test_st consistent_weighted_tests[] ={
- {"generate_pairs", 1, (test_callback_fn*)generate_pairs },
- {"generate_data", 1, (test_callback_fn*)generate_data_with_stats },
- {"get_read", 0, (test_callback_fn*)get_read_count },
- {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
+ {"generate_pairs", true, (test_callback_fn*)generate_pairs },
+ {"generate_data", true, (test_callback_fn*)generate_data_with_stats },
+ {"get_read", false, (test_callback_fn*)get_read_count },
+ {"cleanup", true, (test_callback_fn*)cleanup_pairs },
{0, 0, (test_callback_fn*)0}
};
test_st hsieh_availability[] ={
- {"hsieh_avaibility_test", 0, (test_callback_fn*)hsieh_avaibility_test},
+ {"hsieh_avaibility_test", false, (test_callback_fn*)hsieh_avaibility_test},
{0, 0, (test_callback_fn*)0}
};
test_st murmur_availability[] ={
- {"murmur_avaibility_test", 0, (test_callback_fn*)murmur_avaibility_test},
+ {"murmur_avaibility_test", false, (test_callback_fn*)murmur_avaibility_test},
{0, 0, (test_callback_fn*)0}
};
#endif
test_st ketama_auto_eject_hosts[] ={
- {"auto_eject_hosts", 1, (test_callback_fn*)auto_eject_hosts },
- {"output_ketama_weighted_keys", 1, (test_callback_fn*)output_ketama_weighted_keys },
+ {"auto_eject_hosts", true, (test_callback_fn*)auto_eject_hosts },
+ {"output_ketama_weighted_keys", true, (test_callback_fn*)output_ketama_weighted_keys },
{0, 0, (test_callback_fn*)0}
};
test_st hash_tests[] ={
- {"one_at_a_time_run", 0, (test_callback_fn*)one_at_a_time_run },
- {"md5", 0, (test_callback_fn*)md5_run },
- {"crc", 0, (test_callback_fn*)crc_run },
- {"fnv1_64", 0, (test_callback_fn*)fnv1_64_run },
- {"fnv1a_64", 0, (test_callback_fn*)fnv1a_64_run },
- {"fnv1_32", 0, (test_callback_fn*)fnv1_32_run },
- {"fnv1a_32", 0, (test_callback_fn*)fnv1a_32_run },
- {"hsieh", 0, (test_callback_fn*)hsieh_run },
- {"murmur", 0, (test_callback_fn*)murmur_run },
- {"jenkis", 0, (test_callback_fn*)jenkins_run },
- {"memcached_get_hashkit", 0, (test_callback_fn*)memcached_get_hashkit_test },
+ {"one_at_a_time_run", false, (test_callback_fn*)one_at_a_time_run },
+ {"md5", false, (test_callback_fn*)md5_run },
+ {"crc", false, (test_callback_fn*)crc_run },
+ {"fnv1_64", false, (test_callback_fn*)fnv1_64_run },
+ {"fnv1a_64", false, (test_callback_fn*)fnv1a_64_run },
+ {"fnv1_32", false, (test_callback_fn*)fnv1_32_run },
+ {"fnv1a_32", false, (test_callback_fn*)fnv1a_32_run },
+ {"hsieh", false, (test_callback_fn*)hsieh_run },
+ {"murmur", false, (test_callback_fn*)murmur_run },
+ {"jenkis", false, (test_callback_fn*)jenkins_run },
+ {"memcached_get_hashkit", false, (test_callback_fn*)memcached_get_hashkit_test },
{0, 0, (test_callback_fn*)0}
};
test_st error_conditions[] ={
- {"memcached_get(MEMCACHED_ERRNO)", 0, (test_callback_fn*)memcached_get_MEMCACHED_ERRNO },
- {"memcached_get(MEMCACHED_NOTFOUND)", 0, (test_callback_fn*)memcached_get_MEMCACHED_NOTFOUND },
- {"memcached_get_by_key(MEMCACHED_ERRNO)", 0, (test_callback_fn*)memcached_get_by_key_MEMCACHED_ERRNO },
- {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn*)memcached_get_by_key_MEMCACHED_NOTFOUND },
- {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn*)memcached_get_by_key_MEMCACHED_NOTFOUND },
- {"memcached_increment(MEMCACHED_NO_SERVERS)", 0, (test_callback_fn*)memcached_increment_MEMCACHED_NO_SERVERS },
+ {"memcached_get(MEMCACHED_ERRNO)", false, (test_callback_fn*)memcached_get_MEMCACHED_ERRNO },
+ {"memcached_get(MEMCACHED_NOTFOUND)", false, (test_callback_fn*)memcached_get_MEMCACHED_NOTFOUND },
+ {"memcached_get_by_key(MEMCACHED_ERRNO)", false, (test_callback_fn*)memcached_get_by_key_MEMCACHED_ERRNO },
+ {"memcached_get_by_key(MEMCACHED_NOTFOUND)", false, (test_callback_fn*)memcached_get_by_key_MEMCACHED_NOTFOUND },
+ {"memcached_get_by_key(MEMCACHED_NOTFOUND)", false, (test_callback_fn*)memcached_get_by_key_MEMCACHED_NOTFOUND },
+ {"memcached_increment(MEMCACHED_NO_SERVERS)", false, (test_callback_fn*)memcached_increment_MEMCACHED_NO_SERVERS },
{0, 0, (test_callback_fn*)0}
};
test_st parser_tests[] ={
- {"behavior", 0, (test_callback_fn*)behavior_parser_test },
- {"boolean_options", 0, (test_callback_fn*)parser_boolean_options_test },
- {"configure_file", 0, (test_callback_fn*)memcached_create_with_options_with_filename },
- {"distribtions", 0, (test_callback_fn*)parser_distribution_test },
- {"hash", 0, (test_callback_fn*)parser_hash_test },
- {"libmemcached_check_configuration", 0, (test_callback_fn*)libmemcached_check_configuration_test },
- {"libmemcached_check_configuration_with_filename", 0, (test_callback_fn*)libmemcached_check_configuration_with_filename_test },
- {"number_options", 0, (test_callback_fn*)parser_number_options_test },
- {"randomly generated options", 0, (test_callback_fn*)random_statement_build_test },
- {"namespace", 0, (test_callback_fn*)parser_key_prefix_test },
- {"server", 0, (test_callback_fn*)server_test },
- {"bad server strings", 0, (test_callback_fn*)servers_bad_test },
- {"server with weights", 0, (test_callback_fn*)server_with_weight_test },
- {"parsing servername, port, and weight", 0, (test_callback_fn*)test_hostname_port_weight },
- {"--socket=", 0, (test_callback_fn*)test_parse_socket },
- {"--namespace=", 0, (test_callback_fn*)test_namespace_keyword },
+ {"behavior", false, (test_callback_fn*)behavior_parser_test },
+ {"boolean_options", false, (test_callback_fn*)parser_boolean_options_test },
+ {"configure_file", false, (test_callback_fn*)memcached_create_with_options_with_filename },
+ {"distribtions", false, (test_callback_fn*)parser_distribution_test },
+ {"hash", false, (test_callback_fn*)parser_hash_test },
+ {"libmemcached_check_configuration", false, (test_callback_fn*)libmemcached_check_configuration_test },
+ {"libmemcached_check_configuration_with_filename", false, (test_callback_fn*)libmemcached_check_configuration_with_filename_test },
+ {"number_options", false, (test_callback_fn*)parser_number_options_test },
+ {"randomly generated options", false, (test_callback_fn*)random_statement_build_test },
+ {"namespace", false, (test_callback_fn*)parser_key_prefix_test },
+ {"server", false, (test_callback_fn*)server_test },
+ {"bad server strings", false, (test_callback_fn*)servers_bad_test },
+ {"server with weights", false, (test_callback_fn*)server_with_weight_test },
+ {"parsing servername, port, and weight", false, (test_callback_fn*)test_hostname_port_weight },
+ {"--socket=", false, (test_callback_fn*)test_parse_socket },
+ {"--namespace=", false, (test_callback_fn*)test_namespace_keyword },
{0, 0, (test_callback_fn*)0}
};
test_st virtual_bucket_tests[] ={
- {"basic", 0, (test_callback_fn*)virtual_back_map },
+ {"basic", false, (test_callback_fn*)virtual_back_map },
{0, 0, (test_callback_fn*)0}
};
{"sasl_auth", (test_callback_fn*)pre_sasl, 0, sasl_auth_tests },
{"sasl", (test_callback_fn*)pre_sasl, 0, tests },
{"version_1_2_3", (test_callback_fn*)check_for_1_2_3, 0, version_1_2_3},
- {"string", 0, 0, string_tests},
{"result", 0, 0, result_tests},
{"async", (test_callback_fn*)pre_nonblock, 0, async_tests},
{"async(BINARY)", (test_callback_fn*)pre_nonblock_binary, 0, async_tests},
memcached_st *memc_ptr;
memc_ptr= memcached(test_literal_param("--CONFIGURE-FILE=\"support/example.cnf\""));
test_true_got(memc_ptr, "memcached() failed");
- test_strcmp(SUPPORT_EXAMPLE_CNF, memcached_array_string(memc_ptr->configure.filename));
memcached_free(memc_ptr);
return TEST_SUCCESS;
// We let libmemcached/common.h define config since we are looking at
// library internals.
-#define BUILDING_LIBMEMCACHED
+#include <config.h>
-#include <libmemcached/common.h>
+#include <libmemcached/memcached.h>
+#include <libmemcached/is.h>
#include <libtest/test.hpp>
-#include <libmemcached/error.h>
#include <tests/string.h>
-test_return_t string_static_null(memcached_st *memc)
+test_return_t string_static_null(void*)
{
+ memcached_st *memc= memcached_create(NULL);
memcached_string_st string;
- memcached_string_st *string_ptr;
- string_ptr= memcached_string_create(memc, &string, 0);
- test_true(string.options.is_initialized == true);
+ memcached_string_st *string_ptr= memcached_string_create(memc, &string, 0);
+ test_true(string.options.is_initialized);
test_true(string_ptr);
/* The following two better be the same! */
- test_true(memcached_is_allocated(string_ptr) == false);
- test_true(memcached_is_allocated(&string) == false);
+ test_false(memcached_is_allocated(string_ptr));
+ test_false(memcached_is_allocated(&string));
test_true(&string == string_ptr);
- test_true(string.options.is_initialized == true);
- test_true(memcached_is_initialized(&string) == true);
+ test_true(string.options.is_initialized);
+ test_true(memcached_is_initialized(&string));
memcached_string_free(&string);
- test_true(memcached_is_initialized(&string) == false);
+ test_false(memcached_is_initialized(&string));
+
+ memcached_free(memc);
return TEST_SUCCESS;
}
-test_return_t string_alloc_null(memcached_st *memc)
+test_return_t string_alloc_null(void*)
{
- memcached_string_st *string;
+ memcached_st *memc= memcached_create(NULL);
- string= memcached_string_create(memc, NULL, 0);
+ memcached_string_st *string= memcached_string_create(memc, NULL, 0);
test_true(string);
- test_true(memcached_is_allocated(string) == true);
- test_true(memcached_is_initialized(string) == true);
+ test_true(memcached_is_allocated(string));
+ test_true(memcached_is_initialized(string));
memcached_string_free(string);
+ memcached_free(memc);
+
return TEST_SUCCESS;
}
-test_return_t string_alloc_with_size(memcached_st *memc)
+test_return_t string_alloc_with_size(void*)
{
- memcached_string_st *string;
-
- string= memcached_string_create(memc, NULL, 1024);
+ memcached_st *memc= memcached_create(NULL);
+ memcached_string_st *string= memcached_string_create(memc, NULL, 1024);
test_true(string);
- test_true(memcached_is_allocated(string) == true);
- test_true(memcached_is_initialized(string) == true);
+ test_true(memcached_is_allocated(string));
+ test_true(memcached_is_initialized(string));
memcached_string_free(string);
+ memcached_free(memc);
+
return TEST_SUCCESS;
}
-test_return_t string_alloc_with_size_toobig(memcached_st *memc)
+test_return_t string_alloc_with_size_toobig(void*)
{
- memcached_string_st *string;
-
- string= memcached_string_create(memc, NULL, SIZE_MAX);
- test_true(string == NULL);
+ memcached_st *memc= memcached_create(NULL);
+ memcached_string_st *string= memcached_string_create(memc, NULL, SIZE_MAX);
+ test_zero(string);
+ memcached_free(memc);
return TEST_SUCCESS;
}
-test_return_t string_alloc_append(memcached_st *memc)
+test_return_t string_alloc_append(void*)
{
- unsigned int x;
- char buffer[SMALL_STRING_LEN];
+ memcached_st *memc= memcached_create(NULL);
+
+ char buffer[BUFSIZ];
memcached_string_st *string;
/* Ring the bell! */
- memset(buffer, 6, SMALL_STRING_LEN);
+ memset(buffer, 6, BUFSIZ);
string= memcached_string_create(memc, NULL, 100);
test_true(string);
- test_true(memcached_is_allocated(string) == true);
- test_true(memcached_is_initialized(string) == true);
+ test_true(memcached_is_allocated(string));
+ test_true(memcached_is_initialized(string));
- for (x= 0; x < 1024; x++)
+ for (unsigned int x= 0; x < 1024; x++)
{
memcached_return_t rc;
- rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
+ rc= memcached_string_append(string, buffer, BUFSIZ);
test_true(rc == MEMCACHED_SUCCESS);
}
- test_true(memcached_is_allocated(string) == true);
+ test_true(memcached_is_allocated(string));
memcached_string_free(string);
+ memcached_free(memc);
+
return TEST_SUCCESS;
}
-test_return_t string_alloc_append_toobig(memcached_st *memc)
+test_return_t string_alloc_append_toobig(void*)
{
+ memcached_st *memc= memcached_create(NULL);
+
memcached_return_t rc;
- char buffer[SMALL_STRING_LEN];
+ char buffer[BUFSIZ];
memcached_string_st *string;
/* Ring the bell! */
string= memcached_string_create(memc, NULL, 100);
test_true(string);
- test_true(memcached_is_allocated(string) == true);
- test_true(memcached_is_initialized(string) == true);
+ test_true(memcached_is_allocated(string));
+ test_true(memcached_is_initialized(string));
for (unsigned int x= 0; x < 1024; x++)
{
- rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
+ rc= memcached_string_append(string, buffer, BUFSIZ);
test_true(rc == MEMCACHED_SUCCESS);
}
rc= memcached_string_append(string, buffer, SIZE_MAX);
test_true(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
- test_true(memcached_is_allocated(string) == true);
+ test_true(memcached_is_allocated(string));
memcached_string_free(string);
+ memcached_free(memc);
+
return TEST_SUCCESS;
}
-test_return_t string_alloc_append_multiple(memcached_st *memc)
+test_return_t string_alloc_append_multiple(void*)
{
+ memcached_st *memc= memcached_create(NULL);
+
memcached_string_st *error_string= memcached_string_create(memc, NULL, 1024);
- memcached_string_append(error_string, memcached_literal_param("Error occured while parsing: "));
- memcached_string_append(error_string, memcached_string_make_from_cstr("jog the strlen() method"));
- memcached_string_append(error_string, memcached_literal_param(" ("));
+ memcached_string_append(error_string, test_literal_param("Error occured while parsing: "));
+ memcached_string_append(error_string, test_string_make_from_cstr("jog the strlen() method"));
+ memcached_string_append(error_string, test_literal_param(" ("));
- memcached_string_append(error_string, memcached_string_make_from_cstr(memcached_strerror(NULL, MEMCACHED_SUCCESS)));
- memcached_string_append(error_string, memcached_literal_param(")"));
+ memcached_string_append(error_string, test_string_make_from_cstr(memcached_strerror(NULL, MEMCACHED_SUCCESS)));
+ memcached_string_append(error_string, test_literal_param(")"));
memcached_string_free(error_string);
+ memcached_free(memc);
+
return TEST_SUCCESS;
}
#endif
LIBTEST_INTERNAL_API
-test_return_t string_static_null(memcached_st *memc);
+test_return_t string_static_null(void *);
LIBTEST_INTERNAL_API
-test_return_t string_alloc_null(memcached_st *memc);
+test_return_t string_alloc_null(void *);
LIBTEST_INTERNAL_API
-test_return_t string_alloc_with_size(memcached_st *memc);
+test_return_t string_alloc_with_size(void *);
LIBTEST_INTERNAL_API
-test_return_t string_alloc_with_size_toobig(memcached_st *memc);
+test_return_t string_alloc_with_size_toobig(void *);
LIBTEST_INTERNAL_API
-test_return_t string_alloc_append(memcached_st *memc);
+test_return_t string_alloc_append(void *);
LIBTEST_INTERNAL_API
-test_return_t string_alloc_append_toobig(memcached_st *memc);
+test_return_t string_alloc_append_toobig(void *);
LIBTEST_INTERNAL_API
-test_return_t string_alloc_append_multiple(memcached_st *memc);
+test_return_t string_alloc_append_multiple(void *);
#ifdef __cplusplus
}
#include <cstdio>
#include <sstream>
+#include <iostream>
#include <netdb.h>
#include <poll.h>
#include <sys/socket.h>
#include <cassert>
#include <cstddef>
#include <sys/socket.h>
+#include <string>
#include "util/operation.hpp"
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * DataDifferential Utility Library
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include <config.h>
+
+#include "util/operation.hpp"
+#include <string>
+
+namespace datadifferential {
+namespace util {
+
+bool Operation::response(std::string &arg)
+{
+ if (_response.empty())
+ return false;
+
+ if (not memcmp("OK\r\n", &_response[0], 3))
+ { }
+ else if (not memcmp("OK ", &_response[0], 3))
+ {
+ arg.append(&_response[3], _response.size() -3);
+ }
+ else if (not memcmp("ERR ", &_response[0], 4))
+ {
+ arg.append(&_response[4], _response.size() -4);
+ return false;
+ }
+ else
+ {
+ arg.append(&_response[0], _response.size());
+ }
+
+ return true;
+}
+
+} /* namespace util */
+} /* namespace datadifferential */
#include <cstring>
-#include <iostream>
+#include <iosfwd>
#include <vector>
namespace datadifferential {
}
// Return false on error
- bool response(std::string &arg)
- {
- if (_response.empty())
- return false;
-
- if (not memcmp("OK\r\n", &_response[0], 3))
- { }
- else if (not memcmp("OK ", &_response[0], 3))
- {
- arg.append(&_response[3], _response.size() -3);
- }
- else if (not memcmp("ERR ", &_response[0], 4))
- {
- arg.append(&_response[4], _response.size() -4);
- return false;
- }
- else
- {
- arg.append(&_response[0], _response.size());
- }
-
- return true;
- }
+ bool response(std::string &);
bool reconnect() const
{