Merge in autoconf/libtest updates.
authorBrian Aker <brian@tangent.org>
Thu, 4 Aug 2011 17:55:33 +0000 (10:55 -0700)
committerBrian Aker <brian@tangent.org>
Thu, 4 Aug 2011 17:55:33 +0000 (10:55 -0700)
62 files changed:
.bzrignore
Makefile.am
clients/include.am
clients/memcapable.cc
clients/memparse.cc
config/autorun.sh
configure.ac
example/byteorder.cc [new file with mode: 0644]
example/byteorder.h [new file with mode: 0644]
example/include.am
example/interface_v0.c
example/interface_v1.c
example/memcached_light.c
libhashkit/fnv.cc
libhashkit/include.am
libmemcached/byteorder.cc
libmemcached/common.h
libmemcached/connect.cc
libmemcached/constants.h
libmemcached/continuum.hpp [new file with mode: 0644]
libmemcached/delete.cc
libmemcached/error.cc
libmemcached/fetch.cc
libmemcached/include.am
libmemcached/io.cc
libmemcached/io.h
libmemcached/io.hpp [new file with mode: 0644]
libmemcached/response.cc
libmemcached/return.h
libmemcached/server.cc
libmemcached/server_instance.h [new file with mode: 0644]
libmemcached/storage.cc
libmemcached/string.cc
libmemcached/string.h
libmemcached/string.hpp [new file with mode: 0644]
libmemcached/util/include.am
libmemcached/visibility.h
libmemcachedinternal/include.am [new file with mode: 0644]
libmemcachedinternal/util/include.am [new file with mode: 0644]
libtest/common.h
libtest/include.am
libtest/memcached.cc
libtest/server.cc
m4/bottom.m4 [new file with mode: 0644]
m4/pandora_canonical.m4
m4/pandora_enable_dtrace.m4
m4/pandora_print_callstack.m4 [deleted file]
tests/c_test.c [new file with mode: 0644]
tests/include.am
tests/internals.cc [new file with mode: 0644]
tests/ketama.cc [new file with mode: 0644]
tests/ketama.h [new file with mode: 0644]
tests/ketama_test_cases.h
tests/ketama_test_cases_spy.h
tests/mem_functions.cc
tests/parser.cc
tests/string.cc
tests/string.h
util/instance.cc
util/instance.hpp
util/operation.cc [new file with mode: 0644]
util/operation.hpp

index e1a61fbc39865624cc530de6bae7e780553caff5..27188105add92a99d80639159408d9a887f878bf 100644 (file)
@@ -2,10 +2,14 @@
 *.OTHER
 *.THIS
 *.exe
+*.gz
 *.lo
+*.orig
 *.output
 *.pop
+*.rej
 *.rpm
+*.tar
 */*.l[oa]
 */*/*.l[oa]
 */*/.deps
@@ -19,8 +23,8 @@
 *TAGS
 .deps
 .hg/
-.hgsub
 .hgignore
+.hgsub
 .hgsubstate
 INSTALL
 Makefile
@@ -28,6 +32,7 @@ Makefile.in
 TAGS
 aclocal.m4
 autom4te.cache
+autoscan.log
 clients/memaslap
 clients/memcapable
 clients/memcat
@@ -41,6 +46,7 @@ clients/memslap
 clients/memstat
 config.h
 config.h.in
+config.in
 config.log
 config.status
 config/compile
@@ -54,6 +60,7 @@ config/pandora_vc_revinfo
 config/plugin.ac
 config/top.h
 configure
+configure.scan
 docs/*.[13]
 docs/*.html
 docs/changes
@@ -66,13 +73,6 @@ docs/man/*
 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
@@ -88,6 +88,12 @@ ltoptions.m4
 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
@@ -98,10 +104,14 @@ support/libmemcached.pc
 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
@@ -110,7 +120,3 @@ tests/testplus
 tests/testudp
 tests/var/
 unittests/unittests
-out
-*.orig
-tests/memcapable
-tests/memslap
index b47dfc827666bad98a2782c0e2b78c2805a1455c..5b600d5a6c24b565ee7091c2e32d11b0baa3db76 100644 (file)
@@ -33,19 +33,23 @@ EXTRA_DIST= \
            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
 
index 281aa0b92060dee3909454cafc0f6b48d9776ea6..98511366033a56f474dca4efdaddc7d4430381d0 100644 (file)
@@ -74,6 +74,7 @@ clients_memerror_LDADD= $(CLIENTS_LDADDS)
 
 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= \
index 99ca5ea77c30cda16e953e6caa8a24a05ae1a9a9..9dff427eb3c2c9c88e8c5463569aa895ca8d65d6 100644 (file)
 /* -*- 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
index 4576b7a046fdfc9ecf5aa7f4764e69743e7ab521..f9a2dcf2f5b97cfd1464fc55d386ad904bd94dda 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <config.h>
 
+#include <cstdio>
 #include <iostream>
 
 #include <libmemcached/memcached.h>
index ae57443adca04ce117e0617cb694b4eee068ebd4..3b076d1a12c71eba41bb1e392c1d56f1ed53092f 100755 (executable)
@@ -1,126 +1,2 @@
 #!/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
index bb512954dd1aa967b8e1ccd5065b03c74e12cd2e..153fdb1f9b4c3351e97d9a2823365b86d635b5da 100644 (file)
@@ -7,12 +7,25 @@
 # 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'], [:])
@@ -42,72 +55,11 @@ AC_SUBST(HASHKIT_LIBRARY_VERSION)
 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=
@@ -115,6 +67,7 @@ PANDORA_REQUIRE_PTHREAD
 LIBS="$my_saved_libs"
 
 dnl Specialty checks
+CONFIG_EXTRA
 DETECT_BYTEORDER
 ENABLE_UTILLIB
 SETSOCKOPT_SANITY
@@ -129,6 +82,52 @@ PANDORA_PRINT_CALLSTACK
 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"])
diff --git a/example/byteorder.cc b/example/byteorder.cc
new file mode 100644 (file)
index 0000000..5b25624
--- /dev/null
@@ -0,0 +1,89 @@
+/*  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
diff --git a/example/byteorder.h b/example/byteorder.h
new file mode 100644 (file)
index 0000000..1e319a3
--- /dev/null
@@ -0,0 +1,49 @@
+/*  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
index 561eebc8d7f2a249f3b65f7de813e62828ce3b61..9a1c11b0e580d0891f75295f8f7c70eb8a94559e 100644 (file)
@@ -6,13 +6,16 @@ if HAVE_LIBEVENT
 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)
index a5462734fb45ab3d60af9d17046f348f00d687f8..625b4dd92c203d4ad64e5f515c08f2251e91c953 100644 (file)
@@ -15,7 +15,7 @@
 #include <string.h>
 
 #include <libmemcached/protocol_handler.h>
-#include <libmemcached/byteorder.h>
+#include <example/byteorder.h>
 #include "storage.h"
 #include "memcached_light.h"
 
@@ -78,7 +78,7 @@ static protocol_binary_response_status get_command_handler(const void *cookie,
     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);
@@ -172,8 +172,8 @@ static protocol_binary_response_status arithmetic_command_handler(const void *co
   };
 
   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);
@@ -222,8 +222,8 @@ static protocol_binary_response_status arithmetic_command_handler(const void *co
   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 ||
@@ -266,7 +266,7 @@ static protocol_binary_response_status concat_command_handler(const void *cookie
 {
   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;
@@ -317,7 +317,7 @@ static protocol_binary_response_status concat_command_handler(const void *cookie
             .opcode= header->request.opcode,
             .status= htons(rval),
             .opaque= header->request.opaque,
-            .cas= memcached_htonll(cas),
+            .cas= example_htonll(cas),
           }
         }
       };
@@ -357,7 +357,7 @@ static protocol_binary_response_status set_command_handler(const void *cookie,
     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);
@@ -379,7 +379,7 @@ static protocol_binary_response_status set_command_handler(const void *cookie,
     /* 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);
     }
@@ -426,7 +426,7 @@ static protocol_binary_response_status add_command_handler(const void *cookie,
       /* 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);
       }
@@ -471,7 +471,7 @@ static protocol_binary_response_status replace_command_handler(const void *cooki
   {
     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);
@@ -487,7 +487,7 @@ static protocol_binary_response_status replace_command_handler(const void *cooki
       /* 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);
       }
index 36c0468b28e65b8be047e578217b39295c9c5bde..4fbfed5cbab75630c60e039ef398bba58971c232 100644 (file)
@@ -19,7 +19,7 @@
 #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,
index 6a87ff1917ace469f334c7fc62be6139e3a3bf5d..0249ac6c1fc0240de25628539ab7c6037e6ba57a 100644 (file)
@@ -35,7 +35,7 @@
 #include <event.h>
 
 #include <libmemcached/protocol_handler.h>
-#include <libmemcached/byteorder.h>
+#include <example/byteorder.h>
 #include "storage.h"
 #include "memcached_light.h"
 
index fffb94a492aebf86815942322d9511f0825a7506..7a22cee0dd510681bfc68f317fdda99af66f0597 100644 (file)
@@ -9,8 +9,8 @@
 #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;
 
index 43300585b6124cde647a4434f00aca8f1a70d6a8..cb424e1d5c408020bcf06265c7dfdaa29a589b98 100644 (file)
@@ -54,6 +54,14 @@ if INCLUDE_MURMUR_SRC
 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
@@ -62,6 +70,7 @@ libhashkit_libhashkit_la_LDFLAGS= \
                                  $(LIBM) \
                                  -version-info $(HASHKIT_LIBRARY_VERSION)
 
+# library used for testing
 noinst_LTLIBRARIES+= libhashkit/libhashkitinc.la
 
 libhashkit_libhashkitinc_la_SOURCES= ${libhashkit_libhashkit_la_SOURCES}
index 80ea0210b9857dcab26a327bd815626829394404..7e141756000cc3a5977e5405d9ff1335d77e4a3c 100644 (file)
  *
  */
 
-#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
index d4b2c7df3446660f26307541ec29a3560068767d..62a2b1c67411928c8a517d73aec5e2ba675a538c 100644 (file)
 #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
@@ -92,7 +99,11 @@ memcached_return_t memcached_server_execute(memcached_st *ptr,
 #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>
@@ -107,12 +118,7 @@ memcached_return_t memcached_server_execute(memcached_st *ptr,
 #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)
 
index e3638b46f1b8de0b605337bf4614f6f057950546..07bb545b2bbe55f603f6ade5617ea4f21e5154af 100644 (file)
@@ -446,7 +446,7 @@ static memcached_return_t network_connect(memcached_server_st *ptr)
     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 */
@@ -590,11 +590,6 @@ memcached_return_t memcached_connect(memcached_server_write_instance_st ptr)
   /* 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);
@@ -615,10 +610,6 @@ memcached_return_t memcached_connect(memcached_server_write_instance_st ptr)
   case MEMCACHED_CONNECTION_UNIX_SOCKET:
     rc= unix_socket_connect(ptr);
     break;
-
-  case MEMCACHED_CONNECTION_MAX:
-  default:
-    WATCHPOINT_ASSERT(0);
   }
 
   if (memcached_success(rc))
index 165745e75af99b1aa4fd508fc098ac6bbfefaca3..e17e676ebebb31c58c238ebe63fe54cd077fdcc7 100644 (file)
@@ -155,11 +155,14 @@ typedef enum memcached_hash_t memcached_hash_t;
 #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
diff --git a/libmemcached/continuum.hpp b/libmemcached/continuum.hpp
new file mode 100644 (file)
index 0000000..e39fcdc
--- /dev/null
@@ -0,0 +1,46 @@
+/*  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;
+};
index de4a53dc46a51931b3ce96e84f271ed0d3f13d36..ea3b602539cf557558869e2feb43a67360caf78d 100644 (file)
@@ -161,7 +161,9 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr,
         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);
index 5afb22824a3c0932bce7ab5e499010345973f34e..b0bdd3f85386fdb1f10032b86fd134efa5ea5593 100644 (file)
@@ -495,10 +495,15 @@ memcached_error_t *memcached_error_copy(const memcached_server_st& server)
 
 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;
 }
index d5730105bd069677c346f9e57ff823eb882d1ec8..8867d53d0cc711bc5b6cee9c001bd573015c361f 100644 (file)
@@ -86,7 +86,9 @@ char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length,
   }
 
   if (value_length)
+  {
     *value_length= memcached_string_length(&result_buffer->value);
+  }
 
   if (key)
   {
index f8e20d582662f0f3a4b3783fc19814699746bedc..4950f3ca6409e16313c8e323cb3e0834d3981859 100644 (file)
@@ -16,11 +16,13 @@ noinst_HEADERS+= \
                 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 \
@@ -29,6 +31,8 @@ noinst_HEADERS+= \
                 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+= \
@@ -77,25 +81,6 @@ 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} \
@@ -154,7 +139,7 @@ libmemcached/options.cc: libmemcached/csl/parser.h
 
 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)
@@ -164,22 +149,19 @@ endif
 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
index c04deb30502001570333bfc82f24a94ee57d0e6b..0ed565d7e28a436e7d3bd9b26ba6598175253430 100644 (file)
@@ -44,10 +44,152 @@ enum memc_read_or_write {
   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)
@@ -145,132 +287,158 @@ static memcached_return_t io_wait(memcached_server_write_instance_st ptr,
   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,
@@ -639,155 +807,6 @@ memcached_server_write_instance_st memcached_io_get_readable_server(memcached_st
   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.
 */
@@ -827,10 +846,11 @@ memcached_return_t memcached_safe_read(memcached_server_write_instance_st ptr,
 
 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)
   {
@@ -879,30 +899,6 @@ memcached_return_t memcached_io_readline(memcached_server_write_instance_st ptr,
   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)
index 0d1e6193c3839945b7a0c1a4981229698f28d920..3591de922badf79d8ca27e81457053b420abeea8 100644 (file)
@@ -38,8 +38,6 @@
 
 #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
@@ -71,49 +69,14 @@ extern "C" {
 #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
diff --git a/libmemcached/io.hpp b/libmemcached/io.hpp
new file mode 100644 (file)
index 0000000..23a4a6b
--- /dev/null
@@ -0,0 +1,75 @@
+/*  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);
index 1548b4ed23c847f1ad2a6f70d4680809803b959a..74d10a96a0eabf264aad4f6b3c334edbdf83e3c7 100644 (file)
@@ -36,6 +36,7 @@
  */
 
 #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,
@@ -252,7 +253,9 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta
                                                     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;
@@ -287,8 +290,25 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta
       }
       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));
@@ -593,24 +613,31 @@ static memcached_return_t binary_read_one_response(memcached_server_write_instan
     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:
index 0d3148429f46be9ad901f28c104c9ff4b6688d10..d45d2e853e570d0ca24a8c6559fec5fba92f558b 100644 (file)
@@ -91,8 +91,27 @@ enum memcached_return_t {
 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)
index bde53c7e4c68954f3bd6081d81a8ebdeb1ece3f9..5576caaa5d5b418419485a6aaeac804338885117 100644 (file)
@@ -360,10 +360,6 @@ const char *memcached_server_type(const memcached_server_instance_st ptr)
 
     case MEMCACHED_CONNECTION_UNIX_SOCKET:
       return "SOCKET";
-
-    case MEMCACHED_CONNECTION_MAX:
-    case MEMCACHED_CONNECTION_UNKNOWN:
-      break;
     }
   }
 
diff --git a/libmemcached/server_instance.h b/libmemcached/server_instance.h
new file mode 100644 (file)
index 0000000..8c43992
--- /dev/null
@@ -0,0 +1,48 @@
+/*  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
index 9d77f51f4e5fd1a6e4ab19c9ebfd0cf7bbcefdee..0fc6e234df7d162be7a2646ec4f7629c050f65ce 100644 (file)
@@ -25,23 +25,82 @@ static inline const char *storage_op_string(memcached_storage_action_t verb)
 {
   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,
@@ -54,176 +113,286 @@ 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;
 }
@@ -405,169 +574,3 @@ memcached_return_t memcached_cas_by_key(memcached_st *ptr,
   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);
-}
-
index 7bc7fec0036e87c293d87b1ee8c31287af515472..d482d4cd4d21630feac0412b5d927ffcb8645a01 100644 (file)
@@ -191,7 +191,9 @@ memcached_return_t memcached_string_reset(memcached_string_st *string)
 void memcached_string_free(memcached_string_st *ptr)
 {
   if (not ptr)
+  {
     return;
+  }
 
   if (ptr->string)
   {
@@ -215,7 +217,7 @@ memcached_return_t memcached_string_check(memcached_string_st *string, size_t ne
 
 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)
index 3a3fdf530fd1add85d247bda40f8c86d46de0334..01097a653edc1ee9563158fd256e5fd7266b5c93 100644 (file)
@@ -60,8 +60,6 @@ struct memcached_string_st {
   } options;
 };
 
-#ifdef BUILDING_LIBMEMCACHED
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -109,13 +107,3 @@ void memcached_string_set_length(memcached_string_st *self, size_t length);
 #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
diff --git a/libmemcached/string.hpp b/libmemcached/string.hpp
new file mode 100644 (file)
index 0000000..5703bb4
--- /dev/null
@@ -0,0 +1,47 @@
+/*  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
+
+
index 9ac9c8c44065c455a729fb9bd8995b10a4e012bc..2f44651761e4cba157164ffe8aeb26150fe3d627 100644 (file)
@@ -2,7 +2,6 @@
 # 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 \
@@ -12,7 +11,6 @@ nobase_include_HEADERS+= \
                         libmemcached/util/pool.h \
                         libmemcached/util/version.h
 lib_LTLIBRARIES+= libmemcached/libmemcachedutil.la
-endif
 
 libmemcached_libmemcachedutil_la_SOURCES= \
                                          libmemcached/backtrace.cc \
@@ -31,7 +29,7 @@ libmemcached_libmemcachedutil_la_CXXFLAGS= \
                                           ${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
 
index 646806ac94d8bf588a64a4e5256c32758d368004..d4e4eea05f15051029e4ca77051fd84c1070b18e 100644 (file)
  * 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) */
diff --git a/libmemcachedinternal/include.am b/libmemcachedinternal/include.am
new file mode 100644 (file)
index 0000000..a6153cd
--- /dev/null
@@ -0,0 +1,25 @@
+# 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)
diff --git a/libmemcachedinternal/util/include.am b/libmemcachedinternal/util/include.am
new file mode 100644 (file)
index 0000000..6458925
--- /dev/null
@@ -0,0 +1,25 @@
+# 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
+
+
index c2fe5144a66975e984b9a2d466a013e0c1782d96..7a7f1ff0fec127e23c10d7219498c91cde69187e 100644 (file)
@@ -19,7 +19,6 @@
  *  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>
index 71b5821f54e71c7ca02e11013e76b1706b04000b..2ed437c2af36ad30c087cc84a5f6807219e9b8a7 100644 (file)
@@ -78,19 +78,26 @@ libtest_libtest_la_SOURCES= \
                            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
 
index 475449a944ed3ab1c1a768cba39aa43bf2827bdd..910ea809396dc2ad5476702cefe882cc5ecc5426 100644 (file)
@@ -183,6 +183,8 @@ bool Memcached::build(int argc, const char *argv[])
   }
 
   arg_buffer << " -l 127.0.0.1 ";
+  arg_buffer << " -m 128 ";
+  arg_buffer << " -M ";
 
   for (int x= 1 ; x < argc ; x++)
   {
index c2f38ba9a8512acd2537d30795aa55f462666684..b8fb603e13696fdadc9bdcfa6cb97a6f719bbf6d 100644 (file)
@@ -51,6 +51,19 @@ static inline std::string &rtrim(std::string &s)
 #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)
@@ -180,7 +193,8 @@ bool Server::start()
     _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();
@@ -513,6 +527,7 @@ bool server_startup_st::is_helgrind() const
 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
   {
diff --git a/m4/bottom.m4 b/m4/bottom.m4
new file mode 100644 (file)
index 0000000..55591be
--- /dev/null
@@ -0,0 +1,55 @@
+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
index ceb859af2dd74cf3a32c31af623431378093cce0..2af1f19066336d29772ebcf625a69d0c466091e1 100644 (file)
@@ -69,14 +69,6 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[
     ])
   ])
 
-  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
@@ -87,8 +79,6 @@ AC_DEFUN([PANDORA_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)
   ],[
@@ -320,93 +310,6 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[
 
   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}"
 
index 390efc57ce0250b367c996cba72a9ab5c146a148..4edf46f23ed58b88eeb5b78267c939c5bf336810 100644 (file)
@@ -8,10 +8,10 @@ dnl Macro: PANDORA_ENABLE_DTRACE
 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])
diff --git a/m4/pandora_print_callstack.m4 b/m4/pandora_print_callstack.m4
deleted file mode 100644 (file)
index 93faa83..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-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
-  ])
-
-])
diff --git a/tests/c_test.c b/tests/c_test.c
new file mode 100644 (file)
index 0000000..e8960f4
--- /dev/null
@@ -0,0 +1,56 @@
+/*  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;
+}
+
index 2dfb8f38304631b81a2956eafb65348737ac3bb6..18dbdb6b94f5536d4a92f87f1267bd330392e262 100644 (file)
 
 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
@@ -29,6 +26,7 @@ noinst_HEADERS+= \
                 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 \
@@ -43,40 +41,55 @@ noinst_HEADERS+= \
 
 # 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
 
@@ -130,6 +143,13 @@ tests_memslap_DEPENDENCIES= libtest/libtest.la $(TESTS_LDADDS)
 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
 
diff --git a/tests/internals.cc b/tests/internals.cc
new file mode 100644 (file)
index 0000000..8c28d31
--- /dev/null
@@ -0,0 +1,67 @@
+/*  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;
+}
diff --git a/tests/ketama.cc b/tests/ketama.cc
new file mode 100644 (file)
index 0000000..8223734
--- /dev/null
@@ -0,0 +1,289 @@
+/*  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;
+}
diff --git a/tests/ketama.h b/tests/ketama.h
new file mode 100644 (file)
index 0000000..2d9cbb9
--- /dev/null
@@ -0,0 +1,42 @@
+/*  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 *);
index b01d1ab23cf43d5fcc935fea1a029063d16c9b36..49d1eaa51c2672fa51f481976926660e241bdc61 100644 (file)
@@ -6,8 +6,7 @@
  * 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;
@@ -117,5 +116,3 @@ static struct {
 };
 
 #include "ketama_test_cases_spy.h"
-
-#endif
index b9c0a96eeba7dfaf0a7b459c850a210c94f00ca8..b587031ff2a31f24395cd47e6cf142ce1f8a0b28 100644 (file)
@@ -6,8 +6,7 @@
  * 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;
@@ -115,4 +114,3 @@ static struct {
   { "\\MQ_XNT7L-", 1259349383UL, 1259509450UL, "10.0.1.5" },
   { "VD6D0]ba_\\", 3842502950UL, 3842588691UL, "10.0.1.7" },
 };
-#endif
index 9f0e48ec22d4a09e7b565bb1e68cfba0bd55ae24..7418cc218ecaa7a45c02cd6c7c6eb2fbb359cc0d 100644 (file)
   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>
@@ -66,9 +70,9 @@
 #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"
 
@@ -2931,69 +2932,6 @@ static test_return_t user_supplied_bug20(memcached_st *memc)
   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
@@ -3098,85 +3036,6 @@ static test_return_t user_supplied_bug21(memcached_st *memc)
   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;
@@ -3376,7 +3235,9 @@ static test_return_t get_read_count(memcached_st *memc)
       {
         count++;
         if (return_value)
+        {
           free(return_value);
+        }
       }
     }
   }
@@ -3400,7 +3261,9 @@ static test_return_t get_read(memcached_st *memc)
       test_compare(MEMCACHED_SUCCESS, rc);
     */
     if (rc == MEMCACHED_SUCCESS && return_value)
+    {
       free(return_value);
+    }
   }
 
   return TEST_SUCCESS;
@@ -3419,7 +3282,7 @@ static test_return_t mget_read(memcached_st *memc)
     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;
@@ -4947,110 +4810,6 @@ static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
   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;
@@ -5975,7 +5734,7 @@ static void memcached_die(memcached_st* mc, memcached_return error, const char*
 {
   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));
@@ -6114,161 +5873,150 @@ static test_return_t sasl_auth_test(memcached_st *memc)
 
 /* 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..
@@ -6277,24 +6025,24 @@ test_st user_tests[] ={
   ** 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}
 };
 
@@ -6305,80 +6053,80 @@ test_st replication_tests[]= {
  *   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}
 };
 
@@ -6390,59 +6138,59 @@ test_st hash_sanity[] ={
 #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}
 };
 
@@ -6492,7 +6240,6 @@ collection_st collection[] ={
   {"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},
index b29a6fdcfb66f1c36397bc27706cf0aadf230728..2becbd925a49c36efc05a702ff7347a926e8c0c3 100644 (file)
@@ -343,7 +343,6 @@ test_return_t memcached_create_with_options_with_filename(memcached_st*)
   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;
index 6ffe6a3ff411a5206bb793830978f3ceac48868b..041390ee31fb2e6b8c181cdf20eb0f3b367a1979 100644 (file)
 // 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! */
@@ -142,33 +152,39 @@ test_return_t string_alloc_append_toobig(memcached_st *memc)
 
   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;
 }
index ca1679cd2d94303a6fff88474cbf2eb03986f0f3..e8848fb9c8540555d425fb3135e2f9a8ed10cb9c 100644 (file)
@@ -42,25 +42,25 @@ extern "C" {
 #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
 }
index a5c289efaae27db17d8e6d341625ce36a2e9f4b3..23c8aec4f5947997d871bf766f70636c00851dca 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <cstdio>
 #include <sstream>
+#include <iostream>
 #include <netdb.h>
 #include <poll.h>
 #include <sys/socket.h>
index ff750f4fc293f38d8c62b62c173b0dc4fb49d330..bd9aeaa4a90507b3105df56e241f039e59654d56 100644 (file)
@@ -43,6 +43,7 @@
 #include <cassert>
 #include <cstddef>
 #include <sys/socket.h>
+#include <string>
 
 #include "util/operation.hpp"
 
diff --git a/util/operation.cc b/util/operation.cc
new file mode 100644 (file)
index 0000000..ad19e2b
--- /dev/null
@@ -0,0 +1,72 @@
+/*  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 */
index 5c8c26edee39f7bc2049bdd8422c0c429749ec8a..13aeeb15f2761717a7b4d89f88a6653cc6db0a70 100644 (file)
@@ -39,7 +39,7 @@
 
 
 #include <cstring>
-#include <iostream>
+#include <iosfwd>
 #include <vector>
 
 namespace datadifferential {
@@ -86,29 +86,7 @@ public:
   }
 
   // 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
   {