From: Date: Mon, 10 Mar 2008 15:04:41 +0000 (-0400) Subject: Huge refactoring of directory structure. X-Git-Tag: _20~1^2~64 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=34a8c3858f30b02568c87f56a827f618aba6d6be;p=m6w6%2Flibmemcached Huge refactoring of directory structure. --- diff --git a/.hgignore b/.hgignore index 9aa168ed..a7097160 100644 --- a/.hgignore +++ b/.hgignore @@ -7,6 +7,7 @@ ^libtool$ ^autom4te.cache$ ^include/(libmemcached_config.h(.in)?|stamp-h1)$ +^libmemcached/libmemcached_config.h.in$ ^stamp-h1$ ^lib/libmemcachedPlus.la$ ^tests/testplus$ diff --git a/Makefile.am b/Makefile.am index 7c23b741..b9213a75 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ -INCLUDES = include -SUBDIRS = docs include lib src tests support +INCLUDES = +SUBDIRS = docs libmemcached tests support EXTRA_dist = README.FIRST test: all diff --git a/clients/Makefile.am b/clients/Makefile.am new file mode 100644 index 00000000..ccc90358 --- /dev/null +++ b/clients/Makefile.am @@ -0,0 +1,38 @@ +INCLUDES = +LDADDS = $(top_builddir)/libmemcached/libmemcached.la + +bin_PROGRAMS = memcat memcp memstat memrm memflush memslap memerror + +noinst_HEADERS = client_options.h \ + utilities.h \ + generator.h \ + execute.h + +memcat_SOURCES = memcat.c utilities.c +memcat_LDADD = $(LDADDS) +memcat_LDFLAGS = -rpath $(pkglibdir) + +memcp_SOURCES = memcp.c utilities.c +memcp_LDADD = $(LDADDS) +memcp_LDFLAGS = -rpath $(pkglibdir) + +memstat_SOURCES = memstat.c utilities.c +memstat_LDADD = $(LDADDS) +memstat_LDFLAGS = -rpath $(pkglibdir) + +memrm_SOURCES = memrm.c utilities.c +memrm_LDADD = $(LDADDS) +memrm_LDFLAGS = -rpath $(pkglibdir) + +memflush_SOURCES = memflush.c utilities.c +memflush_LDADD = $(LDADDS) +memflush_LDFLAGS = -rpath $(pkglibdir) + + +memerror_SOURCES = memerror.c utilities.c +memerror_LDADD = $(LDADDS) +memerror_LDFLAGS = -rpath $(pkglibdir) + +memslap_SOURCES = memslap.c utilities.c generator.c execute.c +memslap_LDADD = $(LDADDS) -lpthread +memslap_LDFLAGS = -rpath $(pkglibdir) diff --git a/clients/client_options.h b/clients/client_options.h new file mode 100644 index 00000000..b7ba5a96 --- /dev/null +++ b/clients/client_options.h @@ -0,0 +1,27 @@ +#ifndef __CLIENT_OPTIONS_H__ +#define __CLIENT_OPTIONS_H__ + +typedef struct memcached_help_text_st memcached_help_text_st; + +typedef enum { + OPT_SERVERS= 's', + OPT_VERSION= 'V', + OPT_HELP= 'h', + OPT_VERBOSE= 'v', + OPT_DEBUG= 'd', + OPT_FLAG= 257, + OPT_EXPIRE, + OPT_SET, + OPT_REPLACE, + OPT_ADD, + OPT_SLAP_EXECUTE_NUMBER, + OPT_SLAP_INITIAL_LOAD, + OPT_SLAP_TEST, + OPT_SLAP_CONCURRENCY, + OPT_SLAP_NON_BLOCK, + OPT_SLAP_TCP_NODELAY, + OPT_FLUSH, + OPT_HASH, +} memcached_options; + +#endif /* CLIENT_OPTIONS */ diff --git a/clients/execute.c b/clients/execute.c new file mode 100644 index 00000000..e623825c --- /dev/null +++ b/clients/execute.c @@ -0,0 +1,63 @@ +/* + Execute a memcached_set() a set of pairs. + Return the number of rows set. +*/ + +#include +#include "execute.h" + +unsigned int execute_set(memcached_st *memc, pairs_st *pairs, unsigned int number_of) +{ + memcached_return rc; + unsigned int x; + unsigned int pairs_sent; + + for (x= 0, pairs_sent= 0; x < number_of; x++) + { + rc= memcached_set(memc, pairs[x].key, pairs[x].key_length, + pairs[x].value, pairs[x].value_length, + 0, 0); + if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED) + fprintf(stderr, "Failured on insert of %.*s\n", + (unsigned int)pairs[x].key_length, pairs[x].key); + else + pairs_sent++; + } + + return pairs_sent; +} + +/* + Execute a memcached_get() on a set of pairs. + Return the number of rows retrieved. +*/ +unsigned int execute_get(memcached_st *memc, pairs_st *pairs, unsigned int number_of) +{ + memcached_return rc; + unsigned int x; + unsigned int retrieved; + + + for (retrieved= 0,x= 0; x < number_of; x++) + { + char *value; + size_t value_length; + uint32_t flags; + unsigned int fetch_key; + + fetch_key= random() % number_of; + + value= memcached_get(memc, pairs[fetch_key].key, pairs[fetch_key].key_length, + &value_length, &flags, &rc); + + if (rc != MEMCACHED_SUCCESS) + fprintf(stderr, "Failured on read of %.*s\n", + (unsigned int)pairs[fetch_key].key_length, pairs[fetch_key].key); + else + retrieved++; + + free(value); + } + + return retrieved; +} diff --git a/clients/execute.h b/clients/execute.h new file mode 100644 index 00000000..fc041312 --- /dev/null +++ b/clients/execute.h @@ -0,0 +1,5 @@ +#include +#include "generator.h" + +unsigned int execute_set(memcached_st *memc, pairs_st *pairs, unsigned int number_of); +unsigned int execute_get(memcached_st *memc, pairs_st *pairs, unsigned int number_of); diff --git a/clients/generator.c b/clients/generator.c new file mode 100644 index 00000000..793157ef --- /dev/null +++ b/clients/generator.c @@ -0,0 +1,70 @@ +#include +#include +#include + +#include "generator.h" + +/* Use this for string generation */ +static const char ALPHANUMERICS[]= + "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz"; + +#define ALPHANUMERICS_SIZE (sizeof(ALPHANUMERICS)-1) + +static void get_random_string(char *buffer, size_t size) +{ + char *buffer_ptr= buffer; + + while (--size) + *buffer_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE]; + *buffer_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE]; +} + +void pairs_free(pairs_st *pairs) +{ + unsigned int x; + + if (!pairs) + return; + + /* We free until we hit the null pair we stores during creation */ + for (x= 0; pairs[x].key; x++) + { + free(pairs[x].key); + free(pairs[x].value); + } + + free(pairs); +} + +pairs_st *pairs_generate(unsigned long long number_of, size_t value_length) +{ + unsigned int x; + pairs_st *pairs; + + pairs= (pairs_st*)malloc(sizeof(pairs_st) * (number_of+1)); + + if (!pairs) + goto error; + + memset(pairs, 0, sizeof(pairs_st) * (number_of+1)); + + for (x= 0; x < number_of; x++) + { + pairs[x].key= (char *)malloc(sizeof(char) * 100); + if (!pairs[x].key) + goto error; + get_random_string(pairs[x].key, 100); + pairs[x].key_length= 100; + + pairs[x].value= (char *)malloc(sizeof(char) * value_length); + if (!pairs[x].value) + goto error; + get_random_string(pairs[x].value, value_length); + pairs[x].value_length= value_length; + } + + return pairs; +error: + fprintf(stderr, "Memory Allocation failure in pairs_generate.\n"); + exit(0); +} diff --git a/clients/generator.h b/clients/generator.h new file mode 100644 index 00000000..c3fcab32 --- /dev/null +++ b/clients/generator.h @@ -0,0 +1,20 @@ +/* + Code to generate data to be pushed into memcached +*/ + +#ifndef __GENERATOR_H__ +#define __GENERATOR_H__ + +typedef struct pairs_st pairs_st; + +struct pairs_st { + char *key; + size_t key_length; + char *value; + size_t value_length; +}; + +pairs_st *pairs_generate(unsigned long long number_of, size_t length); +void pairs_free(pairs_st *pairs); + +#endif diff --git a/clients/memcat.c b/clients/memcat.c new file mode 100644 index 00000000..b9db6497 --- /dev/null +++ b/clients/memcat.c @@ -0,0 +1,152 @@ +#include +#include +#include +#include +#include +#include + +#include "utilities.h" + +#define PROGRAM_NAME "memcat" +#define PROGRAM_DESCRIPTION "Cat a set of key values to stdout." + + +/* Prototypes */ +void options_parse(int argc, char *argv[]); + +static int opt_verbose= 0; +static int opt_displayflag= 0; +static char *opt_servers= NULL; +static char *opt_hash= NULL; + +int main(int argc, char *argv[]) +{ + memcached_st *memc; + char *string; + size_t string_length; + uint32_t flags; + memcached_return rc; + memcached_server_st *servers; + + options_parse(argc, argv); + + if (!opt_servers) + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + { + fprintf(stderr, "No Servers provided\n"); + exit(1); + } + } + + memc= memcached_create(NULL); + process_hash_option(memc, opt_hash); + + servers= memcached_servers_parse(opt_servers); + + memcached_server_push(memc, servers); + memcached_server_list_free(servers); + + while (optind < argc) + { + string= memcached_get(memc, argv[optind], strlen(argv[optind]), + &string_length, &flags, &rc); + if (rc == MEMCACHED_SUCCESS) + { + if (opt_displayflag) + { + if (opt_verbose) + printf("key: %s\nflags: ", argv[optind]); + printf("%x\n", flags); + } + else + { + if (opt_verbose) + printf("key: %s\nflags: %x\nlength: %zu\nvalue: ", + argv[optind], flags, string_length); + printf("%.*s\n", (int)string_length, string); + free(string); + } + } + else if (rc != MEMCACHED_NOTFOUND) + { + fprintf(stderr, "memcat: %s: memcache error %s", + argv[optind], memcached_strerror(memc, rc)); + if (memc->cached_errno) + fprintf(stderr, " system error %s", strerror(memc->cached_errno)); + fprintf(stderr, "\n"); + } + optind++; + } + + memcached_free(memc); + + if (opt_servers) + free(opt_servers); + if (opt_hash) + free(opt_hash); + + return 0; +} + + +void options_parse(int argc, char *argv[]) +{ + int option_index= 0; + int option_rv; + + memcached_programs_help_st help_options[]= + { + {0}, + }; + + static struct option long_options[]= + { + {"version", no_argument, NULL, OPT_VERSION}, + {"help", no_argument, NULL, OPT_HELP}, + {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, + {"debug", no_argument, &opt_verbose, OPT_DEBUG}, + {"servers", required_argument, NULL, OPT_SERVERS}, + {"flag", no_argument, &opt_displayflag, OPT_FLAG}, + {"hash", required_argument, NULL, OPT_HASH}, + {0, 0, 0, 0}, + }; + + while (1) + { + option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); + if (option_rv == -1) break; + switch (option_rv) + { + case 0: + break; + case OPT_VERBOSE: /* --verbose or -v */ + opt_verbose = OPT_VERBOSE; + break; + case OPT_DEBUG: /* --debug or -d */ + opt_verbose = OPT_DEBUG; + break; + case OPT_VERSION: /* --version or -V */ + version_command(PROGRAM_NAME); + break; + case OPT_HELP: /* --help or -h */ + help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); + break; + case OPT_SERVERS: /* --servers or -s */ + opt_servers= strdup(optarg); + break; + case OPT_HASH: + opt_hash= strdup(optarg); + break; + case '?': + /* getopt_long already printed an error message. */ + exit(1); + default: + abort(); + } + } +} diff --git a/clients/memcp.c b/clients/memcp.c new file mode 100644 index 00000000..780514c1 --- /dev/null +++ b/clients/memcp.c @@ -0,0 +1,223 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "client_options.h" +#include "utilities.h" + +#define PROGRAM_NAME "memcp" +#define PROGRAM_DESCRIPTION "Copy a set of files to a memcached cluster." + +/* Prototypes */ +void options_parse(int argc, char *argv[]); + +static int opt_verbose= 0; +static char *opt_servers= NULL; +static char *opt_hash= NULL; +static int opt_method= OPT_SET; +static uint32_t opt_flags= 0; +static time_t opt_expires= 0; + +int main(int argc, char *argv[]) +{ + memcached_st *memc; + memcached_return rc; + memcached_server_st *servers; + + options_parse(argc, argv); + + memc= memcached_create(NULL); + process_hash_option(memc, opt_hash); + + if (!opt_servers) + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + { + fprintf(stderr, "No Servers provided\n"); + exit(1); + } + } + + if (opt_servers) + servers= memcached_servers_parse(opt_servers); + else + servers= memcached_servers_parse(argv[--argc]); + + memcached_server_push(memc, servers); + memcached_server_list_free(servers); + + while (optind < argc) + { + struct stat sbuf; + int fd; + char *ptr; + ssize_t read_length; + char *file_buffer_ptr; + + fd= open(argv[optind], O_RDONLY); + if (fd < 0) + { + fprintf(stderr, "memcp: %s: %s\n", argv[optind], strerror(errno)); + optind++; + continue; + } + + (void)fstat(fd, &sbuf); + + ptr= rindex(argv[optind], '/'); + if (ptr) + ptr++; + else + ptr= argv[optind]; + + if (opt_verbose) + { + static char *opstr[] = { "set", "add", "replace" }; + printf("op: %s\nsource file: %s\nlength: %zu\n" + "key: %s\nflags: %x\nexpires: %llu\n", + opstr[opt_method - OPT_SET], argv[optind], (size_t)sbuf.st_size, + ptr, opt_flags, (unsigned long long)opt_expires); + } + + if ((file_buffer_ptr= (char *)malloc(sizeof(char) * sbuf.st_size)) == NULL) + { + fprintf(stderr, "malloc: %s\n", strerror(errno)); + exit(1); + } + + if ((read_length= read(fd, file_buffer_ptr, sbuf.st_size)) == -1) + { + fprintf(stderr, "read: %s\n", strerror(errno)); + exit(1); + } + assert(read_length == sbuf.st_size); + + if (opt_method == OPT_ADD) + rc= memcached_add(memc, ptr, strlen(ptr), + file_buffer_ptr, sbuf.st_size, + opt_expires, opt_flags); + else if (opt_method == OPT_REPLACE) + rc= memcached_replace(memc, ptr, strlen(ptr), + file_buffer_ptr, sbuf.st_size, + opt_expires, opt_flags); + else + rc= memcached_set(memc, ptr, strlen(ptr), + file_buffer_ptr, sbuf.st_size, + opt_expires, opt_flags); + + if (rc != MEMCACHED_SUCCESS) + { + fprintf(stderr, "memcp: %s: memcache error %s", + ptr, memcached_strerror(memc, rc)); + if (memc->cached_errno) + fprintf(stderr, " system error %s", strerror(memc->cached_errno)); + fprintf(stderr, "\n"); + } + + free(file_buffer_ptr); + close(fd); + optind++; + } + + memcached_free(memc); + + if (opt_servers) + free(opt_servers); + if (opt_hash) + free(opt_hash); + + return 0; +} + +void options_parse(int argc, char *argv[]) +{ + int option_index= 0; + int option_rv; + + memcached_programs_help_st help_options[]= + { + {0}, + }; + + static struct option long_options[]= + { + {"version", no_argument, NULL, OPT_VERSION}, + {"help", no_argument, NULL, OPT_HELP}, + {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, + {"debug", no_argument, &opt_verbose, OPT_DEBUG}, + {"servers", required_argument, NULL, OPT_SERVERS}, + {"flag", required_argument, NULL, OPT_FLAG}, + {"expire", required_argument, NULL, OPT_EXPIRE}, + {"set", no_argument, NULL, OPT_SET}, + {"add", no_argument, NULL, OPT_ADD}, + {"replace", no_argument, NULL, OPT_REPLACE}, + {"hash", required_argument, NULL, OPT_HASH}, + {0, 0, 0, 0}, + }; + + while (1) + { + option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); + + if (option_rv == -1) break; + + switch (option_rv) + { + case 0: + break; + case OPT_VERBOSE: /* --verbose or -v */ + opt_verbose = OPT_VERBOSE; + break; + case OPT_DEBUG: /* --debug or -d */ + opt_verbose = OPT_DEBUG; + break; + case OPT_VERSION: /* --version or -V */ + version_command(PROGRAM_NAME); + break; + case OPT_HELP: /* --help or -h */ + help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); + break; + case OPT_SERVERS: /* --servers or -s */ + opt_servers= strdup(optarg); + break; + case OPT_FLAG: /* --flag */ + opt_flags= (uint32_t)strtol(optarg, (char **)NULL, 16); + break; + case OPT_EXPIRE: /* --expire */ + opt_expires= (time_t)strtoll(optarg, (char **)NULL, 10); + break; + case OPT_SET: + opt_method= OPT_SET; + break; + case OPT_REPLACE: + opt_method= OPT_REPLACE; + break; + case OPT_ADD: + opt_method= OPT_ADD; + case OPT_HASH: + opt_hash= strdup(optarg); + break; + case '?': + /* getopt_long already printed an error message. */ + exit(1); + default: + abort(); + } + } +} diff --git a/clients/memerror.c b/clients/memerror.c new file mode 100644 index 00000000..5654c212 --- /dev/null +++ b/clients/memerror.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "utilities.h" + +#define PROGRAM_NAME "memerror" +#define PROGRAM_DESCRIPTION "Translate a memcached errror code into a string." + + +/* Prototypes */ +void options_parse(int argc, char *argv[]); + +static int opt_verbose= 0; + +int main(int argc, char *argv[]) +{ + options_parse(argc, argv); + + if (argc != 2) + return 1; + + printf("%s\n", memcached_strerror(NULL, atoi(argv[1]))); + + return 0; +} + + +void options_parse(int argc, char *argv[]) +{ + int option_index= 0; + int option_rv; + + memcached_programs_help_st help_options[]= + { + {0}, + }; + + static struct option long_options[]= + { + {"version", no_argument, NULL, OPT_VERSION}, + {"help", no_argument, NULL, OPT_HELP}, + {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, + {"debug", no_argument, &opt_verbose, OPT_DEBUG}, + {0, 0, 0, 0}, + }; + + while (1) + { + option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); + if (option_rv == -1) break; + switch (option_rv) + { + case 0: + break; + case OPT_VERBOSE: /* --verbose or -v */ + opt_verbose = OPT_VERBOSE; + break; + case OPT_DEBUG: /* --debug or -d */ + opt_verbose = OPT_DEBUG; + break; + case OPT_VERSION: /* --version or -V */ + version_command(PROGRAM_NAME); + break; + case OPT_HELP: /* --help or -h */ + help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); + break; + case '?': + /* getopt_long already printed an error message. */ + exit(1); + default: + abort(); + } + } +} diff --git a/clients/memflush.c b/clients/memflush.c new file mode 100644 index 00000000..3bf25c34 --- /dev/null +++ b/clients/memflush.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include +#include +#include "client_options.h" +#include "utilities.h" + +static int opt_verbose= 0; +static time_t opt_expire= 0; +static char *opt_servers= NULL; + +#define PROGRAM_NAME "memflush" +#define PROGRAM_DESCRIPTION "Erase all data in a server of memcached servers." + +/* Prototypes */ +void options_parse(int argc, char *argv[]); + +int main(int argc, char *argv[]) +{ + memcached_st *memc; + memcached_return rc; + memcached_server_st *servers; + + options_parse(argc, argv); + + if (!opt_servers) + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + { + fprintf(stderr, "No Servers provided\n"); + exit(1); + } + } + + memc= memcached_create(NULL); + + servers= memcached_servers_parse(opt_servers); + memcached_server_push(memc, servers); + memcached_server_list_free(servers); + + rc = memcached_flush(memc, opt_expire); + if (rc != MEMCACHED_SUCCESS) + { + fprintf(stderr, "memflush: memcache error %s", + memcached_strerror(memc, rc)); + if (memc->cached_errno) + fprintf(stderr, " system error %s", strerror(memc->cached_errno)); + fprintf(stderr, "\n"); + } + + memcached_free(memc); + + free(opt_servers); + + return 0; +} + + +void options_parse(int argc, char *argv[]) +{ + memcached_programs_help_st help_options[]= + { + {0}, + }; + + static struct option long_options[]= + { + {"version", no_argument, NULL, OPT_VERSION}, + {"help", no_argument, NULL, OPT_HELP}, + {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, + {"debug", no_argument, &opt_verbose, OPT_DEBUG}, + {"servers", required_argument, NULL, OPT_SERVERS}, + {"expire", required_argument, NULL, OPT_EXPIRE}, + {0, 0, 0, 0}, + }; + int option_index= 0; + int option_rv; + + while (1) + { + option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); + if (option_rv == -1) break; + switch (option_rv) + { + case 0: + break; + case OPT_VERBOSE: /* --verbose or -v */ + opt_verbose = OPT_VERBOSE; + break; + case OPT_DEBUG: /* --debug or -d */ + opt_verbose = OPT_DEBUG; + break; + case OPT_VERSION: /* --version or -V */ + version_command(PROGRAM_NAME); + break; + case OPT_HELP: /* --help or -h */ + help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); + break; + case OPT_SERVERS: /* --servers or -s */ + opt_servers= strdup(optarg); + break; + case OPT_EXPIRE: /* --expire */ + opt_expire= (time_t)strtoll(optarg, (char **)NULL, 10); + break; + case '?': + /* getopt_long already printed an error message. */ + exit(1); + default: + abort(); + } + } +} diff --git a/clients/memrm.c b/clients/memrm.c new file mode 100644 index 00000000..05fe404b --- /dev/null +++ b/clients/memrm.c @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include +#include "client_options.h" +#include "utilities.h" + +static int opt_verbose= 0; +static time_t opt_expire= 0; +static char *opt_servers= NULL; +static char *opt_hash= NULL; + +#define PROGRAM_NAME "memrm" +#define PROGRAM_DESCRIPTION "Erase a key or set of keys from a memcached cluster." + +/* Prototypes */ +void options_parse(int argc, char *argv[]); + +int main(int argc, char *argv[]) +{ + memcached_st *memc; + memcached_return rc; + memcached_server_st *servers; + + options_parse(argc, argv); + + if (!opt_servers) + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + { + fprintf(stderr, "No Servers provided\n"); + exit(1); + } + } + + memc= memcached_create(NULL); + process_hash_option(memc, opt_hash); + + servers= memcached_servers_parse(opt_servers); + memcached_server_push(memc, servers); + memcached_server_list_free(servers); + + while (optind < argc) + { + if (opt_verbose) + printf("key: %s\nexpires: %llu\n", argv[optind], (unsigned long long)opt_expire); + rc = memcached_delete(memc, argv[optind], strlen(argv[optind]), opt_expire); + + if (rc != MEMCACHED_SUCCESS) + { + fprintf(stderr, "memrm: %s: memcache error %s", + argv[optind], memcached_strerror(memc, rc)); + if (memc->cached_errno) + fprintf(stderr, " system error %s", strerror(memc->cached_errno)); + fprintf(stderr, "\n"); + } + + optind++; + } + + memcached_free(memc); + + if (opt_servers) + free(opt_servers); + if (opt_hash) + free(opt_hash); + + return 0; +} + + +void options_parse(int argc, char *argv[]) +{ + memcached_programs_help_st help_options[]= + { + {0}, + }; + + static struct option long_options[]= + { + {"version", no_argument, NULL, OPT_VERSION}, + {"help", no_argument, NULL, OPT_HELP}, + {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, + {"debug", no_argument, &opt_verbose, OPT_DEBUG}, + {"servers", required_argument, NULL, OPT_SERVERS}, + {"expire", required_argument, NULL, OPT_EXPIRE}, + {"hash", required_argument, NULL, OPT_HASH}, + {0, 0, 0, 0}, + }; + int option_index= 0; + int option_rv; + + while (1) + { + option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); + if (option_rv == -1) break; + switch (option_rv) + { + case 0: + break; + case OPT_VERBOSE: /* --verbose or -v */ + opt_verbose = OPT_VERBOSE; + break; + case OPT_DEBUG: /* --debug or -d */ + opt_verbose = OPT_DEBUG; + break; + case OPT_VERSION: /* --version or -V */ + version_command(PROGRAM_NAME); + break; + case OPT_HELP: /* --help or -h */ + help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); + break; + case OPT_SERVERS: /* --servers or -s */ + opt_servers= strdup(optarg); + break; + case OPT_EXPIRE: /* --expire */ + opt_expire= (time_t)strtoll(optarg, (char **)NULL, 10); + break; + case OPT_HASH: + opt_hash= strdup(optarg); + break; + case '?': + /* getopt_long already printed an error message. */ + exit(1); + default: + abort(); + } + } +} diff --git a/clients/memslap.c b/clients/memslap.c new file mode 100644 index 00000000..164fc099 --- /dev/null +++ b/clients/memslap.c @@ -0,0 +1,388 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "client_options.h" +#include "utilities.h" +#include "generator.h" +#include "execute.h" + +#define DEFAULT_INITIAL_LOAD 10000 +#define DEFAULT_EXECUTE_NUMBER 10000 +#define DEFAULT_CONCURRENCY 1 + +#define PROGRAM_NAME "memslap" +#define PROGRAM_DESCRIPTION "Generates a load against a memcached custer of servers." + +/* Global Thread counter */ +volatile unsigned int thread_counter; +pthread_mutex_t counter_mutex; +pthread_cond_t count_threshhold; +volatile unsigned int master_wakeup; +pthread_mutex_t sleeper_mutex; +pthread_cond_t sleep_threshhold; + +void *run_task(void *p); + +/* Types */ +typedef struct conclusions_st conclusions_st; +typedef struct thread_context_st thread_context_st; +typedef enum { + SET_TEST, + GET_TEST, +} test_type; + +struct thread_context_st { + unsigned int key_count; + pairs_st *initial_pairs; + unsigned int initial_number; + pairs_st *execute_pairs; + unsigned int execute_number; + test_type test; + memcached_st *memc; +}; + +struct conclusions_st { + long int load_time; + long int read_time; + unsigned int rows_loaded; + unsigned int rows_read; +}; + +/* Prototypes */ +void options_parse(int argc, char *argv[]); +void conclusions_print(conclusions_st *conclusion); +void scheduler(memcached_server_st *servers, conclusions_st *conclusion); +pairs_st *load_create_data(memcached_st *memc, unsigned int number_of, + unsigned int *actual_loaded); +void flush_all(memcached_st *memc); + +static int opt_verbose= 0; +static int opt_flush= 0; +static int opt_non_blocking_io= 0; +static int opt_tcp_nodelay= 0; +static unsigned int opt_execute_number= 0; +static unsigned int opt_createial_load= 0; +static unsigned int opt_concurrency= 0; +static int opt_displayflag= 0; +static char *opt_servers= NULL; +test_type opt_test= SET_TEST; + +int main(int argc, char *argv[]) +{ + conclusions_st conclusion; + memcached_server_st *servers; + + memset(&conclusion, 0, sizeof(conclusions_st)); + + srandom(time(NULL)); + options_parse(argc, argv); + + if (!opt_servers) + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + { + fprintf(stderr, "No Servers provided\n"); + exit(1); + } + } + + servers= memcached_servers_parse(opt_servers); + + pthread_mutex_init(&counter_mutex, NULL); + pthread_cond_init(&count_threshhold, NULL); + pthread_mutex_init(&sleeper_mutex, NULL); + pthread_cond_init(&sleep_threshhold, NULL); + + scheduler(servers, &conclusion); + + free(opt_servers); + + (void)pthread_mutex_destroy(&counter_mutex); + (void)pthread_cond_destroy(&count_threshhold); + (void)pthread_mutex_destroy(&sleeper_mutex); + (void)pthread_cond_destroy(&sleep_threshhold); + conclusions_print(&conclusion); + memcached_server_list_free(servers); + + return 0; +} + +void scheduler(memcached_server_st *servers, conclusions_st *conclusion) +{ + unsigned int x; + unsigned int actual_loaded= 0; /* Fix warning */ + memcached_st *memc; + + struct timeval start_time, end_time; + pthread_t mainthread; /* Thread descriptor */ + pthread_attr_t attr; /* Thread attributes */ + pairs_st *pairs= NULL; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, + PTHREAD_CREATE_DETACHED); + + memc= memcached_create(NULL); + memcached_server_push(memc, servers); + + if (opt_flush) + flush_all(memc); + if (opt_createial_load) + pairs= load_create_data(memc, opt_createial_load, &actual_loaded); + + /* We set this after we have loaded */ + { + unsigned int value= 1; + if (opt_non_blocking_io) + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &value); + if (opt_tcp_nodelay) + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &value); + } + + + pthread_mutex_lock(&counter_mutex); + thread_counter= 0; + + pthread_mutex_lock(&sleeper_mutex); + master_wakeup= 1; + pthread_mutex_unlock(&sleeper_mutex); + + for (x= 0; x < opt_concurrency; x++) + { + thread_context_st *context; + context= (thread_context_st *)malloc(sizeof(thread_context_st)); + memset(context, 0, sizeof(thread_context_st)); + + context->memc= memcached_clone(NULL, memc); + context->test= opt_test; + + context->initial_pairs= pairs; + context->initial_number= actual_loaded; + + if (opt_test == SET_TEST) + { + context->execute_pairs= pairs_generate(opt_execute_number, 400); + context->execute_number= opt_execute_number; + } + + /* now you create the thread */ + if (pthread_create(&mainthread, &attr, run_task, + (void *)context) != 0) + { + fprintf(stderr,"Could not create thread\n"); + exit(1); + } + thread_counter++; + } + + pthread_mutex_unlock(&counter_mutex); + pthread_attr_destroy(&attr); + + pthread_mutex_lock(&sleeper_mutex); + master_wakeup= 0; + pthread_mutex_unlock(&sleeper_mutex); + pthread_cond_broadcast(&sleep_threshhold); + + gettimeofday(&start_time, NULL); + /* + We loop until we know that all children have cleaned up. + */ + pthread_mutex_lock(&counter_mutex); + while (thread_counter) + { + struct timespec abstime; + + memset(&abstime, 0, sizeof(struct timespec)); + abstime.tv_sec= 1; + + pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime); + } + pthread_mutex_unlock(&counter_mutex); + + gettimeofday(&end_time, NULL); + + conclusion->load_time= timedif(end_time, start_time); + conclusion->read_time= timedif(end_time, start_time); + pairs_free(pairs); +} + +void options_parse(int argc, char *argv[]) +{ + memcached_programs_help_st help_options[]= + { + {0}, + }; + + static struct option long_options[]= + { + {"concurrency", required_argument, NULL, OPT_SLAP_CONCURRENCY}, + {"debug", no_argument, &opt_verbose, OPT_DEBUG}, + {"execute-number", required_argument, NULL, OPT_SLAP_EXECUTE_NUMBER}, + {"flag", no_argument, &opt_displayflag, OPT_FLAG}, + {"flush", no_argument, &opt_flush, OPT_FLUSH}, + {"help", no_argument, NULL, OPT_HELP}, + {"initial-load", required_argument, NULL, OPT_SLAP_INITIAL_LOAD}, /* Number to load initially */ + {"non-blocking", no_argument, &opt_non_blocking_io, OPT_SLAP_NON_BLOCK}, + {"servers", required_argument, NULL, OPT_SERVERS}, + {"tcp-nodelay", no_argument, &opt_tcp_nodelay, OPT_SLAP_TCP_NODELAY}, + {"test", required_argument, NULL, OPT_SLAP_TEST}, + {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, + {"version", no_argument, NULL, OPT_VERSION}, + {0, 0, 0, 0}, + }; + + int option_index= 0; + int option_rv; + + while (1) + { + option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); + if (option_rv == -1) break; + switch (option_rv) + { + case 0: + break; + case OPT_VERBOSE: /* --verbose or -v */ + opt_verbose = OPT_VERBOSE; + break; + case OPT_DEBUG: /* --debug or -d */ + opt_verbose = OPT_DEBUG; + break; + case OPT_VERSION: /* --version or -V */ + version_command(PROGRAM_NAME); + break; + case OPT_HELP: /* --help or -h */ + help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); + break; + case OPT_SERVERS: /* --servers or -s */ + opt_servers= strdup(optarg); + break; + case OPT_SLAP_TEST: + if (!strcmp(optarg, "get")) + opt_test= GET_TEST ; + else if (!strcmp(optarg, "set")) + opt_test= SET_TEST; + else + { + fprintf(stderr, "Your test, %s, is not a known test\n", optarg); + exit(1); + } + break; + case OPT_SLAP_CONCURRENCY: + opt_concurrency= strtol(optarg, (char **)NULL, 10); + case OPT_SLAP_EXECUTE_NUMBER: + opt_execute_number= strtol(optarg, (char **)NULL, 10); + break; + case OPT_SLAP_INITIAL_LOAD: + opt_createial_load= strtol(optarg, (char **)NULL, 10); + break; + case '?': + /* getopt_long already printed an error message. */ + exit(1); + default: + abort(); + } + } + + if (opt_test == GET_TEST && opt_createial_load == 0) + opt_createial_load= DEFAULT_INITIAL_LOAD; + + if (opt_execute_number == 0) + opt_execute_number= DEFAULT_EXECUTE_NUMBER; + + if (opt_concurrency == 0) + opt_concurrency= DEFAULT_CONCURRENCY; +} + +void conclusions_print(conclusions_st *conclusion) +{ + printf("\tThreads connecting to servers %u\n", opt_concurrency); +#ifdef NOT_FINISHED + printf("\tLoaded %u rows\n", conclusion->rows_loaded); + printf("\tRead %u rows\n", conclusion->rows_read); +#endif + if (opt_test == SET_TEST) + printf("\tTook %ld.%03ld seconds to load data\n", conclusion->load_time / 1000, + conclusion->load_time % 1000); + else + printf("\tTook %ld.%03ld seconds to read data\n", conclusion->read_time / 1000, + conclusion->read_time % 1000); +} + +void *run_task(void *p) +{ + thread_context_st *context= (thread_context_st *)p; + memcached_st *memc; + + memc= context->memc; + + pthread_mutex_lock(&sleeper_mutex); + while (master_wakeup) + { + pthread_cond_wait(&sleep_threshhold, &sleeper_mutex); + } + pthread_mutex_unlock(&sleeper_mutex); + + /* Do Stuff */ + switch (context->test) + { + case SET_TEST: + execute_set(memc, context->execute_pairs, context->execute_number); + break; + case GET_TEST: + execute_get(memc, context->initial_pairs, context->initial_number); + break; + } + + memcached_free(memc); + + if (context->execute_pairs) + pairs_free(context->execute_pairs); + free(context); + + pthread_mutex_lock(&counter_mutex); + thread_counter--; + pthread_cond_signal(&count_threshhold); + pthread_mutex_unlock(&counter_mutex); + + return NULL; +} + +void flush_all(memcached_st *memc) +{ + memcached_flush(memc, 0); +} + +pairs_st *load_create_data(memcached_st *memc, unsigned int number_of, + unsigned int *actual_loaded) +{ + memcached_st *clone; + pairs_st *pairs; + + clone= memcached_clone(NULL, memc); + /* We always used non-blocking IO for load since it is faster */ + memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL ); + + pairs= pairs_generate(number_of, 400); + *actual_loaded= execute_set(clone, pairs, number_of); + + memcached_free(clone); + + return pairs; +} diff --git a/clients/memstat.c b/clients/memstat.c new file mode 100644 index 00000000..3f1a78a3 --- /dev/null +++ b/clients/memstat.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "client_options.h" +#include "utilities.h" + +#define PROGRAM_NAME "memstat" +#define PROGRAM_DESCRIPTION "Output the state of a memcached cluster." + +/* Prototypes */ +void options_parse(int argc, char *argv[]); + +static int opt_verbose= 0; +static int opt_displayflag= 0; +static char *opt_servers= NULL; + +int main(int argc, char *argv[]) +{ + unsigned int x; + memcached_return rc; + memcached_st *memc; + memcached_stat_st *stat; + memcached_server_st *servers; + memcached_server_st *server_list; + + options_parse(argc, argv); + + if (!opt_servers) + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + { + fprintf(stderr, "No Servers provided\n"); + exit(1); + } + } + + memc= memcached_create(NULL); + + servers= memcached_servers_parse(opt_servers); + memcached_server_push(memc, servers); + memcached_server_list_free(servers); + + stat= memcached_stat(memc, NULL, &rc); + + if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_SOME_ERRORS) + { + printf("Failure to communicate with servers (%s)\n", + memcached_strerror(memc, rc)); + exit(1); + } + + server_list= memcached_server_list(memc); + + printf("Listing %u Server\n\n", memcached_server_count(memc)); + for (x= 0; x < memcached_server_count(memc); x++) + { + char **list; + char **ptr; + + list= memcached_stat_get_keys(memc, &stat[x], &rc); + assert(list); + assert(rc == MEMCACHED_SUCCESS); + + printf("Server: %s (%u)\n", memcached_server_name(memc, server_list[x]), + memcached_server_port(memc, server_list[x])); + for (ptr= list; *ptr; ptr++) + { + memcached_return rc; + char *value= memcached_stat_get_value(memc, &stat[x], *ptr, &rc); + + printf("\t %s: %s\n", *ptr, value); + free(value); + } + + free(list); + printf("\n"); + } + + free(stat); + free(opt_servers); + + memcached_free(memc); + + return 0; +} + +void options_parse(int argc, char *argv[]) +{ + memcached_programs_help_st help_options[]= + { + {0}, + }; + + static struct option long_options[]= + { + {"version", no_argument, NULL, OPT_VERSION}, + {"help", no_argument, NULL, OPT_HELP}, + {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, + {"debug", no_argument, &opt_verbose, OPT_DEBUG}, + {"servers", required_argument, NULL, OPT_SERVERS}, + {"flag", no_argument, &opt_displayflag, OPT_FLAG}, + {0, 0, 0, 0}, + }; + + int option_index= 0; + int option_rv; + + while (1) + { + option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); + if (option_rv == -1) break; + switch (option_rv) + { + case 0: + break; + case OPT_VERBOSE: /* --verbose or -v */ + opt_verbose = OPT_VERBOSE; + break; + case OPT_DEBUG: /* --debug or -d */ + opt_verbose = OPT_DEBUG; + break; + case OPT_VERSION: /* --version or -V */ + version_command(PROGRAM_NAME); + break; + case OPT_HELP: /* --help or -h */ + help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); + break; + case OPT_SERVERS: /* --servers or -s */ + opt_servers= strdup(optarg); + break; + case '?': + /* getopt_long already printed an error message. */ + exit(1); + default: + abort(); + } + } +} diff --git a/clients/utilities.c b/clients/utilities.c new file mode 100644 index 00000000..d19f57ec --- /dev/null +++ b/clients/utilities.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include "utilities.h" + + +long int timedif(struct timeval a, struct timeval b) +{ + register int us, s; + + us = a.tv_usec - b.tv_usec; + us /= 1000; + s = a.tv_sec - b.tv_sec; + s *= 1000; + return s + us; +} + +void version_command(char *command_name) +{ + printf("%s v%u.%u\n", command_name, 1, 0); + exit(0); +} + +char *lookup_help(memcached_options option) +{ + switch (option) + { + case OPT_SERVERS: return("List which servers you wish to connect to."); + case OPT_VERSION: return("Display the version of the application and then exit."); + case OPT_HELP: return("Diplay this message and then exit."); + case OPT_VERBOSE: return("Give more details on the progression of the application."); + case OPT_DEBUG: return("Provide output only useful for debugging."); + case OPT_FLAG: return("Provide flag information for storage operation."); + case OPT_EXPIRE: return("Set the expire option for the object."); + case OPT_SET: return("Use set command with memcached when storing."); + case OPT_REPLACE: return("Use replace command with memcached when storing."); + case OPT_ADD: return("Use add command with memcached when storing."); + case OPT_SLAP_EXECUTE_NUMBER: return("Number of times to execute the given test."); + case OPT_SLAP_INITIAL_LOAD: return("Number of key pairs to load before executing tests."); + case OPT_SLAP_TEST: return("Test to run."); + case OPT_SLAP_CONCURRENCY: return("Number of users to simulate with load."); + case OPT_SLAP_NON_BLOCK: return("Set TCP up to use non-blocking IO."); + case OPT_SLAP_TCP_NODELAY: return("Set TCP socket up to use nodelay."); + case OPT_FLUSH: return("Flush servers before running tests."); + case OPT_HASH: return("Select hash type."); + }; + + WATCHPOINT_ASSERT(0); + return "forgot to document this function :)"; +} + +void help_command(char *command_name, char *description, + const struct option *long_options, + memcached_programs_help_st *options) +{ + unsigned int x; + + printf("%s v%u.%u\n\n", command_name, 1, 0); + printf("\t%s\n\n", description); + printf("Current options. A '=' means the option takes a value.\n\n"); + + for (x= 0; long_options[x].name; x++) + { + char *help_message; + + printf("\t --%s%c\n", long_options[x].name, + long_options[x].has_arg ? '=' : ' '); + if ((help_message= lookup_help(long_options[x].val))) + printf("\t\t%s\n", help_message); + } + + printf("\n"); + exit(0); +} + +void process_hash_option(memcached_st *memc, char *opt_hash) +{ + uint64_t set; + memcached_return rc; + + if (opt_hash == NULL) + return; + + set= MEMCACHED_HASH_DEFAULT; /* Just here to solve warning */ + if (!strcasecmp(opt_hash, "CRC")) + set= MEMCACHED_HASH_CRC; + else if (!strcasecmp(opt_hash, "FNV1_64")) + set= MEMCACHED_HASH_FNV1_64; + else if (!strcasecmp(opt_hash, "FNV1A_64")) + set= MEMCACHED_HASH_FNV1A_64; + else if (!strcasecmp(opt_hash, "FNV1_32")) + set= MEMCACHED_HASH_FNV1_32; + else if (!strcasecmp(opt_hash, "FNV1A_32")) + set= MEMCACHED_HASH_FNV1A_32; + else if (!strcasecmp(opt_hash, "KETAMA")) + set= MEMCACHED_HASH_KETAMA; + else + { + fprintf(stderr, "hash: type not recognized %s\n", opt_hash); + exit(1); + } + + rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set); + if (rc != MEMCACHED_SUCCESS) + { + fprintf(stderr, "hash: memcache error %s\n", memcached_strerror(memc, rc)); + exit(1); + } +} + diff --git a/clients/utilities.h b/clients/utilities.h new file mode 100644 index 00000000..6d4d72d4 --- /dev/null +++ b/clients/utilities.h @@ -0,0 +1,32 @@ +#include +#include +#include +#include "client_options.h" +#include "libmemcached_config.h" + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +typedef struct memcached_programs_help_st memcached_programs_help_st; + +struct memcached_programs_help_st +{ + char *not_used_yet; +}; + +char *strdup_cleanup(const char *str); +void cleanup(void); +long int timedif(struct timeval a, struct timeval b); +void version_command(char *command_name); +void help_command(char *command_name, char *description, + const struct option *long_options, + memcached_programs_help_st *options); +void process_hash_option(memcached_st *memc, char *opt_hash); diff --git a/configure.ac b/configure.ac index b70514ad..90072831 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ -AC_INIT(src/memcat.c) +AC_INIT(clients/memcat.c) AC_CONFIG_AUX_DIR(config) -AM_CONFIG_HEADER(include/libmemcached_config.h) +AM_CONFIG_HEADER(libmemcached/libmemcached_config.h) AC_CANONICAL_SYSTEM MEMCACHED_LIBRARY_NAME=libmemcached @@ -71,4 +71,4 @@ AC_C_CONST AC_HEADER_TIME AC_TYPE_SIZE_T AC_SEARCH_LIBS(getopt_long, gnugetopt) -AC_OUTPUT(Makefile src/Makefile tests/Makefile docs/Makefile lib/Makefile include/Makefile support/Makefile support/libmemcached.pc support/libmemcached.spec) +AC_OUTPUT(Makefile clients/Makefile tests/Makefile docs/Makefile libmemcached/Makefile support/Makefile support/libmemcached.pc support/libmemcached.spec) diff --git a/include/Makefile.am b/include/Makefile.am deleted file mode 100644 index d41e7b8b..00000000 --- a/include/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -INCLUDES = include - -pkginclude_HEADERS= memcached.h memcached.hh diff --git a/include/memcached.h b/include/memcached.h deleted file mode 100644 index 3178866d..00000000 --- a/include/memcached.h +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Summary: interface for memcached server - * Description: main include file for libmemcached - * - * Copy: See Copyright for the status of this software. - * - * Author: Brian Aker - */ - -#ifndef __MEMCACHED_H__ -#define __MEMCACHED_H__ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* These are Private and should not be used by applications */ -#define MEMCACHED_VERSION_STRING_LENGTH 12 - -/* Public defines */ -#define MEMCACHED_DEFAULT_PORT 11211 -#define MEMCACHED_MAX_KEY 251 /* We add one to have it null terminated */ -#define MEMCACHED_MAX_BUFFER 8196 -#define MEMCACHED_MAX_HOST_LENGTH 64 -#define MEMCACHED_WHEEL_SIZE 1024 -#define MEMCACHED_STRIDE 4 -#define MEMCACHED_DEFAULT_TIMEOUT INT32_MAX - -/* string value */ -#define LIBMEMCACHED_VERSION_STRING "0.17" - -typedef enum { - MEMCACHED_SUCCESS, - MEMCACHED_FAILURE, - MEMCACHED_HOST_LOOKUP_FAILURE, - MEMCACHED_CONNECTION_FAILURE, - MEMCACHED_CONNECTION_BIND_FAILURE, - MEMCACHED_WRITE_FAILURE, - MEMCACHED_READ_FAILURE, - MEMCACHED_UNKNOWN_READ_FAILURE, - MEMCACHED_PROTOCOL_ERROR, - MEMCACHED_CLIENT_ERROR, - MEMCACHED_SERVER_ERROR, - MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE, - MEMCACHED_DATA_EXISTS, - MEMCACHED_DATA_DOES_NOT_EXIST, - MEMCACHED_NOTSTORED, - MEMCACHED_STORED, - MEMCACHED_NOTFOUND, - MEMCACHED_MEMORY_ALLOCATION_FAILURE, - MEMCACHED_PARTIAL_READ, - MEMCACHED_SOME_ERRORS, - MEMCACHED_NO_SERVERS, - MEMCACHED_END, - MEMCACHED_DELETED, - MEMCACHED_VALUE, - MEMCACHED_STAT, - MEMCACHED_ERRNO, - MEMCACHED_FAIL_UNIX_SOCKET, - MEMCACHED_NOT_SUPPORTED, - MEMCACHED_NO_KEY_PROVIDED, - MEMCACHED_FETCH_NOTFINISHED, - MEMCACHED_TIMEOUT, - MEMCACHED_BUFFERED, - MEMCACHED_BAD_KEY_PROVIDED, - MEMCACHED_MAXIMUM_RETURN, /* Always add new error code before */ -} memcached_return; - -typedef struct memcached_st memcached_st; -typedef struct memcached_stat_st memcached_stat_st; -typedef struct memcached_result_st memcached_result_st; -typedef struct memcached_string_st memcached_string_st; -typedef struct memcached_server_st memcached_server_st; -typedef memcached_return (*memcached_clone_func)(memcached_st *parent, memcached_st *clone); -typedef memcached_return (*memcached_cleanup_func)(memcached_st *ptr); -typedef void (*memcached_free_function)(memcached_st *ptr, void *mem); -typedef void *(*memcached_malloc_function)(memcached_st *ptr, const size_t size); -typedef void *(*memcached_realloc_function)(memcached_st *ptr, void *mem, const size_t size); -typedef memcached_return (*memcached_execute_function)(memcached_st *ptr, memcached_result_st *result, void *context); -typedef memcached_return (*memcached_server_function)(memcached_st *ptr, memcached_server_st *server, void *context); - -typedef enum { - MEMCACHED_DISTRIBUTION_MODULA, - MEMCACHED_DISTRIBUTION_CONSISTENT, -} memcached_server_distribution; - -typedef enum { - MEMCACHED_BEHAVIOR_NO_BLOCK, - MEMCACHED_BEHAVIOR_TCP_NODELAY, - MEMCACHED_BEHAVIOR_HASH, - MEMCACHED_BEHAVIOR_KETAMA, - MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, - MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, - MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, - MEMCACHED_BEHAVIOR_SUPPORT_CAS, - MEMCACHED_BEHAVIOR_POLL_TIMEOUT, - MEMCACHED_BEHAVIOR_DISTRIBUTION, - MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, - MEMCACHED_BEHAVIOR_USER_DATA, - MEMCACHED_BEHAVIOR_SORT_HOSTS, - MEMCACHED_BEHAVIOR_VERIFY_KEY, - MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, - MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, -} memcached_behavior; - -typedef enum { - MEMCACHED_CALLBACK_USER_DATA, - MEMCACHED_CALLBACK_CLEANUP_FUNCTION, - MEMCACHED_CALLBACK_CLONE_FUNCTION, - MEMCACHED_CALLBACK_MALLOC_FUNCTION, - MEMCACHED_CALLBACK_REALLOC_FUNCTION, - MEMCACHED_CALLBACK_FREE_FUNCTION, -} memcached_callback; - -typedef enum { - MEMCACHED_HASH_DEFAULT= 0, - MEMCACHED_HASH_MD5, - MEMCACHED_HASH_CRC, - MEMCACHED_HASH_FNV1_64, - MEMCACHED_HASH_FNV1A_64, - MEMCACHED_HASH_FNV1_32, - MEMCACHED_HASH_FNV1A_32, - MEMCACHED_HASH_KETAMA, - MEMCACHED_HASH_HSIEH, - MEMCACHED_HASH_MURMUR, -} memcached_hash; - -typedef enum { - MEMCACHED_CONNECTION_UNKNOWN, - MEMCACHED_CONNECTION_TCP, - MEMCACHED_CONNECTION_UDP, - MEMCACHED_CONNECTION_UNIX_SOCKET, -} memcached_connection; - -typedef enum { - MEMCACHED_NOT_ALLOCATED, - MEMCACHED_ALLOCATED, - MEMCACHED_USED, -} memcached_allocated; - -struct memcached_server_st { - char hostname[MEMCACHED_MAX_HOST_LENGTH]; - unsigned int port; - int fd; - int cached_errno; - unsigned int cursor_active; - char write_buffer[MEMCACHED_MAX_BUFFER]; - size_t write_buffer_offset; - char read_buffer[MEMCACHED_MAX_BUFFER]; - size_t read_data_length; - size_t read_buffer_length; - char *read_ptr; - memcached_allocated sockaddr_inited; - struct addrinfo *address_info; - memcached_connection type; - uint8_t major_version; - uint8_t minor_version; - uint8_t micro_version; - uint16_t count; - time_t next_retry; - memcached_st *root; -}; - -struct memcached_stat_st { - uint32_t pid; - uint32_t uptime; - uint32_t threads; - uint32_t time; - uint32_t pointer_size; - uint32_t rusage_user_seconds; - uint32_t rusage_user_microseconds; - uint32_t rusage_system_seconds; - uint32_t rusage_system_microseconds; - uint32_t curr_items; - uint32_t total_items; - uint64_t limit_maxbytes; - uint32_t curr_connections; - uint32_t total_connections; - uint32_t connection_structures; - uint64_t bytes; - uint64_t cmd_get; - uint64_t cmd_set; - uint64_t get_hits; - uint64_t get_misses; - uint64_t evictions; - uint64_t bytes_read; - uint64_t bytes_written; - char version[MEMCACHED_VERSION_STRING_LENGTH]; -}; - -struct memcached_string_st { - memcached_st *root; - memcached_allocated is_allocated; - char *string; - char *end; - size_t current_size; - size_t block_size; -}; - -struct memcached_result_st { - memcached_allocated is_allocated; - memcached_st *root; - char key[MEMCACHED_MAX_KEY]; - size_t key_length; - memcached_string_st value; - uint32_t flags; - uint64_t cas; - /* Add result callback function */ -}; - -struct memcached_st { - memcached_allocated is_allocated; - memcached_server_st *hosts; - unsigned int number_of_hosts; - unsigned int cursor_server; - int cached_errno; - uint32_t flags; - int send_size; - int recv_size; - int32_t poll_timeout; - int32_t connect_timeout; - int32_t retry_timeout; - memcached_result_st result; - memcached_hash hash; - memcached_server_distribution distribution; - void *user_data; - unsigned int wheel[MEMCACHED_WHEEL_SIZE]; - memcached_clone_func on_clone; - memcached_cleanup_func on_cleanup; - memcached_free_function call_free; - memcached_malloc_function call_malloc; - memcached_realloc_function call_realloc; -#ifdef NOT_USED /* Future Use */ - uint8_t replicas; - memcached_return warning; -#endif -}; - -/* Public API */ -const char * memcached_lib_version(void); - -memcached_st *memcached_create(memcached_st *ptr); -void memcached_free(memcached_st *ptr); -memcached_st *memcached_clone(memcached_st *clone, memcached_st *ptr); - -memcached_return memcached_delete(memcached_st *ptr, char *key, size_t key_length, - time_t expiration); -memcached_return memcached_increment(memcached_st *ptr, - char *key, size_t key_length, - uint32_t offset, - uint64_t *value); -memcached_return memcached_decrement(memcached_st *ptr, - char *key, size_t key_length, - uint32_t offset, - uint64_t *value); -void memcached_stat_free(memcached_st *, memcached_stat_st *); -memcached_stat_st *memcached_stat(memcached_st *ptr, char *args, memcached_return *error); -memcached_return memcached_stat_servername(memcached_stat_st *stat, char *args, - char *hostname, unsigned int port); -memcached_return memcached_flush(memcached_st *ptr, time_t expiration); -memcached_return memcached_verbosity(memcached_st *ptr, unsigned int verbosity); -void memcached_quit(memcached_st *ptr); -char *memcached_strerror(memcached_st *ptr, memcached_return rc); -memcached_return memcached_behavior_set(memcached_st *ptr, memcached_behavior flag, void *data); -uint64_t memcached_behavior_get(memcached_st *ptr, memcached_behavior flag); - -/* All of the functions for adding data to the server */ -memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags); -memcached_return memcached_add(memcached_st *ptr, char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags); -memcached_return memcached_replace(memcached_st *ptr, char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags); -memcached_return memcached_append(memcached_st *ptr, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags); -memcached_return memcached_prepend(memcached_st *ptr, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags); -memcached_return memcached_cas(memcached_st *ptr, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags, - uint64_t cas); - -/* Get functions */ -char *memcached_get(memcached_st *ptr, char *key, size_t key_length, - size_t *value_length, - uint32_t *flags, - memcached_return *error); -memcached_return memcached_mget(memcached_st *ptr, - char **keys, size_t *key_length, - unsigned int number_of_keys); -char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, - size_t *value_length, uint32_t *flags, - memcached_return *error); -memcached_result_st *memcached_fetch_result(memcached_st *ptr, - memcached_result_st *result, - memcached_return *error); - -/* Server Public functions */ -#define memcached_server_count(A) (A)->number_of_hosts -#define memcached_server_name(A,B) (B).hostname -#define memcached_server_port(A,B) (B).port -#define memcached_server_list(A) (A)->hosts -#define memcached_server_response_count(A) (A)->cursor_active - - -memcached_return memcached_server_add_udp(memcached_st *ptr, - char *hostname, - unsigned int port); -memcached_return memcached_server_add_unix_socket(memcached_st *ptr, - char *filename); -memcached_return memcached_server_add(memcached_st *ptr, char *hostname, - unsigned int port); -void memcached_server_list_free(memcached_server_st *ptr); -memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list); - -memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, - char *hostname, unsigned int port, - memcached_return *error); -unsigned int memcached_server_list_count(memcached_server_st *ptr); -memcached_server_st *memcached_servers_parse(char *server_strings); - -char *memcached_stat_get_value(memcached_st *ptr, memcached_stat_st *stat, - char *key, memcached_return *error); -char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *stat, - memcached_return *error); - -char *memcached_get_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - size_t *value_length, - uint32_t *flags, - memcached_return *error); - -memcached_return memcached_mget_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char **keys, size_t *key_length, - unsigned int number_of_keys); - -memcached_return memcached_set_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags); - -memcached_return memcached_add_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags); - -memcached_return memcached_replace_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags); - -memcached_return memcached_prepend_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags); - -memcached_return memcached_append_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags); - -memcached_return memcached_cas_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags, - uint64_t cas); -memcached_return memcached_delete_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - time_t expiration); - -memcached_return memcached_fetch_execute(memcached_st *ptr, - unsigned int (*callback[])(memcached_st *ptr, memcached_result_st *result, void *context), - void *context, - unsigned int number_of_callbacks - ); - -memcached_return memcached_callback_set(memcached_st *ptr, - memcached_callback flag, - void *data); -void *memcached_callback_get(memcached_st *ptr, - memcached_callback flag, - memcached_return *error); - -memcached_return memcached_server_cursor(memcached_st *ptr, - memcached_server_function *callback, - void *context, - unsigned int number_of_callbacks); - -/* Result Struct */ -void memcached_result_free(memcached_result_st *result); -memcached_result_st *memcached_result_create(memcached_st *ptr, - memcached_result_st *result); -#define memcached_result_key_value(A) (A)->key -#define memcached_result_key_length(A) (A)->key_length -#ifdef FIX -#define memcached_result_value(A) memcached_string_value((A)->value) -#define memcached_result_length(A) memcached_string_length((A)->value) -#else -char *memcached_result_value(memcached_result_st *ptr); -size_t memcached_result_length(memcached_result_st *ptr); -#endif -#define memcached_result_flags(A) (A)->flags -#define memcached_result_cas(A) (A)->cas - - -#ifndef __WATCHPOINT_H__ -#define __WATCHPOINT_H__ -/* Some personal debugging functions */ -#ifdef HAVE_DEBUG -#define WATCHPOINT fprintf(stderr, "\nWATCHPOINT %s:%d (%s)\n", __FILE__, __LINE__,__func__);fflush(stdout); -#ifdef __MEMCACHED_H__ -#define WATCHPOINT_ERROR(A) fprintf(stderr, "\nWATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout); -#define WATCHPOINT_IFERROR(A) if(A != MEMCACHED_SUCCESS)fprintf(stderr, "\nWATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout); -#endif -#define WATCHPOINT_STRING(A) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s\n", __FILE__, __LINE__,__func__,A);fflush(stdout); -#define WATCHPOINT_STRING_LENGTH(A,B) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %.*s\n", __FILE__, __LINE__,__func__,(int)B,A);fflush(stdout); -#define WATCHPOINT_NUMBER(A) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %zu\n", __FILE__, __LINE__,__func__,(size_t)(A));fflush(stdout); -#define WATCHPOINT_ERRNO(A) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s\n", __FILE__, __LINE__,__func__, strerror(A));fflush(stdout); -#define WATCHPOINT_ASSERT(A) assert((A)); -#else -#define WATCHPOINT -#ifdef __MEMCACHED_H__ -#define WATCHPOINT_ERROR(A) -#define WATCHPOINT_IFERROR(A) -#endif -#define WATCHPOINT_STRING(A) -#define WATCHPOINT_NUMBER(A) -#define WATCHPOINT_ERRNO(A) -#define WATCHPOINT_ASSERT(A) -#endif - -#endif /* __WATCHPOINT_H__ */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __MEMCACHED_H__ */ diff --git a/include/memcached.hh b/include/memcached.hh deleted file mode 100644 index e482f4bf..00000000 --- a/include/memcached.hh +++ /dev/null @@ -1,102 +0,0 @@ -#ifdef USE_PRAGMA_INTERFACE -#pragma interface /* gcc class implementation */ -#endif - -#include -#include -#include - -class Memcached -{ - memcached_st memc; - -public: - - Memcached() - { - memcached_create(&memc); - } - - Memcached(memcached_st *clone) - { - WATCHPOINT; - memcached_clone(&memc, clone); - WATCHPOINT; - } - - char *get(char *key, size_t *value_length) - { - uint32_t flags; - memcached_return rc; - - return memcached_get(&memc, key, strlen(key), - value_length, &flags, &rc); - } - - char *get_by_key(char *master_key, char *key, size_t *value_length) - { - uint32_t flags; - memcached_return rc; - - return memcached_get_by_key(&memc, master_key, strlen(master_key), key, strlen(key), - value_length, &flags, &rc); - } - - memcached_return mget(char **keys, size_t *key_length, unsigned int number_of_keys) - { - - return memcached_mget(&memc, keys, key_length, number_of_keys); - } - - memcached_return set(char *key, char *value, size_t value_length) - { - return memcached_set(&memc, key, strlen(key), - value, value_length, - (time_t)0, (uint32_t)0); - } - - memcached_return set_by_key(char *master_key, char *key, char *value, size_t value_length) - { - return memcached_set_by_key(&memc, master_key, strlen(master_key), - key, strlen(key), - value, value_length, - (time_t)0, - (uint32_t)0 ); - } - - - memcached_return add(char *key, char *value, size_t value_length) - { - return memcached_add(&memc, key, strlen(key), - value, value_length, - (time_t)0, (uint32_t)0); - } - - memcached_return replace(char *key, char *value, size_t value_length) - { - return memcached_replace(&memc, key, strlen(key), - value, value_length, - (time_t)0, (uint32_t)0); - } - - memcached_return prepend(char *key, char *value, size_t value_length) - { - return memcached_prepend(&memc, key, strlen(key), - value, value_length, - (time_t)0, - (uint32_t)0); - } - - - memcached_return append(char *key, char *value, size_t value_length) - { - return memcached_append(&memc, key, strlen(key), - value, value_length, - (time_t)0, - (uint32_t)0); - } - ~Memcached() - { - memcached_free(&memc); - } -}; diff --git a/lib/Makefile.am b/lib/Makefile.am deleted file mode 100644 index 7e99091a..00000000 --- a/lib/Makefile.am +++ /dev/null @@ -1,74 +0,0 @@ -EXTRA_DIST = libmemcached_probes.d - -INCLUDES = -I$(top_builddir)/include -I$(top_builddir) -LIBS = - -DTRACE = @DTRACE@ -DTRACEFLAGS = @DTRACEFLAGS@ -DTRACEFILES = memcached.o \ - memcached_strerror.o \ - memcached_connect.o \ - memcached_response.o \ - memcached_get.o \ - memcached_storage.o \ - memcached_delete.o \ - memcached_hash.o \ - memcached_auto.o \ - memcached_verbosity.o \ - memcached_quit.o \ - memcached_flush.o \ - memcached_string.o \ - memcached_stats.o - -noinst_HEADERS = libmemcached_probes.h \ - memcached_io.h \ - common.h - -lib_LTLIBRARIES = libmemcached.la - -libmemcached_la_SOURCES = crc.c \ - hsieh_hash.c \ - memcached.c \ - memcached_auto.c \ - memcached_behavior.c \ - memcached_callback.c \ - memcached_connect.c \ - memcached_delete.c \ - memcached_do.c \ - memcached_fetch.c \ - memcached_fetch_execute.c \ - memcached_flush.c \ - memcached_get.c \ - memcached_hash.c \ - memcached_hosts.c \ - memcached_io.c \ - md5.c \ - memcached_key.c \ - memcached_quit.c \ - memcached_parse.c \ - memcached_response.c \ - memcached_result.c \ - memcached_server.c \ - memcached_storage.c \ - memcached_string.c \ - memcached_stats.c \ - memcached_strerror.c \ - memcached_verbosity.c \ - memcached_version.c \ - murmur_hash.c - -libmemcached_la_LIBADD = -libmemcached_la_LDFLAGS = -version-info $(MEMCACHED_LIBRARY_VERSION) - -if HAVE_DTRACE - libmemcached_la_LIBADD += libmemcached_probes.o -endif - -libmemcached_probes.h: libmemcached_probes.d - $(DTRACE) $(DTRACEFLAGS) -h -s libmemcached_probes.d - mv libmemcached_probes.h libmemcached_probes.h.bak - sed "s/#include //g" libmemcached_probes.h.bak > libmemcached_probes.h - rm libmemcached_probes.h.bak - -libmemcached_probes.o: - $(DTRACE) $(DTRACEFLAGS) -G -s libmemcached_probes.d $(DTRACEFILES) diff --git a/lib/common.h b/lib/common.h deleted file mode 100644 index a70e65f3..00000000 --- a/lib/common.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - Common include file for libmemached -*/ - -#ifndef __COMMON_H__ -#define __COMMON_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - - - -#include -#include "memcached_io.h" - -#include - -#if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) -#define __builtin_expect(x, expected_value) (x) - -#define likely(x) __builtin_expect((x),1) -#define unlikely(x) __builtin_expect((x),0) - -#else - -#define likely(x) if((x)) -#define unlikely(x) if((x)) - -#endif - -#ifdef HAVE_DTRACE -#define _DTRACE_VERSION 1 -#else -#undef _DTRACE_VERSION -#endif - -#include "libmemcached_probes.h" - -#define MEMCACHED_BLOCK_SIZE 1024 -#define MEMCACHED_DEFAULT_COMMAND_SIZE 350 -#define SMALL_STRING_LEN 1024 -#define HUGE_STRING_LEN 8196 - - -typedef enum { - MEM_NO_BLOCK= (1 << 0), - MEM_TCP_NODELAY= (1 << 1), - MEM_REUSE_MEMORY= (1 << 2), - MEM_USE_MD5= (1 << 3), - MEM_USE_KETAMA= (1 << 4), - MEM_USE_CRC= (1 << 5), - MEM_USE_CACHE_LOOKUPS= (1 << 6), - MEM_SUPPORT_CAS= (1 << 7), - MEM_BUFFER_REQUESTS= (1 << 8), - MEM_USE_SORT_HOSTS= (1 << 9), - MEM_VERIFY_KEY= (1 << 10), -} memcached_flags; - -/* Hashing algo */ -void md5_signature(unsigned char *key, unsigned int length, unsigned char *result); -uint32_t hash_crc32(const char *data, - size_t data_len); -uint32_t hsieh_hash(char *key, size_t key_length); -uint32_t murmur_hash(char *key, size_t key_length); - -memcached_return memcached_connect(memcached_server_st *ptr); -memcached_return memcached_response(memcached_server_st *ptr, - char *buffer, size_t buffer_length, - memcached_result_st *result); -unsigned int memcached_generate_hash(memcached_st *ptr, char *key, size_t key_length); -void memcached_quit_server(memcached_server_st *ptr, uint8_t io_death); - -#define memcached_server_response_increment(A) (A)->cursor_active++ -#define memcached_server_response_decrement(A) (A)->cursor_active-- -#define memcached_server_response_reset(A) (A)->cursor_active=0 - -/* String Struct */ -#define memcached_string_length(A) (size_t)((A)->end - (A)->string) -#define memcached_string_set_length(A, B) (A)->end= (A)->string + B -#define memcached_string_size(A) (A)->current_size -#define memcached_string_value(A) (A)->string - -memcached_string_st *memcached_string_create(memcached_st *ptr, - memcached_string_st *string, - size_t initial_size); -memcached_return memcached_string_check(memcached_string_st *string, size_t need); -char *memcached_string_c_copy(memcached_string_st *string); -memcached_return memcached_string_append_character(memcached_string_st *string, - char character); -memcached_return memcached_string_append(memcached_string_st *string, - char *value, size_t length); -size_t memcached_string_backspace(memcached_string_st *string, size_t remove); -memcached_return memcached_string_reset(memcached_string_st *string); -void memcached_string_free(memcached_string_st *string); -memcached_return memcached_do(memcached_server_st *ptr, char *commmand, - size_t command_length, uint8_t with_flush); -memcached_return memcached_version(memcached_st *ptr); -memcached_return value_fetch(memcached_server_st *ptr, - char *buffer, - memcached_result_st *result); -void server_list_free(memcached_st *ptr, memcached_server_st *servers); - -memcached_return memcachd_key_test(char **keys, size_t *key_length, - unsigned int number_of_keys); - -#endif /* __COMMON_H__ */ diff --git a/lib/crc.c b/lib/crc.c deleted file mode 100644 index ed22adc4..00000000 --- a/lib/crc.c +++ /dev/null @@ -1,87 +0,0 @@ -/* The crc32 functions and data was originally written by Spencer - * Garrett and was gleaned from the PostgreSQL source - * tree via the files contrib/ltree/crc32.[ch] and from FreeBSD at - * src/usr.bin/cksum/crc32.c. - */ - -#include "common.h" - -static const uint32_t crc32tab[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, -}; - - -uint32_t hash_crc32(const char *key, size_t key_length) -{ - uint32_t x; - uint32_t crc; - crc= ~0; - - for (x= 0; x < key_length; x++) - crc= (crc >> 8) ^ crc32tab[(crc ^ (key[x])) & 0xff]; - - return ~crc; -} diff --git a/lib/hsieh_hash.c b/lib/hsieh_hash.c deleted file mode 100644 index 9f42a94d..00000000 --- a/lib/hsieh_hash.c +++ /dev/null @@ -1,65 +0,0 @@ -/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh - * derivative license. - * See: http://www.azillionmonkeys.com/qed/weblicense.html for license - * details. - * http://www.azillionmonkeys.com/qed/hash.html -*/ - -#include "common.h" - -#undef get16bits -#if (defined(__GNUC__) && defined(__i386__)) -#define get16bits(d) (*((const uint16_t *) (d))) -#endif - -#if !defined (get16bits) -#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ - +(uint32_t)(((const uint8_t *)(d))[0]) ) -#endif - -uint32_t hsieh_hash(char *key, size_t key_length) -{ - uint32_t hash = 0, tmp; - int rem; - - if (key_length <= 0 || key == NULL) return 0; - - rem = key_length & 3; - key_length >>= 2; - - /* Main loop */ - for (;key_length > 0; key_length--) { - hash += get16bits (key); - tmp = (get16bits (key+2) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - key += 2*sizeof (uint16_t); - hash += hash >> 11; - } - - /* Handle end cases */ - switch (rem) { - case 3: hash += get16bits (key); - hash ^= hash << 16; - hash ^= key[sizeof (uint16_t)] << 18; - hash += hash >> 11; - break; - case 2: hash += get16bits (key); - hash ^= hash << 11; - hash += hash >> 17; - break; - case 1: hash += *key; - hash ^= hash << 10; - hash += hash >> 1; - } - - /* Force "avalanching" of final 127 bits */ - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - - return hash; -} - diff --git a/lib/libmemcached_probes.d b/lib/libmemcached_probes.d deleted file mode 100644 index ae68e34c..00000000 --- a/lib/libmemcached_probes.d +++ /dev/null @@ -1,24 +0,0 @@ -provider libmemcached { - probe memcached_delete_start(); - probe memcached_delete_end(); - probe memcached_increment_start(); - probe memcached_increment_end(); - probe memcached_decrement_start(); - probe memcached_decrement_end(); - probe memcached_flush_start(); - probe memcached_flush_end(); - probe memcached_set_start(); - probe memcached_set_end(); - probe memcached_add_start(); - probe memcached_add_end(); - probe memcached_replace_start(); - probe memcached_replace_end(); - probe memcached_get_start(); - probe memcached_get_end(); - probe memcached_mget_start(); - probe memcached_mget_end(); - probe memcached_connect_start(); - probe memcached_connect_end(); - probe memcached_server_add_start(); - probe memcached_server_add_end(); -}; diff --git a/lib/libmemcached_probes.h b/lib/libmemcached_probes.h deleted file mode 100644 index cf59cc59..00000000 --- a/lib/libmemcached_probes.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Generated by dtrace(1M). - */ - -#ifndef _LIBMEMCACHED_PROBES_H -#define _LIBMEMCACHED_PROBES_H - - - -#ifdef __cplusplus -extern "C" { -#endif - -#if _DTRACE_VERSION - -#define LIBMEMCACHED_MEMCACHED_ADD_END() \ - __dtrace_libmemcached___memcached_add_end() -#define LIBMEMCACHED_MEMCACHED_ADD_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_add_end() -#define LIBMEMCACHED_MEMCACHED_ADD_START() \ - __dtrace_libmemcached___memcached_add_start() -#define LIBMEMCACHED_MEMCACHED_ADD_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_add_start() -#define LIBMEMCACHED_MEMCACHED_CONNECT_END() \ - __dtrace_libmemcached___memcached_connect_end() -#define LIBMEMCACHED_MEMCACHED_CONNECT_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_connect_end() -#define LIBMEMCACHED_MEMCACHED_CONNECT_START() \ - __dtrace_libmemcached___memcached_connect_start() -#define LIBMEMCACHED_MEMCACHED_CONNECT_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_connect_start() -#define LIBMEMCACHED_MEMCACHED_DECREMENT_END() \ - __dtrace_libmemcached___memcached_decrement_end() -#define LIBMEMCACHED_MEMCACHED_DECREMENT_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_decrement_end() -#define LIBMEMCACHED_MEMCACHED_DECREMENT_START() \ - __dtrace_libmemcached___memcached_decrement_start() -#define LIBMEMCACHED_MEMCACHED_DECREMENT_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_decrement_start() -#define LIBMEMCACHED_MEMCACHED_DELETE_END() \ - __dtrace_libmemcached___memcached_delete_end() -#define LIBMEMCACHED_MEMCACHED_DELETE_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_delete_end() -#define LIBMEMCACHED_MEMCACHED_DELETE_START() \ - __dtrace_libmemcached___memcached_delete_start() -#define LIBMEMCACHED_MEMCACHED_DELETE_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_delete_start() -#define LIBMEMCACHED_MEMCACHED_FLUSH_END() \ - __dtrace_libmemcached___memcached_flush_end() -#define LIBMEMCACHED_MEMCACHED_FLUSH_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_flush_end() -#define LIBMEMCACHED_MEMCACHED_FLUSH_START() \ - __dtrace_libmemcached___memcached_flush_start() -#define LIBMEMCACHED_MEMCACHED_FLUSH_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_flush_start() -#define LIBMEMCACHED_MEMCACHED_GET_END() \ - __dtrace_libmemcached___memcached_get_end() -#define LIBMEMCACHED_MEMCACHED_GET_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_get_end() -#define LIBMEMCACHED_MEMCACHED_GET_START() \ - __dtrace_libmemcached___memcached_get_start() -#define LIBMEMCACHED_MEMCACHED_GET_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_get_start() -#define LIBMEMCACHED_MEMCACHED_INCREMENT_END() \ - __dtrace_libmemcached___memcached_increment_end() -#define LIBMEMCACHED_MEMCACHED_INCREMENT_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_increment_end() -#define LIBMEMCACHED_MEMCACHED_INCREMENT_START() \ - __dtrace_libmemcached___memcached_increment_start() -#define LIBMEMCACHED_MEMCACHED_INCREMENT_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_increment_start() -#define LIBMEMCACHED_MEMCACHED_MGET_END() \ - __dtrace_libmemcached___memcached_mget_end() -#define LIBMEMCACHED_MEMCACHED_MGET_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_mget_end() -#define LIBMEMCACHED_MEMCACHED_MGET_START() \ - __dtrace_libmemcached___memcached_mget_start() -#define LIBMEMCACHED_MEMCACHED_MGET_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_mget_start() -#define LIBMEMCACHED_MEMCACHED_REPLACE_END() \ - __dtrace_libmemcached___memcached_replace_end() -#define LIBMEMCACHED_MEMCACHED_REPLACE_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_replace_end() -#define LIBMEMCACHED_MEMCACHED_REPLACE_START() \ - __dtrace_libmemcached___memcached_replace_start() -#define LIBMEMCACHED_MEMCACHED_REPLACE_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_replace_start() -#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_END() \ - __dtrace_libmemcached___memcached_server_add_end() -#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_server_add_end() -#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_START() \ - __dtrace_libmemcached___memcached_server_add_start() -#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_server_add_start() -#define LIBMEMCACHED_MEMCACHED_SET_END() \ - __dtrace_libmemcached___memcached_set_end() -#define LIBMEMCACHED_MEMCACHED_SET_END_ENABLED() \ - __dtraceenabled_libmemcached___memcached_set_end() -#define LIBMEMCACHED_MEMCACHED_SET_START() \ - __dtrace_libmemcached___memcached_set_start() -#define LIBMEMCACHED_MEMCACHED_SET_START_ENABLED() \ - __dtraceenabled_libmemcached___memcached_set_start() - - -extern void __dtrace_libmemcached___memcached_add_end(void); -extern int __dtraceenabled_libmemcached___memcached_add_end(void); -extern void __dtrace_libmemcached___memcached_add_start(void); -extern int __dtraceenabled_libmemcached___memcached_add_start(void); -extern void __dtrace_libmemcached___memcached_connect_end(void); -extern int __dtraceenabled_libmemcached___memcached_connect_end(void); -extern void __dtrace_libmemcached___memcached_connect_start(void); -extern int __dtraceenabled_libmemcached___memcached_connect_start(void); -extern void __dtrace_libmemcached___memcached_decrement_end(void); -extern int __dtraceenabled_libmemcached___memcached_decrement_end(void); -extern void __dtrace_libmemcached___memcached_decrement_start(void); -extern int __dtraceenabled_libmemcached___memcached_decrement_start(void); -extern void __dtrace_libmemcached___memcached_delete_end(void); -extern int __dtraceenabled_libmemcached___memcached_delete_end(void); -extern void __dtrace_libmemcached___memcached_delete_start(void); -extern int __dtraceenabled_libmemcached___memcached_delete_start(void); -extern void __dtrace_libmemcached___memcached_flush_end(void); -extern int __dtraceenabled_libmemcached___memcached_flush_end(void); -extern void __dtrace_libmemcached___memcached_flush_start(void); -extern int __dtraceenabled_libmemcached___memcached_flush_start(void); -extern void __dtrace_libmemcached___memcached_get_end(void); -extern int __dtraceenabled_libmemcached___memcached_get_end(void); -extern void __dtrace_libmemcached___memcached_get_start(void); -extern int __dtraceenabled_libmemcached___memcached_get_start(void); -extern void __dtrace_libmemcached___memcached_increment_end(void); -extern int __dtraceenabled_libmemcached___memcached_increment_end(void); -extern void __dtrace_libmemcached___memcached_increment_start(void); -extern int __dtraceenabled_libmemcached___memcached_increment_start(void); -extern void __dtrace_libmemcached___memcached_mget_end(void); -extern int __dtraceenabled_libmemcached___memcached_mget_end(void); -extern void __dtrace_libmemcached___memcached_mget_start(void); -extern int __dtraceenabled_libmemcached___memcached_mget_start(void); -extern void __dtrace_libmemcached___memcached_replace_end(void); -extern int __dtraceenabled_libmemcached___memcached_replace_end(void); -extern void __dtrace_libmemcached___memcached_replace_start(void); -extern int __dtraceenabled_libmemcached___memcached_replace_start(void); -extern void __dtrace_libmemcached___memcached_server_add_end(void); -extern int __dtraceenabled_libmemcached___memcached_server_add_end(void); -extern void __dtrace_libmemcached___memcached_server_add_start(void); -extern int __dtraceenabled_libmemcached___memcached_server_add_start(void); -extern void __dtrace_libmemcached___memcached_set_end(void); -extern int __dtraceenabled_libmemcached___memcached_set_end(void); -extern void __dtrace_libmemcached___memcached_set_start(void); -extern int __dtraceenabled_libmemcached___memcached_set_start(void); - -#else - -#define LIBMEMCACHED_MEMCACHED_ADD_END() -#define LIBMEMCACHED_MEMCACHED_ADD_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_ADD_START() -#define LIBMEMCACHED_MEMCACHED_ADD_START_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_CONNECT_END() -#define LIBMEMCACHED_MEMCACHED_CONNECT_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_CONNECT_START() -#define LIBMEMCACHED_MEMCACHED_CONNECT_START_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_DECREMENT_END() -#define LIBMEMCACHED_MEMCACHED_DECREMENT_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_DECREMENT_START() -#define LIBMEMCACHED_MEMCACHED_DECREMENT_START_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_DELETE_END() -#define LIBMEMCACHED_MEMCACHED_DELETE_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_DELETE_START() -#define LIBMEMCACHED_MEMCACHED_DELETE_START_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_FLUSH_END() -#define LIBMEMCACHED_MEMCACHED_FLUSH_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_FLUSH_START() -#define LIBMEMCACHED_MEMCACHED_FLUSH_START_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_GET_END() -#define LIBMEMCACHED_MEMCACHED_GET_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_GET_START() -#define LIBMEMCACHED_MEMCACHED_GET_START_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_INCREMENT_END() -#define LIBMEMCACHED_MEMCACHED_INCREMENT_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_INCREMENT_START() -#define LIBMEMCACHED_MEMCACHED_INCREMENT_START_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_MGET_END() -#define LIBMEMCACHED_MEMCACHED_MGET_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_MGET_START() -#define LIBMEMCACHED_MEMCACHED_MGET_START_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_REPLACE_END() -#define LIBMEMCACHED_MEMCACHED_REPLACE_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_REPLACE_START() -#define LIBMEMCACHED_MEMCACHED_REPLACE_START_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_END() -#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_START() -#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_START_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_SET_END() -#define LIBMEMCACHED_MEMCACHED_SET_END_ENABLED() (0) -#define LIBMEMCACHED_MEMCACHED_SET_START() -#define LIBMEMCACHED_MEMCACHED_SET_START_ENABLED() (0) - -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBMEMCACHED_PROBES_H */ diff --git a/lib/md5.c b/lib/md5.c deleted file mode 100644 index 61f8d692..00000000 --- a/lib/md5.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - This Library has been modified from its original form by - Brian Aker (brian@tangent.org) - - See below for original Copyright. -*/ -/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. -*/ - - -#include -#include - -/* POINTER defines a generic pointer type */ -typedef unsigned char *POINTER; - - -/* UINT4 defines a four byte word */ -typedef unsigned int UINT4; - - -/* MD5 context. */ -typedef struct { - UINT4 state[4]; /* state (ABCD) */ - UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ -} MD5_CTX; - -static void MD5Init (MD5_CTX *context); /* context */ -static void MD5Update ( MD5_CTX *context, /* context */ - unsigned char *input, /* input block */ - unsigned int inputLen); /* length of input block */ -static void MD5Final ( unsigned char digest[16], /* message digest */ - MD5_CTX *context); /* context */ - -/* Constants for MD5Transform routine. */ - -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - - -static void MD5Transform (UINT4 state[4], - unsigned char block[64]); -static void Encode (unsigned char *output, - UINT4 *input, - unsigned int len); -static void Decode(UINT4 *output, unsigned char *input, unsigned int len); - -static unsigned char PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G, H and I are basic MD5 functions. - */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. - */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -Rotation is separate from addition to prevent recomputation. - */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - - -/* - Just a simple method for getting the signature - result must be == 16 -*/ -void md5_signature(unsigned char *key, unsigned int length, unsigned char *result) -{ - MD5_CTX my_md5; - - MD5Init(&my_md5); - (void)MD5Update(&my_md5, key, length); - MD5Final(result, &my_md5); -} - -/* MD5 initialization. Begins an MD5 operation, writing a new context. - */ -static void MD5Init (MD5_CTX *context) /* context */ -{ - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. -*/ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. - */ - -static void MD5Update ( - MD5_CTX *context, /* context */ - unsigned char *input, /* input block */ - unsigned int inputLen) /* length of input block */ -{ - unsigned int i, idx, partLen; - - /* Compute number of bytes mod 64 */ - idx = (unsigned int)((context->count[0] >> 3) & 0x3F); - - - /* Update number of bits */ - if ((context->count[0] += ((UINT4)inputLen << 3)) - < ((UINT4)inputLen << 3)) - context->count[1]++; - context->count[1] += ((UINT4)inputLen >> 29); - - partLen = 64 - idx; - - /* Transform as many times as possible. -*/ - if (inputLen >= partLen) { - memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen); - MD5Transform(context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform (context->state, &input[i]); - - idx = 0; - } - else - i = 0; - - /* Buffer remaining input */ - memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i], - inputLen-i); -} - -/* MD5 finalization. Ends an MD5 message-digest operation, writing the - the message digest and zeroizing the context. - */ - -static void MD5Final ( - unsigned char digest[16], /* message digest */ - MD5_CTX *context) /* context */ -{ - unsigned char bits[8]; - unsigned int idx, padLen; - - /* Save number of bits */ - Encode (bits, context->count, 8); - - /* Pad out to 56 mod 64. -*/ - idx = (unsigned int)((context->count[0] >> 3) & 0x3f); - padLen = (idx < 56) ? (56 - idx) : (120 - idx); - MD5Update (context, PADDING, padLen); - - /* Append length (before padding) */ - MD5Update (context, bits, 8); - - /* Store state in digest */ - Encode (digest, context->state, 16); - - /* Zeroize sensitive information. -*/ - memset((POINTER)context, 0, sizeof (*context)); -} - -/* MD5 basic transformation. Transforms state based on block. - */ -static void MD5Transform ( - UINT4 state[4], - unsigned char block[64]) -{ - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode (x, block, 64); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information. -*/ - memset((POINTER)x, 0, sizeof (x)); -} - -/* Encodes input (UINT4) into output (unsigned char). Assumes len is - a multiple of 4. - */ -static void Encode ( -unsigned char *output, -UINT4 *input, -unsigned int len) -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); - } -} - - -/* Decodes input (unsigned char) into output (UINT4). Assumes len is - a multiple of 4. - */ -static void Decode ( -UINT4 *output, -unsigned char *input, -unsigned int len) -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | - (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); -} diff --git a/lib/memcached.c b/lib/memcached.c deleted file mode 100644 index 31c12ab3..00000000 --- a/lib/memcached.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - Memcached library -*/ -#include "common.h" - -memcached_st *memcached_create(memcached_st *ptr) -{ - memcached_result_st *result_ptr; - - if (ptr == NULL) - { - ptr= (memcached_st *)malloc(sizeof(memcached_st)); - - if (!ptr) - return NULL; /* MEMCACHED_MEMORY_ALLOCATION_FAILURE */ - - memset(ptr, 0, sizeof(memcached_st)); - ptr->is_allocated= MEMCACHED_ALLOCATED; - } - else - { - memset(ptr, 0, sizeof(memcached_st)); - } - result_ptr= memcached_result_create(ptr, &ptr->result); - WATCHPOINT_ASSERT(result_ptr); - ptr->poll_timeout= MEMCACHED_DEFAULT_TIMEOUT; - ptr->distribution= MEMCACHED_DISTRIBUTION_MODULA; - - return ptr; -} - -void memcached_free(memcached_st *ptr) -{ - /* If we have anything open, lets close it now */ - memcached_quit(ptr); - server_list_free(ptr, ptr->hosts); - memcached_result_free(&ptr->result); - - if (ptr->on_cleanup) - ptr->on_cleanup(ptr); - - if (ptr->is_allocated == MEMCACHED_ALLOCATED) - { - if (ptr->call_free) - ptr->call_free(ptr, ptr); - else - free(ptr); - } - else - ptr->is_allocated= MEMCACHED_USED; -} - -/* - clone is the destination, while ptr is the structure to clone. - If ptr is NULL the call is the same as if a memcached_create() was - called. -*/ -memcached_st *memcached_clone(memcached_st *clone, memcached_st *ptr) -{ - memcached_return rc= MEMCACHED_SUCCESS; - memcached_st *new_clone; - - if (ptr == NULL) - return memcached_create(clone); - - if (ptr->is_allocated == MEMCACHED_USED) - { - WATCHPOINT_ASSERT(0); - return NULL; - } - - new_clone= memcached_create(clone); - - if (new_clone == NULL) - return NULL; - - if (ptr->hosts) - rc= memcached_server_push(new_clone, ptr->hosts); - - if (rc != MEMCACHED_SUCCESS) - { - memcached_free(new_clone); - - return NULL; - } - - - new_clone->flags= ptr->flags; - new_clone->send_size= ptr->send_size; - new_clone->recv_size= ptr->recv_size; - new_clone->poll_timeout= ptr->poll_timeout; - new_clone->distribution= ptr->distribution; - new_clone->hash= ptr->hash; - new_clone->user_data= ptr->user_data; - - new_clone->on_clone= ptr->on_clone; - new_clone->on_cleanup= ptr->on_cleanup; - new_clone->call_free= ptr->call_free; - new_clone->call_malloc= ptr->call_malloc; - new_clone->call_realloc= ptr->call_realloc; - - if (ptr->on_clone) - ptr->on_clone(ptr, new_clone); - - return new_clone; -} diff --git a/lib/memcached_auto.c b/lib/memcached_auto.c deleted file mode 100644 index a607ed66..00000000 --- a/lib/memcached_auto.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "common.h" - -static memcached_return memcached_auto(memcached_st *ptr, - char *verb, - char *key, size_t key_length, - unsigned int offset, - uint64_t *value) -{ - size_t send_length; - memcached_return rc; - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - unsigned int server_key; - - unlikely (key_length == 0) - return MEMCACHED_NO_KEY_PROVIDED; - - unlikely (ptr->hosts == NULL || ptr->number_of_hosts == 0) - return MEMCACHED_NO_SERVERS; - - if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED)) - return MEMCACHED_BAD_KEY_PROVIDED; - - server_key= memcached_generate_hash(ptr, key, key_length); - - send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "%s %.*s %u\r\n", verb, - (int)key_length, key, - offset); - unlikely (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) - return MEMCACHED_WRITE_FAILURE; - - rc= memcached_do(&ptr->hosts[server_key], buffer, send_length, 1); - if (rc != MEMCACHED_SUCCESS) - return rc; - - rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); - - /* - So why recheck responce? Because the protocol is brain dead :) - The number returned might end up equaling one of the string - values. Less chance of a mistake with strncmp() so we will - use it. We still called memcached_response() though since it - worked its magic for non-blocking IO. - */ - if (!strncmp(buffer, "ERROR\r\n", 7)) - { - *value= 0; - rc= MEMCACHED_PROTOCOL_ERROR; - } - else if (!strncmp(buffer, "NOT_FOUND\r\n", 11)) - { - *value= 0; - rc= MEMCACHED_NOTFOUND; - } - else - { - *value= (uint64_t)strtoll(buffer, (char **)NULL, 10); - rc= MEMCACHED_SUCCESS; - } - - return rc; -} - -memcached_return memcached_increment(memcached_st *ptr, - char *key, size_t key_length, - uint32_t offset, - uint64_t *value) -{ - memcached_return rc; - - LIBMEMCACHED_MEMCACHED_INCREMENT_START(); - rc= memcached_auto(ptr, "incr", key, key_length, offset, value); - LIBMEMCACHED_MEMCACHED_INCREMENT_END(); - - return rc; -} - -memcached_return memcached_decrement(memcached_st *ptr, - char *key, size_t key_length, - uint32_t offset, - uint64_t *value) -{ - memcached_return rc; - - LIBMEMCACHED_MEMCACHED_DECREMENT_START(); - rc= memcached_auto(ptr, "decr", key, key_length, offset, value); - LIBMEMCACHED_MEMCACHED_DECREMENT_END(); - - return rc; -} diff --git a/lib/memcached_behavior.c b/lib/memcached_behavior.c deleted file mode 100644 index ce598fc0..00000000 --- a/lib/memcached_behavior.c +++ /dev/null @@ -1,197 +0,0 @@ -#include "common.h" -#include -#include -#include - -/* - This function is used to modify the behabior of running client. - - We quit all connections so we can reset the sockets. -*/ - -void set_behavior_flag(memcached_st *ptr, memcached_flags temp_flag, void *data) -{ - uint8_t truefalse; - - if (data) - truefalse= *(unsigned int *)data; - else - truefalse= 0; - - if (truefalse) - ptr->flags|= temp_flag; - else - ptr->flags+= temp_flag; -} - -memcached_return memcached_behavior_set(memcached_st *ptr, - memcached_behavior flag, - void *data) -{ - switch (flag) - { - case MEMCACHED_BEHAVIOR_SUPPORT_CAS: - set_behavior_flag(ptr, MEM_SUPPORT_CAS, data); - break; - case MEMCACHED_BEHAVIOR_NO_BLOCK: - set_behavior_flag(ptr, MEM_NO_BLOCK, data); - memcached_quit(ptr); - case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS: - set_behavior_flag(ptr, MEM_BUFFER_REQUESTS, data); - memcached_quit(ptr); - break; - case MEMCACHED_BEHAVIOR_TCP_NODELAY: - set_behavior_flag(ptr, MEM_TCP_NODELAY, data); - memcached_quit(ptr); - break; - case MEMCACHED_BEHAVIOR_DISTRIBUTION: - ptr->distribution= *(memcached_server_distribution *)(data); - break; - case MEMCACHED_BEHAVIOR_HASH: - ptr->hash= *(memcached_hash *)(data); - break; - case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS: - set_behavior_flag(ptr, MEM_USE_CACHE_LOOKUPS, data); - memcached_quit(ptr); - break; - case MEMCACHED_BEHAVIOR_VERIFY_KEY: - set_behavior_flag(ptr, MEM_VERIFY_KEY, data); - break; - case MEMCACHED_BEHAVIOR_KETAMA: - set_behavior_flag(ptr, MEM_USE_KETAMA, data); - break; - case MEMCACHED_BEHAVIOR_SORT_HOSTS: - set_behavior_flag(ptr, MEM_USE_SORT_HOSTS, data); - break; - case MEMCACHED_BEHAVIOR_USER_DATA: - ptr->user_data= data; - break; - case MEMCACHED_BEHAVIOR_POLL_TIMEOUT: - { - int32_t timeout= (*((int32_t *)data)); - - ptr->poll_timeout= timeout; - break; - } - case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT: - { - int32_t timeout= (*((int32_t *)data)); - - ptr->connect_timeout= timeout; - break; - } - case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT: - { - ptr->retry_timeout= (int32_t)data; - break; - } - case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE: - { - ptr->send_size= (*((int *)data)); - memcached_quit(ptr); - break; - } - case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE: - { - ptr->recv_size= (*((int *)data)); - memcached_quit(ptr); - break; - } - - - } - - return MEMCACHED_SUCCESS; -} - -unsigned long long memcached_behavior_get(memcached_st *ptr, - memcached_behavior flag) -{ - memcached_flags temp_flag= 0; - - switch (flag) - { - case MEMCACHED_BEHAVIOR_SUPPORT_CAS: - temp_flag= MEM_SUPPORT_CAS; - break; - case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS: - temp_flag= MEM_USE_CACHE_LOOKUPS; - break; - case MEMCACHED_BEHAVIOR_NO_BLOCK: - temp_flag= MEM_NO_BLOCK; - break; - case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS: - temp_flag= MEM_BUFFER_REQUESTS; - break; - case MEMCACHED_BEHAVIOR_TCP_NODELAY: - temp_flag= MEM_TCP_NODELAY; - break; - case MEMCACHED_BEHAVIOR_VERIFY_KEY: - temp_flag= MEM_VERIFY_KEY; - break; - case MEMCACHED_BEHAVIOR_DISTRIBUTION: - return ptr->distribution; - case MEMCACHED_BEHAVIOR_HASH: - return ptr->hash; - case MEMCACHED_BEHAVIOR_KETAMA: - temp_flag= MEM_USE_KETAMA; - break; - case MEMCACHED_BEHAVIOR_SORT_HOSTS: - temp_flag= MEM_USE_SORT_HOSTS; - break; - case MEMCACHED_BEHAVIOR_USER_DATA: - return 0; - case MEMCACHED_BEHAVIOR_POLL_TIMEOUT: - { - return (unsigned long long)ptr->poll_timeout; - } - case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT: - { - return (unsigned long long)ptr->connect_timeout; - } - case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT: - { - return (unsigned long long)ptr->retry_timeout; - } - case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE: - { - int sock_size; - socklen_t sock_length= sizeof(int); - - /* REFACTOR */ - /* We just try the first host, and if it is down we return zero */ - if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS) - return 0; - - if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET, - SO_SNDBUF, &sock_size, &sock_length)) - return 0; /* Zero means error */ - - return sock_size; - } - case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE: - { - int sock_size; - socklen_t sock_length= sizeof(int); - - /* REFACTOR */ - /* We just try the first host, and if it is down we return zero */ - if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS) - return 0; - - if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET, - SO_RCVBUF, &sock_size, &sock_length)) - return 0; /* Zero means error */ - - return sock_size; - } - } - - WATCHPOINT_ASSERT(temp_flag); /* Programming mistake if it gets this far */ - if (ptr->flags & temp_flag) - return 1; - else - return 0; - - return MEMCACHED_SUCCESS; -} diff --git a/lib/memcached_callback.c b/lib/memcached_callback.c deleted file mode 100644 index 95d6a384..00000000 --- a/lib/memcached_callback.c +++ /dev/null @@ -1,103 +0,0 @@ -#include "common.h" -#include -#include -#include - -/* - These functions provide data and function callback support -*/ - -memcached_return memcached_callback_set(memcached_st *ptr, - memcached_callback flag, - void *data) -{ - switch (flag) - { - case MEMCACHED_CALLBACK_USER_DATA: - { - ptr->user_data= data; - break; - } - case MEMCACHED_CALLBACK_CLEANUP_FUNCTION: - { - memcached_cleanup_func func= (memcached_cleanup_func)data; - ptr->on_cleanup= func; - break; - } - case MEMCACHED_CALLBACK_CLONE_FUNCTION: - { - memcached_clone_func func= (memcached_clone_func)data; - ptr->on_clone= func; - break; - } - case MEMCACHED_CALLBACK_MALLOC_FUNCTION: - { - memcached_malloc_function func= (memcached_malloc_function)data; - ptr->call_malloc= func; - break; - } - case MEMCACHED_CALLBACK_REALLOC_FUNCTION: - { - memcached_realloc_function func= (memcached_realloc_function)data; - ptr->call_realloc= func; - break; - } - case MEMCACHED_CALLBACK_FREE_FUNCTION: - { - memcached_free_function func= (memcached_free_function)data; - ptr->call_free= func; - break; - } - default: - return MEMCACHED_FAILURE; - } - - return MEMCACHED_SUCCESS; -} - -void *memcached_callback_get(memcached_st *ptr, - memcached_callback flag, - memcached_return *error) -{ - memcached_return local_error; - if (!error) - error = &local_error; - - switch (flag) - { - case MEMCACHED_CALLBACK_USER_DATA: - { - *error= ptr->user_data ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; - return (void *)ptr->user_data; - } - case MEMCACHED_CALLBACK_CLEANUP_FUNCTION: - { - *error= ptr->on_cleanup ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; - return (void *)ptr->on_cleanup; - } - case MEMCACHED_CALLBACK_CLONE_FUNCTION: - { - *error= ptr->on_clone ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; - return (void *)ptr->on_clone; - } - case MEMCACHED_CALLBACK_MALLOC_FUNCTION: - { - *error= ptr->call_malloc ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; - return (void *)ptr->call_malloc; - } - case MEMCACHED_CALLBACK_REALLOC_FUNCTION: - { - *error= ptr->call_realloc ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; - return (void *)ptr->call_realloc; - } - case MEMCACHED_CALLBACK_FREE_FUNCTION: - { - *error= ptr->call_free ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; - return (void *)ptr->call_free; - } - default: - WATCHPOINT_ASSERT(0); - *error= MEMCACHED_FAILURE; - return NULL; - } -} diff --git a/lib/memcached_connect.c b/lib/memcached_connect.c deleted file mode 100644 index ab4b84f0..00000000 --- a/lib/memcached_connect.c +++ /dev/null @@ -1,292 +0,0 @@ -#include "common.h" -#include - -static memcached_return set_hostinfo(memcached_server_st *server) -{ - struct addrinfo *ai; - struct addrinfo hints; - int e; - char str_port[NI_MAXSERV]; - - sprintf(str_port, "%u", server->port); - - memset(&hints, 0, sizeof(hints)); - - hints.ai_family= AF_INET; - if (server->type == MEMCACHED_CONNECTION_UDP) - { - hints.ai_protocol= IPPROTO_UDP; - hints.ai_socktype= SOCK_DGRAM; - } - else - { - hints.ai_socktype= SOCK_STREAM; - hints.ai_protocol= IPPROTO_TCP; - } - - e= getaddrinfo(server->hostname, str_port, &hints, &ai); - if (e != 0) - { - WATCHPOINT_STRING(server->hostname); - WATCHPOINT_STRING(gai_strerror(e)); - return MEMCACHED_HOST_LOOKUP_FAILURE; - } - - if (server->address_info) - freeaddrinfo(server->address_info); - server->address_info= ai; - - return MEMCACHED_SUCCESS; -} - -static memcached_return set_socket_options(memcached_server_st *ptr) -{ - if (ptr->type == MEMCACHED_CONNECTION_UDP) - return MEMCACHED_SUCCESS; - - if (ptr->root->flags & MEM_NO_BLOCK) - { - int error; - struct linger linger; - struct timeval waittime; - - waittime.tv_sec= 10; - waittime.tv_usec= 0; - - linger.l_onoff= 1; - linger.l_linger= MEMCACHED_DEFAULT_TIMEOUT; - error= setsockopt(ptr->fd, SOL_SOCKET, SO_LINGER, - &linger, (socklen_t)sizeof(struct linger)); - WATCHPOINT_ASSERT(error == 0); - - error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDTIMEO, - &waittime, (socklen_t)sizeof(struct timeval)); - WATCHPOINT_ASSERT(error == 0); - - error= setsockopt(ptr->fd, SOL_SOCKET, SO_RCVTIMEO, - &waittime, (socklen_t)sizeof(struct timeval)); - WATCHPOINT_ASSERT(error == 0); - } - - if (ptr->root->flags & MEM_TCP_NODELAY) - { - int flag= 1; - int error; - - error= setsockopt(ptr->fd, IPPROTO_TCP, TCP_NODELAY, - &flag, (socklen_t)sizeof(int)); - WATCHPOINT_ASSERT(error == 0); - } - - if (ptr->root->send_size) - { - int error; - - error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDBUF, - &ptr->root->send_size, (socklen_t)sizeof(int)); - WATCHPOINT_ASSERT(error == 0); - } - - if (ptr->root->recv_size) - { - int error; - - error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDBUF, - &ptr->root->recv_size, (socklen_t)sizeof(int)); - WATCHPOINT_ASSERT(error == 0); - } - - /* For the moment, not getting a nonblocking mode will not be fatal */ - if (ptr->root->flags & MEM_NO_BLOCK) - { - int flags; - - flags= fcntl(ptr->fd, F_GETFL, 0); - unlikely (flags != -1) - { - (void)fcntl(ptr->fd, F_SETFL, flags | O_NONBLOCK); - } - } - - return MEMCACHED_SUCCESS; -} - -static memcached_return unix_socket_connect(memcached_server_st *ptr) -{ - struct sockaddr_un servAddr; - socklen_t addrlen; - - if (ptr->fd == -1) - { - if ((ptr->fd= socket(AF_UNIX, SOCK_STREAM, 0)) < 0) - { - ptr->cached_errno= errno; - return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE; - } - - memset(&servAddr, 0, sizeof (struct sockaddr_un)); - servAddr.sun_family= AF_UNIX; - strcpy(servAddr.sun_path, ptr->hostname); /* Copy filename */ - - addrlen= strlen(servAddr.sun_path) + sizeof(servAddr.sun_family); - -test_connect: - if (connect(ptr->fd, - (struct sockaddr *)&servAddr, - sizeof(servAddr)) < 0) - { - switch (errno) { - case EINPROGRESS: - case EALREADY: - case EINTR: - goto test_connect; - case EISCONN: /* We were spinning waiting on connect */ - break; - default: - WATCHPOINT_ERRNO(errno); - ptr->cached_errno= errno; - return MEMCACHED_ERRNO; - } - } - } - return MEMCACHED_SUCCESS; -} - -static memcached_return network_connect(memcached_server_st *ptr) -{ - if (ptr->fd == -1) - { - struct addrinfo *use; - - /* Old connection junk still is in the structure */ - WATCHPOINT_ASSERT(ptr->cursor_active == 0); - - if (ptr->sockaddr_inited == MEMCACHED_NOT_ALLOCATED || - (!(ptr->root->flags & MEM_USE_CACHE_LOOKUPS))) - { - memcached_return rc; - - rc= set_hostinfo(ptr); - if (rc != MEMCACHED_SUCCESS) - return rc; - ptr->sockaddr_inited= MEMCACHED_ALLOCATED; - } - - use= ptr->address_info; - /* Create the socket */ - while (use != NULL) - { - if ((ptr->fd= socket(use->ai_family, - use->ai_socktype, - use->ai_protocol)) < 0) - { - ptr->cached_errno= errno; - WATCHPOINT_ERRNO(errno); - return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE; - } - - (void)set_socket_options(ptr); - - /* connect to server */ -test_connect: - if (connect(ptr->fd, - use->ai_addr, - use->ai_addrlen) < 0) - { - switch (errno) { - /* We are spinning waiting on connect */ - case EALREADY: - case EINPROGRESS: - { - struct pollfd fds[1]; - int error; - - memset(&fds, 0, sizeof(struct pollfd)); - fds[0].fd= ptr->fd; - fds[0].events= POLLOUT | POLLERR; - error= poll(fds, 1, ptr->root->connect_timeout); - - if (error != 1) - { - ptr->cached_errno= errno; - WATCHPOINT_ERRNO(ptr->cached_errno); - close(ptr->fd); - ptr->fd= -1; - return MEMCACHED_ERRNO; - } - - break; - } - /* We are spinning waiting on connect */ - case EINTR: - goto test_connect; - case EISCONN: /* We were spinning waiting on connect */ - break; - default: - ptr->cached_errno= errno; - WATCHPOINT_ERRNO(ptr->cached_errno); - close(ptr->fd); - ptr->fd= -1; - if (ptr->root->retry_timeout) - { - struct timeval next_time; - - gettimeofday(&next_time, NULL); - ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout; - } - } - } - else - { - WATCHPOINT_ASSERT(ptr->cursor_active == 0); - return MEMCACHED_SUCCESS; - } - use = use->ai_next; - } - } - - if (ptr->fd == -1) - return MEMCACHED_ERRNO; /* The last error should be from connect() */ - - return MEMCACHED_SUCCESS; /* The last error should be from connect() */ -} - - -memcached_return memcached_connect(memcached_server_st *ptr) -{ - memcached_return rc= MEMCACHED_NO_SERVERS; - LIBMEMCACHED_MEMCACHED_CONNECT_START(); - - if (ptr->root->retry_timeout) - { - struct timeval next_time; - - gettimeofday(&next_time, NULL); - if (next_time.tv_sec < ptr->next_retry) - return MEMCACHED_TIMEOUT; - } - /* 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); - break; - case MEMCACHED_CONNECTION_UNIX_SOCKET: - rc= unix_socket_connect(ptr); - break; - default: - WATCHPOINT_ASSERT(0); - } - - if (rc != MEMCACHED_SUCCESS) - WATCHPOINT_ERROR(rc); - - LIBMEMCACHED_MEMCACHED_CONNECT_END(); - - return rc; -} diff --git a/lib/memcached_delete.c b/lib/memcached_delete.c deleted file mode 100644 index 60e3bed4..00000000 --- a/lib/memcached_delete.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "common.h" - -memcached_return memcached_delete(memcached_st *ptr, char *key, size_t key_length, - time_t expiration) -{ - return memcached_delete_by_key(ptr, key, key_length, - key, key_length, expiration); -} - -memcached_return memcached_delete_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - time_t expiration) -{ - char to_write; - size_t send_length; - memcached_return rc; - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - unsigned int server_key; - - LIBMEMCACHED_MEMCACHED_DELETE_START(); - - unlikely (key_length == 0) - return MEMCACHED_NO_KEY_PROVIDED; - - unlikely (ptr->hosts == NULL || ptr->number_of_hosts == 0) - return MEMCACHED_NO_SERVERS; - - server_key= memcached_generate_hash(ptr, master_key, master_key_length); - - if (expiration) - send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "delete %.*s %llu\r\n", (int)key_length, key, - (unsigned long long)expiration); - else - send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "delete %.*s\r\n", (int)key_length, key); - - if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) - { - rc= MEMCACHED_WRITE_FAILURE; - goto error; - } - - to_write= (ptr->flags & MEM_BUFFER_REQUESTS) ? 0 : 1; - - rc= memcached_do(&ptr->hosts[server_key], buffer, send_length, to_write); - if (rc != MEMCACHED_SUCCESS) - goto error; - - if ((ptr->flags & MEM_BUFFER_REQUESTS)) - { - rc= MEMCACHED_BUFFERED; - } - else - { - rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); - if (rc == MEMCACHED_DELETED) - rc= MEMCACHED_SUCCESS; - } - -error: - LIBMEMCACHED_MEMCACHED_DELETE_END(); - return rc; -} diff --git a/lib/memcached_do.c b/lib/memcached_do.c deleted file mode 100644 index c4bf574f..00000000 --- a/lib/memcached_do.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "common.h" - -memcached_return memcached_do(memcached_server_st *ptr, char *command, - size_t command_length, uint8_t with_flush) -{ - memcached_return rc; - ssize_t sent_length; - - WATCHPOINT_ASSERT(command_length); - WATCHPOINT_ASSERT(command); - - if ((rc= memcached_connect(ptr)) != MEMCACHED_SUCCESS) - return rc; - - sent_length= memcached_io_write(ptr, command, command_length, with_flush); - - if (sent_length == -1 || sent_length != command_length) - rc= MEMCACHED_WRITE_FAILURE; - else - memcached_server_response_increment(ptr); - - return rc; -} diff --git a/lib/memcached_fetch.c b/lib/memcached_fetch.c deleted file mode 100644 index 37cec5d3..00000000 --- a/lib/memcached_fetch.c +++ /dev/null @@ -1,225 +0,0 @@ -#include "common.h" -#include "memcached_io.h" - -memcached_return value_fetch(memcached_server_st *ptr, - char *buffer, - memcached_result_st *result) -{ - memcached_return rc= MEMCACHED_SUCCESS; - char *string_ptr; - char *end_ptr; - char *next_ptr; - size_t value_length; - size_t read_length; - size_t to_read; - char *value_ptr; - - end_ptr= buffer + MEMCACHED_DEFAULT_COMMAND_SIZE; - - result->key_length= 0; - result->flags= 0; - memcached_string_reset(&result->value); - - string_ptr= buffer; - string_ptr+= 6; /* "VALUE " */ - - - /* We load the key */ - { - char *key; - - key= result->key; - result->key_length= 0; - - for (; isgraph(*string_ptr); string_ptr++) - { - *key= *string_ptr; - key++; - result->key_length++; - } - result->key[result->key_length]= 0; - } - - if (end_ptr == string_ptr) - goto read_error; - - /* Flags fetch move past space */ - string_ptr++; - if (end_ptr == string_ptr) - goto read_error; - for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++); - result->flags= (uint32_t)strtol(next_ptr, &string_ptr, 10); - - if (end_ptr == string_ptr) - goto read_error; - - /* Length fetch move past space*/ - string_ptr++; - if (end_ptr == string_ptr) - goto read_error; - - for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++); - value_length= (size_t)strtoll(next_ptr, &string_ptr, 10); - - if (end_ptr == string_ptr) - goto read_error; - - /* Skip spaces */ - if (*string_ptr == '\r') - { - /* Skip past the \r\n */ - string_ptr+= 2; - result->cas= 0; - } - else - { - string_ptr++; - for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++); - result->cas= (size_t)strtoll(next_ptr, &string_ptr, 10); - } - - if (end_ptr < string_ptr) - goto read_error; - - /* We add two bytes so that we can walk the \r\n */ - rc= memcached_string_check(&result->value, value_length+2); - if (rc != MEMCACHED_SUCCESS) - { - value_length= 0; - return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - } - - value_ptr= memcached_string_value(&result->value); - read_length= 0; - /* - We read the \r\n into the string since not doing so is more - cycles then the waster of memory to do so. - - We are null terminating through, which will most likely make - some people lazy about using the return length. - */ - to_read= (value_length) + 2; - read_length= memcached_io_read(ptr, value_ptr, to_read); - if (read_length != (size_t)(value_length + 2)) - { - goto read_error; - } - -/* This next bit blows the API, but this is internal....*/ - { - char *char_ptr; - char_ptr= memcached_string_value(&result->value);; - char_ptr[value_length]= 0; - char_ptr[value_length + 1]= 0; - memcached_string_set_length(&result->value, value_length); - } - - return MEMCACHED_SUCCESS; - -read_error: - memcached_io_reset(ptr); - - return MEMCACHED_PARTIAL_READ; -} - -char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, - size_t *value_length, - uint32_t *flags, - memcached_return *error) -{ - memcached_result_st *result_buffer= &ptr->result; - - while (ptr->cursor_server < ptr->number_of_hosts) - { - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - - if (memcached_server_response_count(&ptr->hosts[ptr->cursor_server]) == 0) - { - ptr->cursor_server++; - continue; - } - - *error= memcached_response(&ptr->hosts[ptr->cursor_server], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result_buffer); - - if (*error == MEMCACHED_END) /* END means that we move on to the next */ - { - memcached_server_response_reset(&ptr->hosts[ptr->cursor_server]); - ptr->cursor_server++; - continue; - } - else if (*error == MEMCACHED_SUCCESS) - { - *value_length= memcached_string_length(&result_buffer->value); - - if (key) - { - strncpy(key, result_buffer->key, result_buffer->key_length); - *key_length= result_buffer->key_length; - } - - if (result_buffer->flags) - *flags= result_buffer->flags; - else - *flags= 0; - - return memcached_string_c_copy(&result_buffer->value); - } - else - { - *value_length= 0; - return NULL; - } - } - - ptr->cursor_server= 0; - *value_length= 0; - return NULL; -} - -memcached_result_st *memcached_fetch_result(memcached_st *ptr, - memcached_result_st *result, - memcached_return *error) -{ - if (result == NULL) - result= memcached_result_create(ptr, NULL); - - WATCHPOINT_ASSERT(result->value.is_allocated != MEMCACHED_USED); - -#ifdef UNUSED - if (ptr->flags & MEM_NO_BLOCK) - memcached_io_preread(ptr); -#endif - - while (ptr->cursor_server < ptr->number_of_hosts) - { - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - - if (memcached_server_response_count(&ptr->hosts[ptr->cursor_server]) == 0) - { - ptr->cursor_server++; - continue; - } - - *error= memcached_response(&ptr->hosts[ptr->cursor_server], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result); - - if (*error == MEMCACHED_END) /* END means that we move on to the next */ - { - memcached_server_response_reset(&ptr->hosts[ptr->cursor_server]); - ptr->cursor_server++; - continue; - } - else if (*error == MEMCACHED_SUCCESS) - return result; - else - return NULL; - } - - /* We have completed reading data */ - if (result->is_allocated == MEMCACHED_ALLOCATED) - memcached_result_free(result); - else - memcached_string_reset(&result->value); - - ptr->cursor_server= 0; - return NULL; -} diff --git a/lib/memcached_fetch_execute.c b/lib/memcached_fetch_execute.c deleted file mode 100644 index 29d76244..00000000 --- a/lib/memcached_fetch_execute.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "common.h" - -memcached_return memcached_fetch_execute(memcached_st *ptr, - memcached_execute_function *callback, - void *context, - unsigned int number_of_callbacks - ) -{ - memcached_result_st *result= &ptr->result; - - while (ptr->cursor_server < ptr->number_of_hosts) - { - memcached_return rc; - - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - - if (memcached_server_response_count(&ptr->hosts[ptr->cursor_server]) == 0) - { - ptr->cursor_server++; - continue; - } - - rc= memcached_response(&ptr->hosts[ptr->cursor_server], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result); - - if (rc == MEMCACHED_END) /* END means that we move on to the next */ - { - memcached_server_response_reset(&ptr->hosts[ptr->cursor_server]); - ptr->cursor_server++; - continue; - } - else if (rc == MEMCACHED_SUCCESS) - { - unsigned int x; - - for (x= 0; x < number_of_callbacks; x++) - { - memcached_return iferror; - - iferror= (*callback[x])(ptr, result, context); - - if (iferror != MEMCACHED_SUCCESS) - continue; - } - } - } - - return MEMCACHED_SUCCESS; -} diff --git a/lib/memcached_flush.c b/lib/memcached_flush.c deleted file mode 100644 index 1511adbe..00000000 --- a/lib/memcached_flush.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "common.h" - -memcached_return memcached_flush(memcached_st *ptr, time_t expiration) -{ - unsigned int x; - size_t send_length; - memcached_return rc; - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - LIBMEMCACHED_MEMCACHED_FLUSH_START(); - - unlikely (ptr->number_of_hosts == 0) - return MEMCACHED_NO_SERVERS; - - for (x= 0; x < ptr->number_of_hosts; x++) - { - if (expiration) - send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "flush_all %llu\r\n", (unsigned long long)expiration); - else - send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "flush_all\r\n"); - - rc= memcached_do(&ptr->hosts[x], buffer, send_length, 1); - - if (rc == MEMCACHED_SUCCESS) - (void)memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); - } - - LIBMEMCACHED_MEMCACHED_FLUSH_END(); - return MEMCACHED_SUCCESS; -} diff --git a/lib/memcached_get.c b/lib/memcached_get.c deleted file mode 100644 index 8cc7ce30..00000000 --- a/lib/memcached_get.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "common.h" -#include "memcached_io.h" - -/* - What happens if no servers exist? -*/ -char *memcached_get(memcached_st *ptr, char *key, size_t key_length, - size_t *value_length, - uint32_t *flags, - memcached_return *error) -{ - return memcached_get_by_key(ptr, NULL, 0, key, key_length, value_length, - flags, error); -} - -char *memcached_get_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - size_t *value_length, - uint32_t *flags, - memcached_return *error) -{ - char *value; - size_t dummy_length; - uint32_t dummy_flags; - memcached_return dummy_error; - - /* Request the key */ - *error= memcached_mget_by_key(ptr, - master_key, - master_key_length, - &key, &key_length, 1); - - value= memcached_fetch(ptr, NULL, NULL, - value_length, flags, error); - /* This is for historical reasons */ - if (*error == MEMCACHED_END) - *error= MEMCACHED_NOTFOUND; - - if (value == NULL) - return NULL; - - (void)memcached_fetch(ptr, NULL, NULL, - &dummy_length, &dummy_flags, - &dummy_error); - WATCHPOINT_ASSERT(dummy_length == 0); - - return value; -} - -memcached_return memcached_mget(memcached_st *ptr, - char **keys, size_t *key_length, - unsigned int number_of_keys) -{ - return memcached_mget_by_key(ptr, NULL, 0, keys, key_length, number_of_keys); -} - -memcached_return memcached_mget_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char **keys, size_t *key_length, - unsigned int number_of_keys) -{ - unsigned int x; - memcached_return rc= MEMCACHED_NOTFOUND; - char *get_command= "get "; - uint8_t get_command_length= 4; - unsigned int master_server_key= 0; - - LIBMEMCACHED_MEMCACHED_MGET_START(); - ptr->cursor_server= 0; - - if (number_of_keys == 0) - return MEMCACHED_NOTFOUND; - - if (ptr->number_of_hosts == 0) - return MEMCACHED_NO_SERVERS; - - if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(keys, key_length, number_of_keys) == MEMCACHED_BAD_KEY_PROVIDED)) - return MEMCACHED_BAD_KEY_PROVIDED; - - if (ptr->flags & MEM_SUPPORT_CAS) - { - get_command= "gets "; - get_command_length= 5; - } - - if (master_key && master_key_length) - master_server_key= memcached_generate_hash(ptr, master_key, master_key_length); - - /* - Here is where we pay for the non-block API. We need to remove any data sitting - in the queue before we start our get. - - It might be optimum to bounce the connection if count > some number. - */ - for (x= 0; x < ptr->number_of_hosts; x++) - { - if (memcached_server_response_count(&ptr->hosts[x])) - { - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - - if (ptr->flags & MEM_NO_BLOCK) - (void)memcached_io_write(&ptr->hosts[x], NULL, 0, 1); - - while(memcached_server_response_count(&ptr->hosts[x])) - (void)memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, &ptr->result); - } - } - - /* - If a server fails we warn about errors and start all over with sending keys - to the server. - */ - for (x= 0; x < number_of_keys; x++) - { - unsigned int server_key; - - if (master_server_key) - server_key= master_server_key; - else - server_key= memcached_generate_hash(ptr, keys[x], key_length[x]); - - if (memcached_server_response_count(&ptr->hosts[server_key]) == 0) - { - rc= memcached_connect(&ptr->hosts[server_key]); - - if (rc != MEMCACHED_SUCCESS) - continue; - - if ((memcached_io_write(&ptr->hosts[server_key], get_command, get_command_length, 0)) == -1) - { - rc= MEMCACHED_SOME_ERRORS; - continue; - } - WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 0); - memcached_server_response_increment(&ptr->hosts[server_key]); - WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 1); - } - - if ((memcached_io_write(&ptr->hosts[server_key], keys[x], key_length[x], 0)) == -1) - { - memcached_server_response_reset(&ptr->hosts[server_key]); - rc= MEMCACHED_SOME_ERRORS; - continue; - } - - if ((memcached_io_write(&ptr->hosts[server_key], " ", 1, 0)) == -1) - { - memcached_server_response_reset(&ptr->hosts[server_key]); - rc= MEMCACHED_SOME_ERRORS; - continue; - } - } - - /* - Should we muddle on if some servers are dead? - */ - for (x= 0; x < ptr->number_of_hosts; x++) - { - if (memcached_server_response_count(&ptr->hosts[x])) - { - /* We need to do something about non-connnected hosts in the future */ - if ((memcached_io_write(&ptr->hosts[x], "\r\n", 2, 1)) == -1) - { - rc= MEMCACHED_SOME_ERRORS; - } - } - } - - LIBMEMCACHED_MEMCACHED_MGET_END(); - return rc; -} diff --git a/lib/memcached_hash.c b/lib/memcached_hash.c deleted file mode 100644 index f365cc0e..00000000 --- a/lib/memcached_hash.c +++ /dev/null @@ -1,156 +0,0 @@ -#include "common.h" - -/* Defines */ -static uint64_t FNV_64_INIT= 0xcbf29ce484222325LL; -static uint64_t FNV_64_PRIME= 0x100000001b3LL; - -static uint32_t FNV_32_INIT= 2166136261UL; -static uint32_t FNV_32_PRIME= 16777619; - -/* Prototypes */ -static uint32_t internal_generate_hash(char *key, size_t key_length); -static uint32_t internal_generate_md5(char *key, size_t key_length); -static uint32_t internal_generate_ketama_md5(char *key, size_t key_length); - -unsigned int memcached_generate_hash(memcached_st *ptr, char *key, size_t key_length) -{ - uint32_t hash= 1; /* Just here to remove compile warning */ - unsigned int x; - - WATCHPOINT_ASSERT(ptr->number_of_hosts); - - if (ptr->number_of_hosts == 1) - return 0; - - switch (ptr->hash) - { - case MEMCACHED_HASH_DEFAULT: - hash= internal_generate_hash(key, key_length); - break; - case MEMCACHED_HASH_MD5: - hash= internal_generate_md5(key, key_length); - break; - case MEMCACHED_HASH_CRC: - hash= ((hash_crc32(key, key_length) >> 16) & 0x7fff); - if (hash == 0) - hash= 1; - break; - /* FNV hash'es lifted from Dustin Sallings work */ - case MEMCACHED_HASH_FNV1_64: - { - /* Thanks to pierre@demartines.com for the pointer */ - uint64_t temp_hash; - - temp_hash= FNV_64_INIT; - for (x= 0; x < key_length; x++) - { - temp_hash *= FNV_64_PRIME; - temp_hash ^= key[x]; - } - hash= (uint32_t)temp_hash; - } - break; - case MEMCACHED_HASH_FNV1A_64: - { - hash= FNV_64_INIT; - for (x= 0; x < key_length; x++) - { - hash ^= key[x]; - hash *= FNV_64_PRIME; - } - } - break; - case MEMCACHED_HASH_FNV1_32: - { - hash= FNV_32_INIT; - for (x= 0; x < key_length; x++) - { - hash *= FNV_32_PRIME; - hash ^= key[x]; - } - } - break; - case MEMCACHED_HASH_FNV1A_32: - { - hash= FNV_32_INIT; - for (x= 0; x < key_length; x++) - { - hash ^= key[x]; - hash *= FNV_32_PRIME; - } - } - break; - case MEMCACHED_HASH_KETAMA: - { - hash= internal_generate_ketama_md5(key, key_length); - break; - } - case MEMCACHED_HASH_HSIEH: - { - hash= hsieh_hash(key, key_length); - break; - } - case MEMCACHED_HASH_MURMUR: - { - hash= murmur_hash(key, key_length); - break; - } - } - - WATCHPOINT_ASSERT(hash); - - if (ptr->distribution == MEMCACHED_DISTRIBUTION_MODULA) - { - return hash % ptr->number_of_hosts; - } - else - { - unsigned int server_key; - - server_key= hash % MEMCACHED_WHEEL_SIZE; - - return ptr->wheel[server_key]; - } -} - -static uint32_t internal_generate_hash(char *key, size_t key_length) -{ - char *ptr= key; - uint32_t value= 0; - - while (--key_length) - { - value += *ptr++; - value += (value << 10); - value ^= (value >> 6); - } - value += (value << 3); - value ^= (value >> 11); - value += (value << 15); - - return value == 0 ? 1 : value; -} - -static uint32_t internal_generate_md5(char *key, size_t key_length) -{ - unsigned char results[16]; - - md5_signature((unsigned char*)key, (unsigned int)key_length, results); - - return (uint32_t)(( results[3] << 24 ) - | ( results[2] << 16 ) - | ( results[1] << 8 ) - | results[0] ); -} - -static uint32_t internal_generate_ketama_md5(char *key, size_t key_length) -{ - unsigned char results[16]; - - md5_signature((unsigned char*)key, (unsigned int)key_length, results); - - return ((uint32_t) (results[3] & 0xFF) << 24) - | ((uint32_t) (results[2] & 0xFF) << 16) - | ((uint32_t) (results[1] & 0xFF) << 8) - | (results[0] & 0xFF); -} diff --git a/lib/memcached_hosts.c b/lib/memcached_hosts.c deleted file mode 100644 index fb53fa22..00000000 --- a/lib/memcached_hosts.c +++ /dev/null @@ -1,250 +0,0 @@ -#include -#include "common.h" - -/* Protoypes (static) */ -static memcached_return server_add(memcached_st *ptr, char *hostname, - unsigned int port, - memcached_connection type); - -#define MEMCACHED_WHEEL_SIZE 1024 -#define MEMCACHED_STRIDE 4 -static void rebalance_wheel(memcached_st *ptr) -{ - unsigned int x; - unsigned int y; - unsigned int latch; - - /* Seed the Wheel */ - memset(ptr->wheel, 0, sizeof(unsigned int) * MEMCACHED_WHEEL_SIZE); - - for (latch= y= x= 0; x < MEMCACHED_WHEEL_SIZE; x++, latch++) - { - if (latch == MEMCACHED_STRIDE) - { - y++; - if (y == ptr->number_of_hosts) - y= 0; - latch= 0; - } - - ptr->wheel[x]= y; - } -} - -static int compare_servers(const void *p1, const void *p2) -{ - int return_value; - memcached_server_st *a= (memcached_server_st *)p1; - memcached_server_st *b= (memcached_server_st *)p2; - - return_value= strcmp(a->hostname, b->hostname); - - if (return_value == 0) - { - if (a->port > b->port) - return_value++; - else - return_value--; - } - - return return_value; -} - -static void host_reset(memcached_st *ptr, memcached_server_st *host, - char *hostname, unsigned int port, - memcached_connection type) -{ - memset(host, 0, sizeof(memcached_server_st)); - strncpy(host->hostname, hostname, MEMCACHED_MAX_HOST_LENGTH - 1); - host->root= ptr ? ptr : NULL; - host->port= port; - host->fd= -1; - host->type= type; - host->read_ptr= host->read_buffer; - if (ptr) - host->next_retry= ptr->retry_timeout; - host->sockaddr_inited= MEMCACHED_NOT_ALLOCATED; -} - -void server_list_free(memcached_st *ptr, memcached_server_st *servers) -{ - unsigned int x; - - if (servers == NULL) - return; - - for (x= 0; x < servers->count; x++) - if (servers[x].address_info) - freeaddrinfo(servers[x].address_info); - - if (ptr && ptr->call_free) - ptr->call_free(ptr, servers); - else - free(servers); -} - -memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list) -{ - unsigned int x; - uint16_t count; - memcached_server_st *new_host_list; - - if (!list) - return MEMCACHED_SUCCESS; - - count= list[0].count; - - if (ptr->call_realloc) - new_host_list= - (memcached_server_st *)ptr->call_realloc(ptr, ptr->hosts, - sizeof(memcached_server_st) * (count + ptr->number_of_hosts)); - else - new_host_list= - (memcached_server_st *)realloc(ptr->hosts, - sizeof(memcached_server_st) * (count + ptr->number_of_hosts)); - - if (!new_host_list) - return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - - ptr->hosts= new_host_list; - - for (x= 0; x < count; x++) - { - WATCHPOINT_ASSERT(list[x].hostname[0] != 0); - host_reset(ptr, &ptr->hosts[ptr->number_of_hosts], list[x].hostname, - list[x].port, list[x].type); - ptr->number_of_hosts++; - } - ptr->hosts[0].count= ptr->number_of_hosts; - - if (ptr->number_of_hosts > 1) - qsort(ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st), compare_servers); - - rebalance_wheel(ptr); - - return MEMCACHED_SUCCESS; -} - -memcached_return memcached_server_add_unix_socket(memcached_st *ptr, char *filename) -{ - if (!filename) - return MEMCACHED_FAILURE; - - return server_add(ptr, filename, 0, MEMCACHED_CONNECTION_UNIX_SOCKET); -} - -memcached_return memcached_server_add_udp(memcached_st *ptr, - char *hostname, - unsigned int port) -{ - if (!port) - port= MEMCACHED_DEFAULT_PORT; - - if (!hostname) - hostname= "localhost"; - - return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_UDP); -} - -memcached_return memcached_server_add(memcached_st *ptr, - char *hostname, - unsigned int port) -{ - if (!port) - port= MEMCACHED_DEFAULT_PORT; - - if (!hostname) - hostname= "localhost"; - - return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_TCP); -} - -static memcached_return server_add(memcached_st *ptr, char *hostname, - unsigned int port, - memcached_connection type) -{ - memcached_server_st *new_host_list; - LIBMEMCACHED_MEMCACHED_SERVER_ADD_START(); - - - if (ptr->call_realloc) - new_host_list= (memcached_server_st *)ptr->call_realloc(ptr, ptr->hosts, - sizeof(memcached_server_st) * (ptr->number_of_hosts+1)); - else - new_host_list= (memcached_server_st *)realloc(ptr->hosts, - sizeof(memcached_server_st) * (ptr->number_of_hosts+1)); - if (new_host_list == NULL) - return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - - ptr->hosts= new_host_list; - - host_reset(ptr, &ptr->hosts[ptr->number_of_hosts], hostname, port, type); - ptr->number_of_hosts++; - ptr->hosts[0].count++; - - if (ptr->number_of_hosts > 1) - qsort(ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st), compare_servers); - - rebalance_wheel(ptr); - - LIBMEMCACHED_MEMCACHED_SERVER_ADD_END(); - - return MEMCACHED_SUCCESS; -} - -memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, - char *hostname, unsigned int port, - memcached_return *error) -{ - unsigned int count; - memcached_server_st *new_host_list; - - if (hostname == NULL || error == NULL) - return NULL; - - if (!port) - port= MEMCACHED_DEFAULT_PORT; - - /* Increment count for hosts */ - count= 1; - if (ptr != NULL) - { - count+= ptr[0].count; - } - - new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count); - if (!new_host_list) - { - *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; - return NULL; - } - - host_reset(NULL, &new_host_list[count-1], hostname, port, MEMCACHED_CONNECTION_TCP); - - /* Backwards compatibility hack */ - new_host_list[0].count++; - - count= new_host_list[0].count; - - if (new_host_list[0].count > 1) - qsort(new_host_list, count, sizeof(memcached_server_st), compare_servers); - - new_host_list[0].count= count; - - - *error= MEMCACHED_SUCCESS; - return new_host_list; -} - -unsigned int memcached_server_list_count(memcached_server_st *ptr) -{ - if (ptr == NULL) - return 0; - - return ptr[0].count; -} - -void memcached_server_list_free(memcached_server_st *ptr) -{ - server_list_free(NULL, ptr); -} diff --git a/lib/memcached_io.c b/lib/memcached_io.c deleted file mode 100644 index b9261f3d..00000000 --- a/lib/memcached_io.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - Basic socket buffered IO -*/ - -#include "common.h" -#include "memcached_io.h" -#include -#include - -typedef enum { - MEM_READ, - MEM_WRITE, -} memc_read_or_write; - -static ssize_t io_flush(memcached_server_st *ptr, memcached_return *error); - -static memcached_return io_wait(memcached_server_st *ptr, - memc_read_or_write read_or_write) -{ - struct pollfd fds[1]; - short flags= 0; - int error; - - if (read_or_write == MEM_WRITE) /* write */ - flags= POLLOUT | POLLERR; - else - flags= POLLIN | POLLERR; - - memset(&fds, 0, sizeof(struct pollfd)); - fds[0].fd= ptr->fd; - fds[0].events= flags; - - error= poll(fds, 1, ptr->root->poll_timeout); - - if (error == 1) - return MEMCACHED_SUCCESS; - else if (error == 0) - { - return MEMCACHED_TIMEOUT; - } - - /* Imposssible for anything other then -1 */ - WATCHPOINT_ASSERT(error == -1); - memcached_quit_server(ptr, 1); - - return MEMCACHED_FAILURE; - -} - -#ifdef UNUSED -void memcached_io_preread(memcached_st *ptr) -{ - unsigned int x; - - return; - - for (x= 0; x < ptr->number_of_hosts; x++) - { - if (memcached_server_response_count(ptr, x) && - ptr->hosts[x].read_data_length < MEMCACHED_MAX_BUFFER ) - { - size_t data_read; - - data_read= read(ptr->hosts[x].fd, - ptr->hosts[x].read_ptr + ptr->hosts[x].read_data_length, - MEMCACHED_MAX_BUFFER - ptr->hosts[x].read_data_length); - if (data_read == -1) - continue; - - ptr->hosts[x].read_buffer_length+= data_read; - ptr->hosts[x].read_data_length+= data_read; - } - } -} -#endif - -ssize_t memcached_io_read(memcached_server_st *ptr, - char *buffer, size_t length) -{ - char *buffer_ptr; - - buffer_ptr= buffer; - - while (length) - { - uint8_t found_eof= 0; - if (!ptr->read_buffer_length) - { - ssize_t data_read; - - while (1) - { - data_read= read(ptr->fd, - ptr->read_buffer, - MEMCACHED_MAX_BUFFER); - if (data_read > 0) - break; - else if (data_read == -1) - { - ptr->cached_errno= errno; - switch (errno) - { - case EAGAIN: - { - memcached_return rc; - - rc= io_wait(ptr, MEM_READ); - - if (rc == MEMCACHED_SUCCESS) - continue; - } - /* fall trough */ - default: - { - memcached_quit_server(ptr, 1); - return -1; - } - } - } - else - { - found_eof= 1; - break; - } - } - - ptr->read_data_length= data_read; - ptr->read_buffer_length= data_read; - ptr->read_ptr= ptr->read_buffer; - } - - if (length > 1) - { - size_t difference; - - difference= (length > ptr->read_buffer_length) ? ptr->read_buffer_length : length; - - memcpy(buffer_ptr, ptr->read_ptr, difference); - length -= difference; - ptr->read_ptr+= difference; - ptr->read_buffer_length-= difference; - buffer_ptr+= difference; - } - else - { - *buffer_ptr= *ptr->read_ptr; - ptr->read_ptr++; - ptr->read_buffer_length--; - buffer_ptr++; - break; - } - - if (found_eof) - break; - } - - return (size_t)(buffer_ptr - buffer); -} - -ssize_t memcached_io_write(memcached_server_st *ptr, - char *buffer, size_t length, char with_flush) -{ - size_t original_length; - char* buffer_ptr; - - original_length= length; - buffer_ptr= buffer; - - while (length) - { - char *write_ptr; - size_t should_write; - - should_write= MEMCACHED_MAX_BUFFER - ptr->write_buffer_offset; - write_ptr= ptr->write_buffer + ptr->write_buffer_offset; - - should_write= (should_write < length) ? should_write : length; - - memcpy(write_ptr, buffer_ptr, should_write); - ptr->write_buffer_offset+= should_write; - buffer_ptr+= should_write; - length-= should_write; - - if (ptr->write_buffer_offset == MEMCACHED_MAX_BUFFER) - { - memcached_return rc; - ssize_t sent_length; - - sent_length= io_flush(ptr, &rc); - if (sent_length == -1) - return -1; - - WATCHPOINT_ASSERT(sent_length == MEMCACHED_MAX_BUFFER); - } - } - - if (with_flush) - { - memcached_return rc; - if (io_flush(ptr, &rc) == -1) - return -1; - } - - return original_length; -} - -memcached_return memcached_io_close(memcached_server_st *ptr) -{ - close(ptr->fd); - - return MEMCACHED_SUCCESS; -} - -static ssize_t io_flush(memcached_server_st *ptr, - memcached_return *error) -{ - size_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; - - if (ptr->write_buffer_offset == 0) - return 0; - - /* Looking for memory overflows */ - 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)); - - return_length= 0; - while (write_length) - { - WATCHPOINT_ASSERT(write_length > 0); - sent_length= 0; - if (ptr->type == MEMCACHED_CONNECTION_UDP) - { - struct addrinfo *ai; - - ai= ptr->address_info; - - /* Crappy test code */ - char buffer[HUGE_STRING_LEN + 8]; - memset(buffer, 0, HUGE_STRING_LEN + 8); - memcpy (buffer+8, local_write_ptr, write_length); - buffer[0]= 0; - buffer[1]= 0; - buffer[2]= 0; - buffer[3]= 0; - buffer[4]= 0; - buffer[5]= 1; - buffer[6]= 0; - buffer[7]= 0; - sent_length= sendto(ptr->fd, buffer, write_length + 8, 0, - (struct sockaddr *)ai->ai_addr, - ai->ai_addrlen); - if (sent_length == -1) - { - WATCHPOINT_ERRNO(errno); - WATCHPOINT_ASSERT(0); - } - sent_length-= 8; /* We remove the header */ - } - else - { - if ((ssize_t)(sent_length= write(ptr->fd, local_write_ptr, - write_length)) == -1) - { - switch (errno) - { - case ENOBUFS: - continue; - case EAGAIN: - { - memcached_return rc; - rc= io_wait(ptr, MEM_WRITE); - - if (rc == MEMCACHED_SUCCESS) - continue; - - memcached_quit_server(ptr, 1); - return -1; - } - default: - memcached_quit_server(ptr, 1); - ptr->cached_errno= errno; - *error= MEMCACHED_ERRNO; - return -1; - } - } - } - - local_write_ptr+= sent_length; - write_length-= sent_length; - return_length+= sent_length; - } - - WATCHPOINT_ASSERT(write_length == 0); - WATCHPOINT_ASSERT(return_length == ptr->write_buffer_offset); - ptr->write_buffer_offset= 0; - - return return_length; -} - -/* - Eventually we will just kill off the server with the problem. -*/ -void memcached_io_reset(memcached_server_st *ptr) -{ - memcached_quit_server(ptr, 0); -} diff --git a/lib/memcached_io.h b/lib/memcached_io.h deleted file mode 100644 index 30ac18b2..00000000 --- a/lib/memcached_io.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Server IO, Not public! */ -#include - -ssize_t memcached_io_write(memcached_server_st *ptr, - char *buffer, size_t length, char with_flush); -void memcached_io_reset(memcached_server_st *ptr); -ssize_t memcached_io_read(memcached_server_st *ptr, - char *buffer, size_t length); -memcached_return memcached_io_close(memcached_server_st *ptr); diff --git a/lib/memcached_key.c b/lib/memcached_key.c deleted file mode 100644 index ef1fe15f..00000000 --- a/lib/memcached_key.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "common.h" - -memcached_return memcachd_key_test(char **keys, size_t *key_length, - unsigned int number_of_keys) -{ - int x; - - for (x= 0; x < number_of_keys; x++) - { - int y; - for (y= 0; y < key_length[x]; y++) - { - if ((isgraph(keys[x][y])) == 0) - return MEMCACHED_BAD_KEY_PROVIDED; - } - } - - return MEMCACHED_SUCCESS; -} - diff --git a/lib/memcached_parse.c b/lib/memcached_parse.c deleted file mode 100644 index 366e77b5..00000000 --- a/lib/memcached_parse.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - I debated about putting this in the client library since it does an - action I don't really believe belongs in the library. - - Frankly its too damn useful not to be here though. -*/ - -#include -#include "common.h" - -memcached_server_st *memcached_servers_parse(char *server_strings) -{ - char *string; - unsigned int port; - char *begin_ptr; - char *end_ptr; - memcached_server_st *servers= NULL; - memcached_return rc; - - WATCHPOINT_ASSERT(server_strings); - - end_ptr= server_strings + strlen(server_strings); - - for (begin_ptr= server_strings, string= index(server_strings, ','); - begin_ptr != end_ptr; - string= index(begin_ptr, ',')) - { - char buffer[HUGE_STRING_LEN]; - char *ptr; - port= 0; - - if (string) - { - memcpy(buffer, begin_ptr, string - begin_ptr); - buffer[(unsigned int)(string - begin_ptr)]= 0; - begin_ptr= string+1; - } - else - { - size_t length= strlen(begin_ptr); - memcpy(buffer, begin_ptr, length); - buffer[length]= 0; - begin_ptr= end_ptr; - } - - ptr= index(buffer, ':'); - - if (ptr) - { - ptr[0]= 0; - - ptr++; - - port= strtol(ptr, (char **)NULL, 10); - } - - servers= memcached_server_list_append(servers, buffer, port, &rc); - - if (isspace(*begin_ptr)) - begin_ptr++; - } - - return servers; -} diff --git a/lib/memcached_quit.c b/lib/memcached_quit.c deleted file mode 100644 index 9874bb6e..00000000 --- a/lib/memcached_quit.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "common.h" - -/* - This closes all connections (forces flush of input as well). - - Maybe add a host specific, or key specific version? - - The reason we send "quit" is that in case we have buffered IO, this - will force data to be completed. -*/ - -void memcached_quit_server(memcached_server_st *ptr, uint8_t io_death) -{ - if (ptr->fd != -1) - { - if (io_death == 0) - { - memcached_return rc; - ssize_t read_length; - char buffer[MEMCACHED_MAX_BUFFER]; - - rc= memcached_do(ptr, "quit\r\n", 6, 1); - WATCHPOINT_ASSERT(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_FETCH_NOTFINISHED); - - /* read until socket is closed, or there is an error - * closing the socket before all data is read - * results in server throwing away all data which is - * not read - */ - while ((read_length= - memcached_io_read(ptr, buffer, sizeof(buffer)/sizeof(*buffer))) - > 0) - { - ; - } - memcached_io_close(ptr); - } - - ptr->fd= -1; - ptr->write_buffer_offset= 0; - ptr->read_buffer_length= 0; - ptr->read_ptr= ptr->read_buffer; - memcached_server_response_reset(ptr); - } -} - -void memcached_quit(memcached_st *ptr) -{ - unsigned int x; - - if (ptr->hosts == NULL || - ptr->number_of_hosts == 0) - return; - - if (ptr->hosts && ptr->number_of_hosts) - { - for (x= 0; x < ptr->number_of_hosts; x++) - memcached_quit_server(&ptr->hosts[x], 0); - } -} diff --git a/lib/memcached_response.c b/lib/memcached_response.c deleted file mode 100644 index 6f9e7c33..00000000 --- a/lib/memcached_response.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - Memcached library - - memcached_response() is used to determine the return result - from an issued command. -*/ - -#include "common.h" -#include "memcached_io.h" - -memcached_return memcached_response(memcached_server_st *ptr, - char *buffer, size_t buffer_length, - memcached_result_st *result) -{ - unsigned int x; - size_t send_length; - char *buffer_ptr; - unsigned int max_messages; - - - send_length= 0; - /* UDP at the moment is odd...*/ - if (ptr->type == MEMCACHED_CONNECTION_UDP) - { - char buffer[8]; - ssize_t read_length; - - return MEMCACHED_SUCCESS; - - read_length= memcached_io_read(ptr, buffer, 8); - } - - /* We may have old commands in the buffer not set, first purge */ - if (ptr->root->flags & MEM_NO_BLOCK) - (void)memcached_io_write(ptr, NULL, 0, 1); - - max_messages= memcached_server_response_count(ptr); - for (x= 0; x < max_messages; x++) - { - size_t total_length= 0; - buffer_ptr= buffer; - - - while (1) - { - ssize_t read_length; - - read_length= memcached_io_read(ptr, buffer_ptr, 1); - WATCHPOINT_ASSERT(isgraph(*buffer_ptr) || isspace(*buffer_ptr)); - - if (read_length != 1) - { - memcached_io_reset(ptr); - return MEMCACHED_UNKNOWN_READ_FAILURE; - } - - if (*buffer_ptr == '\n') - break; - else - buffer_ptr++; - - total_length++; - WATCHPOINT_ASSERT(total_length <= buffer_length); - - if (total_length >= buffer_length) - { - memcached_io_reset(ptr); - return MEMCACHED_PROTOCOL_ERROR; - } - } - buffer_ptr++; - *buffer_ptr= 0; - - memcached_server_response_decrement(ptr); - } - - switch(buffer[0]) - { - case 'V': /* VALUE || VERSION */ - if (buffer[1] == 'A') /* VALUE */ - { - memcached_return rc; - - /* We add back in one because we will need to search for END */ - memcached_server_response_increment(ptr); - if (result) - rc= value_fetch(ptr, buffer, result); - else - rc= value_fetch(ptr, buffer, &ptr->root->result); - - return rc; - } - else if (buffer[1] == 'E') /* VERSION */ - { - return MEMCACHED_SUCCESS; - } - else - { - WATCHPOINT_STRING(buffer); - WATCHPOINT_ASSERT(0); - memcached_io_reset(ptr); - return MEMCACHED_UNKNOWN_READ_FAILURE; - } - case 'O': /* OK */ - return MEMCACHED_SUCCESS; - case 'S': /* STORED STATS SERVER_ERROR */ - { - if (buffer[2] == 'A') /* STORED STATS */ - { - memcached_server_response_increment(ptr); - return MEMCACHED_STAT; - } - else if (buffer[1] == 'E') - return MEMCACHED_SERVER_ERROR; - else if (buffer[1] == 'T') - return MEMCACHED_STORED; - else - { - WATCHPOINT_STRING(buffer); - WATCHPOINT_ASSERT(0); - memcached_io_reset(ptr); - return MEMCACHED_UNKNOWN_READ_FAILURE; - } - } - case 'D': /* DELETED */ - return MEMCACHED_DELETED; - case 'N': /* NOT_FOUND */ - { - if (buffer[4] == 'F') - return MEMCACHED_NOTFOUND; - else if (buffer[4] == 'S') - return MEMCACHED_NOTSTORED; - else - { - memcached_io_reset(ptr); - return MEMCACHED_UNKNOWN_READ_FAILURE; - } - } - case 'E': /* PROTOCOL ERROR or END */ - { - if (buffer[1] == 'N') - return MEMCACHED_END; - else if (buffer[1] == 'R') - { - memcached_io_reset(ptr); - return MEMCACHED_PROTOCOL_ERROR; - } - else if (buffer[1] == 'X') - { - memcached_io_reset(ptr); - return MEMCACHED_DATA_EXISTS; - } - else - { - memcached_io_reset(ptr); - return MEMCACHED_UNKNOWN_READ_FAILURE; - } - } - case 'C': /* CLIENT ERROR */ - memcached_io_reset(ptr); - return MEMCACHED_CLIENT_ERROR; - default: - memcached_io_reset(ptr); - return MEMCACHED_UNKNOWN_READ_FAILURE; - - } - - return MEMCACHED_SUCCESS; -} - -char *memcached_result_value(memcached_result_st *ptr) -{ - memcached_string_st *sptr= &ptr->value; - return memcached_string_value(sptr); -} - -size_t memcached_result_length(memcached_result_st *ptr) -{ - memcached_string_st *sptr= &ptr->value; - return memcached_string_length(sptr); -} diff --git a/lib/memcached_result.c b/lib/memcached_result.c deleted file mode 100644 index cf3894be..00000000 --- a/lib/memcached_result.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - memcached_result_st are used to internally represent the return values from - memcached. We use a structure so that long term as identifiers are added - to memcached we will be able to absorb new attributes without having - to addjust the entire API. -*/ -#include "common.h" - -memcached_result_st *memcached_result_create(memcached_st *memc, - memcached_result_st *ptr) -{ - /* Saving malloc calls :) */ - if (ptr) - { - memset(ptr, 0, sizeof(memcached_result_st)); - ptr->is_allocated= MEMCACHED_NOT_ALLOCATED; - } - else - { - if (memc->call_malloc) - ptr= (memcached_result_st *)memc->call_malloc(memc, sizeof(memcached_result_st)); - else - ptr= (memcached_result_st *)malloc(sizeof(memcached_result_st)); - - if (ptr == NULL) - return NULL; - memset(ptr, 0, sizeof(memcached_result_st)); - ptr->is_allocated= MEMCACHED_ALLOCATED; - } - - ptr->root= memc; - memcached_string_create(memc, &ptr->value, 0); - WATCHPOINT_ASSERT(ptr->value.string == NULL); - WATCHPOINT_ASSERT(ptr->value.is_allocated == MEMCACHED_NOT_ALLOCATED); - - return ptr; -} - -void memcached_result_free(memcached_result_st *ptr) -{ - if (ptr == NULL) - return; - - memcached_string_free(&ptr->value); - - if (ptr->is_allocated == MEMCACHED_ALLOCATED) - free(ptr); - else - ptr->is_allocated= MEMCACHED_USED; -} diff --git a/lib/memcached_server.c b/lib/memcached_server.c deleted file mode 100644 index fd86e6d6..00000000 --- a/lib/memcached_server.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "common.h" - -memcached_return memcached_server_cursor(memcached_st *ptr, - memcached_server_function *callback, - void *context, - unsigned int number_of_callbacks) -{ - unsigned int y; - - for (y= 0; y < ptr->number_of_hosts; y++) - { - unsigned int x; - - for (x= 0; x < number_of_callbacks; x++) - { - unsigned int iferror; - - iferror= (*callback[x])(ptr, &ptr->hosts[y], context); - - if (iferror) - continue; - } - } - - return MEMCACHED_SUCCESS; -} diff --git a/lib/memcached_stats.c b/lib/memcached_stats.c deleted file mode 100644 index a1ef99f3..00000000 --- a/lib/memcached_stats.c +++ /dev/null @@ -1,365 +0,0 @@ -/* -*/ - -#include "common.h" - -static char *memcached_stat_keys[] = { - "pid", - "uptime", - "time", - "version", - "pointer_size", - "rusage_user", - "rusage_system", - "curr_items", - "total_items", - "bytes", - "curr_connections", - "total_connections", - "connection_structures", - "cmd_get", - "cmd_set", - "get_hits", - "get_misses", - "evictions", - "bytes_read", - "bytes_written", - "limit_maxbytes", - "threads", - NULL -}; - - -static void set_data(memcached_stat_st *stat, char *key, char *value) -{ - - if(strlen(key) < 1) - { - fprintf(stderr, "Invalid key %s\n", key); - } - else if (!strcmp("pid", key)) - { - stat->pid= strtol(value, (char **)NULL, 10); - } - else if (!strcmp("uptime", key)) - { - stat->uptime= strtol(value, (char **)NULL, 10); - } - else if (!strcmp("time", key)) - { - stat->time= strtol(value, (char **)NULL, 10); - } - else if (!strcmp("version", key)) - { - memcpy(stat->version, value, strlen(value)); - stat->version[strlen(value)]= 0; - } - else if (!strcmp("pointer_size", key)) - { - stat->pointer_size= strtol(value, (char **)NULL, 10); - } - else if (!strcmp("rusage_user", key)) - { - char *walk_ptr; - for (walk_ptr= value; (!ispunct(*walk_ptr)); walk_ptr++); - *walk_ptr= 0; - walk_ptr++; - stat->rusage_user_seconds= strtol(value, (char **)NULL, 10); - stat->rusage_user_microseconds= strtol(walk_ptr, (char **)NULL, 10); - } - else if (!strcmp("rusage_system", key)) - { - char *walk_ptr; - for (walk_ptr= value; (!ispunct(*walk_ptr)); walk_ptr++); - *walk_ptr= 0; - walk_ptr++; - stat->rusage_system_seconds= strtol(value, (char **)NULL, 10); - stat->rusage_system_microseconds= strtol(walk_ptr, (char **)NULL, 10); - } - else if (!strcmp("curr_items", key)) - { - stat->curr_items= strtol(value, (char **)NULL, 10); - } - else if (!strcmp("total_items", key)) - { - stat->total_items= strtol(value, (char **)NULL, 10); - } - else if (!strcmp("bytes", key)) - { - stat->bytes= strtoll(value, (char **)NULL, 10); - } - else if (!strcmp("curr_connections", key)) - { - stat->curr_connections= strtoll(value, (char **)NULL, 10); - } - else if (!strcmp("total_connections", key)) - { - stat->total_connections= strtoll(value, (char **)NULL, 10); - } - else if (!strcmp("connection_structures", key)) - { - stat->connection_structures= strtol(value, (char **)NULL, 10); - } - else if (!strcmp("cmd_get", key)) - { - stat->cmd_get= strtoll(value, (char **)NULL, 10); - } - else if (!strcmp("cmd_set", key)) - { - stat->cmd_set= strtoll(value, (char **)NULL, 10); - } - else if (!strcmp("get_hits", key)) - { - stat->get_hits= strtoll(value, (char **)NULL, 10); - } - else if (!strcmp("get_misses", key)) - { - stat->get_misses= (uint64_t)strtoll(value, (char **)NULL, 10); - } - else if (!strcmp("evictions", key)) - { - stat->evictions= (uint64_t)strtoll(value, (char **)NULL, 10); - } - else if (!strcmp("bytes_read", key)) - { - stat->bytes_read= strtoll(value, (char **)NULL, 10); - } - else if (!strcmp("bytes_written", key)) - { - stat->bytes_written= strtoll(value, (char **)NULL, 10); - } - else if (!strcmp("limit_maxbytes", key)) - { - stat->limit_maxbytes= strtol(value, (char **)NULL, 10); - } - else if (!strcmp("threads", key)) - { - stat->threads= strtol(key, (char **)NULL, 10); - } - else - { - fprintf(stderr, "Unknown key %s\n", key); - } -} - -char *memcached_stat_get_value(memcached_st *ptr, memcached_stat_st *stat, - char *key, memcached_return *error) -{ - char buffer[SMALL_STRING_LEN]; - size_t length; - char *ret; - - *error= MEMCACHED_SUCCESS; - - if (!memcmp("pid", key, strlen("pid"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->pid); - else if (!memcmp("uptime", key, strlen("uptime"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->uptime); - else if (!memcmp("time", key, strlen("time"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->time); - else if (!memcmp("version", key, strlen("version"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%s", stat->version); - else if (!memcmp("pointer_size", key, strlen("pointer_size"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->pointer_size); - else if (!memcmp("rusage_user", key, strlen("rusage_user"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u.%u", stat->rusage_user_seconds, stat->rusage_user_microseconds); - else if (!memcmp("rusage_system", key, strlen("rusage_system"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u.%u", stat->rusage_system_seconds, stat->rusage_system_microseconds); - else if (!memcmp("curr_items", key, strlen("curr_items"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->curr_items); - else if (!memcmp("total_items", key, strlen("total_items"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->total_items); - else if (!memcmp("bytes", key, strlen("bytes"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes); - else if (!memcmp("curr_connections", key, strlen("curr_connections"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->curr_connections); - else if (!memcmp("total_connections", key, strlen("total_connections"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->total_connections); - else if (!memcmp("connection_structures", key, strlen("connection_structures"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->connection_structures); - else if (!memcmp("cmd_get", key, strlen("cmd_get"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->cmd_get); - else if (!memcmp("cmd_set", key, strlen("cmd_set"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->cmd_set); - else if (!memcmp("get_hits", key, strlen("get_hits"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->get_hits); - else if (!memcmp("get_misses", key, strlen("get_misses"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->get_misses); - else if (!memcmp("evictions", key, strlen("evictions"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->evictions); - else if (!memcmp("bytes_read", key, strlen("bytes_read"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes_read); - else if (!memcmp("bytes_written", key, strlen("bytes_written"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes_written); - else if (!memcmp("limit_maxbytes", key, strlen("limit_maxbytes"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%llu", stat->limit_maxbytes); - else if (!memcmp("threads", key, strlen("threads"))) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->threads); - else - { - *error= MEMCACHED_NOTFOUND; - return NULL; - } - - if (ptr->call_malloc) - ret= ptr->call_malloc(ptr, length + 1); - else - ret= malloc(length + 1); - memcpy(ret, buffer, length); - ret[length]= '\0'; - - return ret; -} - -static memcached_return memcached_stats_fetch(memcached_st *ptr, - memcached_stat_st *stat, - char *args, - unsigned int server_key) -{ - memcached_return rc; - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - size_t send_length; - - if (args) - send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "stats %s\r\n", args); - else - send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "stats\r\n"); - - if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) - return MEMCACHED_WRITE_FAILURE; - - rc= memcached_do(&ptr->hosts[server_key], buffer, send_length, 1); - if (rc != MEMCACHED_SUCCESS) - goto error; - - while (1) - { - rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); - - if (rc == MEMCACHED_STAT) - { - char *string_ptr, *end_ptr; - char *key, *value; - - string_ptr= buffer; - string_ptr+= 5; /* Move past STAT */ - for (end_ptr= string_ptr; isgraph(*end_ptr); end_ptr++); - key= string_ptr; - key[(size_t)(end_ptr-string_ptr)]= 0; - - string_ptr= end_ptr + 1; - for (end_ptr= string_ptr; !(isspace(*end_ptr)); end_ptr++); - value= string_ptr; - value[(size_t)(end_ptr-string_ptr)]= 0; - string_ptr= end_ptr + 2; - set_data(stat, key, value); - } - else - break; - } - -error: - if (rc == MEMCACHED_END) - return MEMCACHED_SUCCESS; - else - return rc; -} - -memcached_stat_st *memcached_stat(memcached_st *ptr, char *args, memcached_return *error) -{ - unsigned int x; - memcached_return rc; - memcached_stat_st *stats; - - if (ptr->call_malloc) - stats= (memcached_stat_st *)ptr->call_malloc(ptr, sizeof(memcached_stat_st)*(ptr->number_of_hosts)); - else - stats= (memcached_stat_st *)malloc(sizeof(memcached_stat_st)*(ptr->number_of_hosts)); - - if (!stats) - { - *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; - if (ptr->call_free) - ptr->call_free(ptr, stats); - else - free(stats); - - return NULL; - } - memset(stats, 0, sizeof(memcached_stat_st)*(ptr->number_of_hosts)); - - rc= MEMCACHED_SUCCESS; - for (x= 0; x < ptr->number_of_hosts; x++) - { - memcached_return temp_return; - - temp_return= memcached_stats_fetch(ptr, stats + x, args, x); - if (temp_return != MEMCACHED_SUCCESS) - rc= MEMCACHED_SOME_ERRORS; - } - - *error= rc; - return stats; -} - -memcached_return memcached_stat_servername(memcached_stat_st *stat, char *args, - char *hostname, unsigned int port) -{ - memcached_return rc; - memcached_st memc; - - memcached_create(&memc); - - memcached_server_add(&memc, hostname, port); - - rc= memcached_stats_fetch(&memc, stat, args, 0); - - memcached_free(&memc); - - return rc; -} - -/* - We make a copy of the keys since at some point in the not so distant future - we will add support for "found" keys. -*/ -char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *stat, - memcached_return *error) -{ - char **list; - size_t length= sizeof(memcached_stat_keys); - - if (ptr->call_malloc) - list= (char **)ptr->call_malloc(ptr, length); - else - list= (char **)malloc(length); - - if (!list) - { - *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; - return NULL; - } - memset(list, 0, sizeof(memcached_stat_keys)); - - memcpy(list, memcached_stat_keys, sizeof(memcached_stat_keys)); - - *error= MEMCACHED_SUCCESS; - - return list; -} - -void memcached_stat_free(memcached_st *ptr, memcached_stat_st *stat) -{ - if (stat == NULL) - { - WATCHPOINT_ASSERT(0); /* Be polite, but when debugging catch this as an error */ - return; - } - - if (ptr && ptr->call_free) - ptr->call_free(ptr, stat); - else - free(stat); -} diff --git a/lib/memcached_storage.c b/lib/memcached_storage.c deleted file mode 100644 index fb3e6b2b..00000000 --- a/lib/memcached_storage.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - Memcached library - - memcached_set() - memcached_replace() - memcached_add() - -*/ - -#include "common.h" -#include "memcached_io.h" - -typedef enum { - SET_OP, - REPLACE_OP, - ADD_OP, - PREPEND_OP, - APPEND_OP, - CAS_OP, -} memcached_storage_action; - -/* Inline this */ -static char *storage_op_string(memcached_storage_action 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"; - }; - - return SET_OP; -} - -static inline memcached_return memcached_send(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags, - uint64_t cas, - memcached_storage_action verb) -{ - char to_write; - size_t write_length; - ssize_t sent_length; - memcached_return rc; - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - unsigned int server_key; - - WATCHPOINT_ASSERT(!(value == NULL && value_length > 0)); - WATCHPOINT_ASSERT(!(value && value_length == 0)); - - unlikely (key_length == 0) - return MEMCACHED_NO_KEY_PROVIDED; - - unlikely (ptr->number_of_hosts == 0) - return MEMCACHED_NO_SERVERS; - - if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED)) - return MEMCACHED_BAD_KEY_PROVIDED; - - server_key= memcached_generate_hash(ptr, master_key, master_key_length); - - if (cas) - write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "%s %.*s %u %llu %zu %llu\r\n", storage_op_string(verb), - (int)key_length, key, flags, - (unsigned long long)expiration, value_length, - (unsigned long long)cas); - else - write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "%s %.*s %u %llu %zu\r\n", storage_op_string(verb), - (int)key_length, key, flags, - (unsigned long long)expiration, value_length); - - if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) - { - rc= MEMCACHED_WRITE_FAILURE; - goto error; - } - - rc= memcached_do(&ptr->hosts[server_key], buffer, write_length, 0); - if (rc != MEMCACHED_SUCCESS) - goto error; - - if ((sent_length= memcached_io_write(&ptr->hosts[server_key], value, value_length, 0)) == -1) - { - rc= MEMCACHED_WRITE_FAILURE; - goto error; - } - - if ((ptr->flags & MEM_BUFFER_REQUESTS) && verb == SET_OP) - to_write= 0; - else - to_write= 1; - - if ((sent_length= memcached_io_write(&ptr->hosts[server_key], "\r\n", 2, to_write)) == -1) - { - rc= MEMCACHED_WRITE_FAILURE; - goto error; - } - - if (to_write == 0) - return MEMCACHED_BUFFERED; - - rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); - - if (rc == MEMCACHED_STORED) - return MEMCACHED_SUCCESS; - else - return rc; - -error: - memcached_io_reset(&ptr->hosts[server_key]); - - return rc; -} - -memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags) -{ - memcached_return rc; - LIBMEMCACHED_MEMCACHED_SET_START(); - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, 0, SET_OP); - LIBMEMCACHED_MEMCACHED_SET_END(); - return rc; -} - -memcached_return memcached_add(memcached_st *ptr, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags) -{ - memcached_return rc; - LIBMEMCACHED_MEMCACHED_ADD_START(); - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, 0, ADD_OP); - LIBMEMCACHED_MEMCACHED_ADD_END(); - return rc; -} - -memcached_return memcached_replace(memcached_st *ptr, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags) -{ - memcached_return rc; - LIBMEMCACHED_MEMCACHED_REPLACE_START(); - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, 0, REPLACE_OP); - LIBMEMCACHED_MEMCACHED_REPLACE_END(); - return rc; -} - -memcached_return memcached_prepend(memcached_st *ptr, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags) -{ - memcached_return rc; - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, 0, PREPEND_OP); - return rc; -} - -memcached_return memcached_append(memcached_st *ptr, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags) -{ - memcached_return rc; - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, 0, APPEND_OP); - return rc; -} - -memcached_return memcached_cas(memcached_st *ptr, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags, - uint64_t cas) -{ - memcached_return rc; - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, cas, CAS_OP); - return rc; -} - -memcached_return memcached_set_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags) -{ - memcached_return rc; - LIBMEMCACHED_MEMCACHED_SET_START(); - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, 0, SET_OP); - LIBMEMCACHED_MEMCACHED_SET_END(); - return rc; -} - -memcached_return memcached_add_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags) -{ - memcached_return rc; - LIBMEMCACHED_MEMCACHED_ADD_START(); - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, 0, ADD_OP); - LIBMEMCACHED_MEMCACHED_ADD_END(); - return rc; -} - -memcached_return memcached_replace_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags) -{ - memcached_return rc; - LIBMEMCACHED_MEMCACHED_REPLACE_START(); - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, 0, REPLACE_OP); - LIBMEMCACHED_MEMCACHED_REPLACE_END(); - return rc; -} - -memcached_return memcached_prepend_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags) -{ - memcached_return rc; - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, 0, PREPEND_OP); - return rc; -} - -memcached_return memcached_append_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags) -{ - memcached_return rc; - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, 0, APPEND_OP); - return rc; -} - -memcached_return memcached_cas_by_key(memcached_st *ptr, - char *master_key, size_t master_key_length, - char *key, size_t key_length, - char *value, size_t value_length, - time_t expiration, - uint32_t flags, - uint64_t cas) -{ - memcached_return rc; - rc= memcached_send(ptr, key, key_length, - key, key_length, value, value_length, - expiration, flags, cas, CAS_OP); - return rc; -} diff --git a/lib/memcached_strerror.c b/lib/memcached_strerror.c deleted file mode 100644 index 3271682d..00000000 --- a/lib/memcached_strerror.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "common.h" - -char *memcached_strerror(memcached_st *ptr, memcached_return rc) -{ - switch (rc) - { - case MEMCACHED_SUCCESS: - return "SUCCESS"; - case MEMCACHED_FAILURE: - return "FAILURE"; - case MEMCACHED_HOST_LOOKUP_FAILURE: - return "HOSTNAME LOOKUP FAILURE"; - case MEMCACHED_CONNECTION_FAILURE: - return "CONNECTION FAILURE"; - case MEMCACHED_CONNECTION_BIND_FAILURE: - return "CONNECTION BIND FAILURE"; - case MEMCACHED_READ_FAILURE: - return "READ FAILURE"; - case MEMCACHED_UNKNOWN_READ_FAILURE: - return "UNKNOWN READ FAILURE"; - case MEMCACHED_PROTOCOL_ERROR: - return "PROTOCOL ERROR"; - case MEMCACHED_CLIENT_ERROR: - return "CLIENT ERROR"; - case MEMCACHED_SERVER_ERROR: - return "SERVER ERROR"; - case MEMCACHED_WRITE_FAILURE: - return "WRITE FAILURE"; - case MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE: - return "CONNECTION SOCKET CREATE FAILURE"; - case MEMCACHED_DATA_EXISTS: - return "CONNECTION DATA EXISTS"; - case MEMCACHED_DATA_DOES_NOT_EXIST: - return "CONNECTION DATA DOES NOT EXIST"; - case MEMCACHED_NOTSTORED: - return "NOT STORED"; - case MEMCACHED_STORED: - return "STORED"; - case MEMCACHED_NOTFOUND: - return "NOT FOUND"; - case MEMCACHED_MEMORY_ALLOCATION_FAILURE: - return "MEMORY ALLOCATION FAILURE"; - case MEMCACHED_PARTIAL_READ: - return "PARTIAL READ"; - case MEMCACHED_SOME_ERRORS: - return "SOME ERRORS WERE REPORTED"; - case MEMCACHED_NO_SERVERS: - return "NO SERVERS DEFINED"; - case MEMCACHED_END: - return "SERVER END"; - case MEMCACHED_DELETED: - return "SERVER DELETE"; - case MEMCACHED_VALUE: - return "SERVER VALUE"; - case MEMCACHED_STAT: - return "STAT VALUE"; - case MEMCACHED_ERRNO: - return "SYSTEM ERROR"; - case MEMCACHED_FAIL_UNIX_SOCKET: - return "COULD NOT OPEN UNIX SOCKET"; - case MEMCACHED_NOT_SUPPORTED: - return "ACTION NOT SUPPORTED"; - case MEMCACHED_FETCH_NOTFINISHED: - return "FETCH WAS NOT COMPLETED"; - case MEMCACHED_NO_KEY_PROVIDED: - return "A KEY LENGTH OF ZERO WAS PROVIDED"; - case MEMCACHED_BUFFERED: - return "ACTION QUEUED"; - case MEMCACHED_TIMEOUT: - return "A TIMEOUT OCCURRED"; - case MEMCACHED_BAD_KEY_PROVIDED: - return "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE"; - case MEMCACHED_MAXIMUM_RETURN: - return "Gibberish returned!"; - default: - return "Gibberish returned!"; - }; -} diff --git a/lib/memcached_string.c b/lib/memcached_string.c deleted file mode 100644 index 1595ec61..00000000 --- a/lib/memcached_string.c +++ /dev/null @@ -1,190 +0,0 @@ -#include "common.h" - -memcached_return memcached_string_check(memcached_string_st *string, size_t need) -{ - if (need && need > (size_t)(string->current_size - (size_t)(string->end - string->string))) - { - size_t current_offset= string->end - string->string; - char *new_value; - size_t adjust; - size_t new_size; - - /* This is the block multiplier. To keep it larger and surive division errors we must round it up */ - adjust= (need - (size_t)(string->current_size - (size_t)(string->end - string->string))) / string->block_size; - adjust++; - - new_size= sizeof(char) * (size_t)((adjust * string->block_size) + string->current_size); - /* Test for overflow */ - if (new_size < need) - return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - - if (string->root->call_realloc) - new_value= (char *)string->root->call_realloc(string->root, string->string, new_size); - else - new_value= (char *)realloc(string->string, new_size); - - if (new_value == NULL) - return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - - string->string= new_value; - string->end= string->string + current_offset; - - string->current_size+= (string->block_size * adjust); - } - - return MEMCACHED_SUCCESS; -} - -memcached_string_st *memcached_string_create(memcached_st *ptr, memcached_string_st *string, size_t initial_size) -{ - memcached_return rc; - - /* Saving malloc calls :) */ - if (string) - { - memset(string, 0, sizeof(memcached_string_st)); - string->is_allocated= MEMCACHED_NOT_ALLOCATED; - } - else - { - if (ptr->call_malloc) - string= (memcached_string_st *)ptr->call_malloc(ptr, sizeof(memcached_string_st)); - else - string= (memcached_string_st *)malloc(sizeof(memcached_string_st)); - - if (string == NULL) - return NULL; - memset(string, 0, sizeof(memcached_string_st)); - string->is_allocated= MEMCACHED_ALLOCATED; - } - string->block_size= MEMCACHED_BLOCK_SIZE; - string->root= ptr; - - rc= memcached_string_check(string, initial_size); - if (rc != MEMCACHED_SUCCESS) - { - if (ptr->call_free) - ptr->call_free(ptr, string); - else - free(string); - - return NULL; - } - - WATCHPOINT_ASSERT(string->string == string->end); - - return string; -} - -memcached_return memcached_string_append_character(memcached_string_st *string, - char character) -{ - memcached_return rc; - - WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); - - rc= memcached_string_check(string, 1); - - if (rc != MEMCACHED_SUCCESS) - return rc; - - *string->end= ' '; - string->end++; - - return MEMCACHED_SUCCESS; -} - -memcached_return memcached_string_append(memcached_string_st *string, - char *value, size_t length) -{ - memcached_return rc; - - WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); - - rc= memcached_string_check(string, length); - - if (rc != MEMCACHED_SUCCESS) - return rc; - - WATCHPOINT_ASSERT(length <= string->current_size); - WATCHPOINT_ASSERT(string->string); - WATCHPOINT_ASSERT(string->end >= string->string); - - memcpy(string->end, value, length); - string->end+= length; - - return MEMCACHED_SUCCESS; -} - -size_t memcached_string_backspace(memcached_string_st *string, size_t remove) -{ - WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); - - if (string->end - string->string > remove) - { - size_t difference; - - difference= string->end - string->string; - string->end= string->string; - - return difference; - } - string->end-= remove; - - return remove; -} - -char *memcached_string_c_copy(memcached_string_st *string) -{ - char *c_ptr; - - WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); - - if (memcached_string_length(string) == 0) - return NULL; - - if (string->root->call_malloc) - c_ptr= (char *)string->root->call_malloc(string->root, (memcached_string_length(string)+1) * sizeof(char)); - else - c_ptr= (char *)malloc((memcached_string_length(string)+1) * sizeof(char)); - - if (c_ptr == NULL) - return NULL; - - memcpy(c_ptr, memcached_string_value(string), memcached_string_length(string)); - c_ptr[memcached_string_length(string)]= 0; - - return c_ptr; -} - -memcached_return memcached_string_reset(memcached_string_st *string) -{ - WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); - string->end= string->string; - - return MEMCACHED_SUCCESS; -} - -void memcached_string_free(memcached_string_st *ptr) -{ - if (ptr == NULL) - return; - - if (ptr->string) - { - if (ptr->root->call_free) - ptr->root->call_free(ptr->root, ptr->string); - else - free(ptr->string); - } - - if (ptr->is_allocated == MEMCACHED_ALLOCATED) - { - if (ptr->root->call_free) - ptr->root->call_free(ptr->root, ptr); - else - free(ptr); - } - else - ptr->is_allocated= MEMCACHED_USED; -} diff --git a/lib/memcached_verbosity.c b/lib/memcached_verbosity.c deleted file mode 100644 index 7cfb073f..00000000 --- a/lib/memcached_verbosity.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "common.h" - -memcached_return memcached_verbosity(memcached_st *ptr, unsigned int verbosity) -{ - unsigned int x; - size_t send_length; - memcached_return rc; - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - - send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "verbosity %u\r\n", verbosity); - unlikely (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) - return MEMCACHED_WRITE_FAILURE; - - rc= MEMCACHED_SUCCESS; - for (x= 0; x < ptr->number_of_hosts; x++) - { - memcached_return rrc; - - rrc= memcached_do(&ptr->hosts[x], buffer, send_length, 1); - if (rrc != MEMCACHED_SUCCESS) - { - rc= MEMCACHED_SOME_ERRORS; - continue; - } - - rrc= memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); - if (rrc != MEMCACHED_SUCCESS) - rc= MEMCACHED_SOME_ERRORS; - } - - return rc; -} diff --git a/lib/memcached_version.c b/lib/memcached_version.c deleted file mode 100644 index e49d76f0..00000000 --- a/lib/memcached_version.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "common.h" - -const char * memcached_lib_version(void) -{ - return LIBMEMCACHED_VERSION_STRING; -} - -memcached_return memcached_version(memcached_st *ptr) -{ - unsigned int x; - size_t send_length; - memcached_return rc; - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - char *response_ptr; - char *command= "version\r\n"; - - send_length= strlen(command); - - rc= MEMCACHED_SUCCESS; - for (x= 0; x < ptr->number_of_hosts; x++) - { - memcached_return rrc; - - rrc= memcached_do(&ptr->hosts[x], command, send_length, 1); - if (rrc != MEMCACHED_SUCCESS) - { - rc= MEMCACHED_SOME_ERRORS; - continue; - } - - rrc= memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); - if (rrc != MEMCACHED_SUCCESS) - rc= MEMCACHED_SOME_ERRORS; - - /* Find the space, and then move one past it to copy version */ - response_ptr= index(buffer, ' '); - response_ptr++; - - ptr->hosts[x].major_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10); - response_ptr= index(response_ptr, '.'); - response_ptr++; - ptr->hosts[x].minor_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10); - response_ptr= index(response_ptr, '.'); - response_ptr++; - ptr->hosts[x].micro_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10); - } - - return rc; -} diff --git a/lib/murmur_hash.c b/lib/murmur_hash.c deleted file mode 100644 index abb2deda..00000000 --- a/lib/murmur_hash.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "common.h" - -/* - "Murmur"hash provided by Austin, tanjent@gmail.com -#define MURMUR_POSTMIX -*/ - -uint32_t murmur_hash(char *key, size_t length) -{ - const unsigned int m= 0x7fd652ad; - const int r= 16; - - uint32_t h= 0xdeadbeef; - - while(length >= 4) - { - h += *(unsigned int *)key; - h *= m; - h ^= h >> r; - - key += 4; - length -= 4; - } - - switch(length) - { - case 3: - h += key[2] << 16; - case 2: - h += key[1] << 8; - case 1: - default: - h += key[0]; - h *= m; - h ^= h >> r; - }; - -#ifdef MURMUR_POSTMIX - - h *= m; - h ^= h >> 10; - h *= m; - h ^= h >> 17; - -#endif - - return h; -} diff --git a/libmemcached/Makefile.am b/libmemcached/Makefile.am new file mode 100644 index 00000000..bd35e18a --- /dev/null +++ b/libmemcached/Makefile.am @@ -0,0 +1,76 @@ +EXTRA_DIST = libmemcached_probes.d + +INCLUDES = -I$(top_builddir) +LIBS = + +DTRACE = @DTRACE@ +DTRACEFLAGS = @DTRACEFLAGS@ +DTRACEFILES = memcached.o \ + memcached_strerror.o \ + memcached_connect.o \ + memcached_response.o \ + memcached_get.o \ + memcached_storage.o \ + memcached_delete.o \ + memcached_hash.o \ + memcached_auto.o \ + memcached_verbosity.o \ + memcached_quit.o \ + memcached_flush.o \ + memcached_string.o \ + memcached_stats.o + +noinst_HEADERS = libmemcached_probes.h \ + memcached_io.h \ + common.h + +pkginclude_HEADERS= memcached.h memcached.hh + +lib_LTLIBRARIES = libmemcached.la + +libmemcached_la_SOURCES = crc.c \ + hsieh_hash.c \ + memcached.c \ + memcached_auto.c \ + memcached_behavior.c \ + memcached_callback.c \ + memcached_connect.c \ + memcached_delete.c \ + memcached_do.c \ + memcached_fetch.c \ + memcached_fetch_execute.c \ + memcached_flush.c \ + memcached_get.c \ + memcached_hash.c \ + memcached_hosts.c \ + memcached_io.c \ + md5.c \ + memcached_key.c \ + memcached_quit.c \ + memcached_parse.c \ + memcached_response.c \ + memcached_result.c \ + memcached_server.c \ + memcached_storage.c \ + memcached_string.c \ + memcached_stats.c \ + memcached_strerror.c \ + memcached_verbosity.c \ + memcached_version.c \ + murmur_hash.c + +libmemcached_la_LIBADD = +libmemcached_la_LDFLAGS = -version-info $(MEMCACHED_LIBRARY_VERSION) + +if HAVE_DTRACE + libmemcached_la_LIBADD += libmemcached_probes.o +endif + +libmemcached_probes.h: libmemcached_probes.d + $(DTRACE) $(DTRACEFLAGS) -h -s libmemcached_probes.d + mv libmemcached_probes.h libmemcached_probes.h.bak + sed "s/#include //g" libmemcached_probes.h.bak > libmemcached_probes.h + rm libmemcached_probes.h.bak + +libmemcached_probes.o: + $(DTRACE) $(DTRACEFLAGS) -G -s libmemcached_probes.d $(DTRACEFILES) diff --git a/libmemcached/common.h b/libmemcached/common.h new file mode 100644 index 00000000..a70e65f3 --- /dev/null +++ b/libmemcached/common.h @@ -0,0 +1,131 @@ +/* + Common include file for libmemached +*/ + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + + + +#include +#include "memcached_io.h" + +#include + +#if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) +#define __builtin_expect(x, expected_value) (x) + +#define likely(x) __builtin_expect((x),1) +#define unlikely(x) __builtin_expect((x),0) + +#else + +#define likely(x) if((x)) +#define unlikely(x) if((x)) + +#endif + +#ifdef HAVE_DTRACE +#define _DTRACE_VERSION 1 +#else +#undef _DTRACE_VERSION +#endif + +#include "libmemcached_probes.h" + +#define MEMCACHED_BLOCK_SIZE 1024 +#define MEMCACHED_DEFAULT_COMMAND_SIZE 350 +#define SMALL_STRING_LEN 1024 +#define HUGE_STRING_LEN 8196 + + +typedef enum { + MEM_NO_BLOCK= (1 << 0), + MEM_TCP_NODELAY= (1 << 1), + MEM_REUSE_MEMORY= (1 << 2), + MEM_USE_MD5= (1 << 3), + MEM_USE_KETAMA= (1 << 4), + MEM_USE_CRC= (1 << 5), + MEM_USE_CACHE_LOOKUPS= (1 << 6), + MEM_SUPPORT_CAS= (1 << 7), + MEM_BUFFER_REQUESTS= (1 << 8), + MEM_USE_SORT_HOSTS= (1 << 9), + MEM_VERIFY_KEY= (1 << 10), +} memcached_flags; + +/* Hashing algo */ +void md5_signature(unsigned char *key, unsigned int length, unsigned char *result); +uint32_t hash_crc32(const char *data, + size_t data_len); +uint32_t hsieh_hash(char *key, size_t key_length); +uint32_t murmur_hash(char *key, size_t key_length); + +memcached_return memcached_connect(memcached_server_st *ptr); +memcached_return memcached_response(memcached_server_st *ptr, + char *buffer, size_t buffer_length, + memcached_result_st *result); +unsigned int memcached_generate_hash(memcached_st *ptr, char *key, size_t key_length); +void memcached_quit_server(memcached_server_st *ptr, uint8_t io_death); + +#define memcached_server_response_increment(A) (A)->cursor_active++ +#define memcached_server_response_decrement(A) (A)->cursor_active-- +#define memcached_server_response_reset(A) (A)->cursor_active=0 + +/* String Struct */ +#define memcached_string_length(A) (size_t)((A)->end - (A)->string) +#define memcached_string_set_length(A, B) (A)->end= (A)->string + B +#define memcached_string_size(A) (A)->current_size +#define memcached_string_value(A) (A)->string + +memcached_string_st *memcached_string_create(memcached_st *ptr, + memcached_string_st *string, + size_t initial_size); +memcached_return memcached_string_check(memcached_string_st *string, size_t need); +char *memcached_string_c_copy(memcached_string_st *string); +memcached_return memcached_string_append_character(memcached_string_st *string, + char character); +memcached_return memcached_string_append(memcached_string_st *string, + char *value, size_t length); +size_t memcached_string_backspace(memcached_string_st *string, size_t remove); +memcached_return memcached_string_reset(memcached_string_st *string); +void memcached_string_free(memcached_string_st *string); +memcached_return memcached_do(memcached_server_st *ptr, char *commmand, + size_t command_length, uint8_t with_flush); +memcached_return memcached_version(memcached_st *ptr); +memcached_return value_fetch(memcached_server_st *ptr, + char *buffer, + memcached_result_st *result); +void server_list_free(memcached_st *ptr, memcached_server_st *servers); + +memcached_return memcachd_key_test(char **keys, size_t *key_length, + unsigned int number_of_keys); + +#endif /* __COMMON_H__ */ diff --git a/libmemcached/crc.c b/libmemcached/crc.c new file mode 100644 index 00000000..ed22adc4 --- /dev/null +++ b/libmemcached/crc.c @@ -0,0 +1,87 @@ +/* The crc32 functions and data was originally written by Spencer + * Garrett and was gleaned from the PostgreSQL source + * tree via the files contrib/ltree/crc32.[ch] and from FreeBSD at + * src/usr.bin/cksum/crc32.c. + */ + +#include "common.h" + +static const uint32_t crc32tab[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + + +uint32_t hash_crc32(const char *key, size_t key_length) +{ + uint32_t x; + uint32_t crc; + crc= ~0; + + for (x= 0; x < key_length; x++) + crc= (crc >> 8) ^ crc32tab[(crc ^ (key[x])) & 0xff]; + + return ~crc; +} diff --git a/libmemcached/hsieh_hash.c b/libmemcached/hsieh_hash.c new file mode 100644 index 00000000..9f42a94d --- /dev/null +++ b/libmemcached/hsieh_hash.c @@ -0,0 +1,65 @@ +/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh + * derivative license. + * See: http://www.azillionmonkeys.com/qed/weblicense.html for license + * details. + * http://www.azillionmonkeys.com/qed/hash.html +*/ + +#include "common.h" + +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif + +uint32_t hsieh_hash(char *key, size_t key_length) +{ + uint32_t hash = 0, tmp; + int rem; + + if (key_length <= 0 || key == NULL) return 0; + + rem = key_length & 3; + key_length >>= 2; + + /* Main loop */ + for (;key_length > 0; key_length--) { + hash += get16bits (key); + tmp = (get16bits (key+2) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + key += 2*sizeof (uint16_t); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) { + case 3: hash += get16bits (key); + hash ^= hash << 16; + hash ^= key[sizeof (uint16_t)] << 18; + hash += hash >> 11; + break; + case 2: hash += get16bits (key); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: hash += *key; + hash ^= hash << 10; + hash += hash >> 1; + } + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; +} + diff --git a/libmemcached/libmemcached_probes.d b/libmemcached/libmemcached_probes.d new file mode 100644 index 00000000..ae68e34c --- /dev/null +++ b/libmemcached/libmemcached_probes.d @@ -0,0 +1,24 @@ +provider libmemcached { + probe memcached_delete_start(); + probe memcached_delete_end(); + probe memcached_increment_start(); + probe memcached_increment_end(); + probe memcached_decrement_start(); + probe memcached_decrement_end(); + probe memcached_flush_start(); + probe memcached_flush_end(); + probe memcached_set_start(); + probe memcached_set_end(); + probe memcached_add_start(); + probe memcached_add_end(); + probe memcached_replace_start(); + probe memcached_replace_end(); + probe memcached_get_start(); + probe memcached_get_end(); + probe memcached_mget_start(); + probe memcached_mget_end(); + probe memcached_connect_start(); + probe memcached_connect_end(); + probe memcached_server_add_start(); + probe memcached_server_add_end(); +}; diff --git a/libmemcached/libmemcached_probes.h b/libmemcached/libmemcached_probes.h new file mode 100644 index 00000000..cf59cc59 --- /dev/null +++ b/libmemcached/libmemcached_probes.h @@ -0,0 +1,205 @@ +/* + * Generated by dtrace(1M). + */ + +#ifndef _LIBMEMCACHED_PROBES_H +#define _LIBMEMCACHED_PROBES_H + + + +#ifdef __cplusplus +extern "C" { +#endif + +#if _DTRACE_VERSION + +#define LIBMEMCACHED_MEMCACHED_ADD_END() \ + __dtrace_libmemcached___memcached_add_end() +#define LIBMEMCACHED_MEMCACHED_ADD_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_add_end() +#define LIBMEMCACHED_MEMCACHED_ADD_START() \ + __dtrace_libmemcached___memcached_add_start() +#define LIBMEMCACHED_MEMCACHED_ADD_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_add_start() +#define LIBMEMCACHED_MEMCACHED_CONNECT_END() \ + __dtrace_libmemcached___memcached_connect_end() +#define LIBMEMCACHED_MEMCACHED_CONNECT_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_connect_end() +#define LIBMEMCACHED_MEMCACHED_CONNECT_START() \ + __dtrace_libmemcached___memcached_connect_start() +#define LIBMEMCACHED_MEMCACHED_CONNECT_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_connect_start() +#define LIBMEMCACHED_MEMCACHED_DECREMENT_END() \ + __dtrace_libmemcached___memcached_decrement_end() +#define LIBMEMCACHED_MEMCACHED_DECREMENT_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_decrement_end() +#define LIBMEMCACHED_MEMCACHED_DECREMENT_START() \ + __dtrace_libmemcached___memcached_decrement_start() +#define LIBMEMCACHED_MEMCACHED_DECREMENT_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_decrement_start() +#define LIBMEMCACHED_MEMCACHED_DELETE_END() \ + __dtrace_libmemcached___memcached_delete_end() +#define LIBMEMCACHED_MEMCACHED_DELETE_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_delete_end() +#define LIBMEMCACHED_MEMCACHED_DELETE_START() \ + __dtrace_libmemcached___memcached_delete_start() +#define LIBMEMCACHED_MEMCACHED_DELETE_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_delete_start() +#define LIBMEMCACHED_MEMCACHED_FLUSH_END() \ + __dtrace_libmemcached___memcached_flush_end() +#define LIBMEMCACHED_MEMCACHED_FLUSH_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_flush_end() +#define LIBMEMCACHED_MEMCACHED_FLUSH_START() \ + __dtrace_libmemcached___memcached_flush_start() +#define LIBMEMCACHED_MEMCACHED_FLUSH_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_flush_start() +#define LIBMEMCACHED_MEMCACHED_GET_END() \ + __dtrace_libmemcached___memcached_get_end() +#define LIBMEMCACHED_MEMCACHED_GET_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_get_end() +#define LIBMEMCACHED_MEMCACHED_GET_START() \ + __dtrace_libmemcached___memcached_get_start() +#define LIBMEMCACHED_MEMCACHED_GET_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_get_start() +#define LIBMEMCACHED_MEMCACHED_INCREMENT_END() \ + __dtrace_libmemcached___memcached_increment_end() +#define LIBMEMCACHED_MEMCACHED_INCREMENT_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_increment_end() +#define LIBMEMCACHED_MEMCACHED_INCREMENT_START() \ + __dtrace_libmemcached___memcached_increment_start() +#define LIBMEMCACHED_MEMCACHED_INCREMENT_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_increment_start() +#define LIBMEMCACHED_MEMCACHED_MGET_END() \ + __dtrace_libmemcached___memcached_mget_end() +#define LIBMEMCACHED_MEMCACHED_MGET_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_mget_end() +#define LIBMEMCACHED_MEMCACHED_MGET_START() \ + __dtrace_libmemcached___memcached_mget_start() +#define LIBMEMCACHED_MEMCACHED_MGET_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_mget_start() +#define LIBMEMCACHED_MEMCACHED_REPLACE_END() \ + __dtrace_libmemcached___memcached_replace_end() +#define LIBMEMCACHED_MEMCACHED_REPLACE_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_replace_end() +#define LIBMEMCACHED_MEMCACHED_REPLACE_START() \ + __dtrace_libmemcached___memcached_replace_start() +#define LIBMEMCACHED_MEMCACHED_REPLACE_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_replace_start() +#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_END() \ + __dtrace_libmemcached___memcached_server_add_end() +#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_server_add_end() +#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_START() \ + __dtrace_libmemcached___memcached_server_add_start() +#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_server_add_start() +#define LIBMEMCACHED_MEMCACHED_SET_END() \ + __dtrace_libmemcached___memcached_set_end() +#define LIBMEMCACHED_MEMCACHED_SET_END_ENABLED() \ + __dtraceenabled_libmemcached___memcached_set_end() +#define LIBMEMCACHED_MEMCACHED_SET_START() \ + __dtrace_libmemcached___memcached_set_start() +#define LIBMEMCACHED_MEMCACHED_SET_START_ENABLED() \ + __dtraceenabled_libmemcached___memcached_set_start() + + +extern void __dtrace_libmemcached___memcached_add_end(void); +extern int __dtraceenabled_libmemcached___memcached_add_end(void); +extern void __dtrace_libmemcached___memcached_add_start(void); +extern int __dtraceenabled_libmemcached___memcached_add_start(void); +extern void __dtrace_libmemcached___memcached_connect_end(void); +extern int __dtraceenabled_libmemcached___memcached_connect_end(void); +extern void __dtrace_libmemcached___memcached_connect_start(void); +extern int __dtraceenabled_libmemcached___memcached_connect_start(void); +extern void __dtrace_libmemcached___memcached_decrement_end(void); +extern int __dtraceenabled_libmemcached___memcached_decrement_end(void); +extern void __dtrace_libmemcached___memcached_decrement_start(void); +extern int __dtraceenabled_libmemcached___memcached_decrement_start(void); +extern void __dtrace_libmemcached___memcached_delete_end(void); +extern int __dtraceenabled_libmemcached___memcached_delete_end(void); +extern void __dtrace_libmemcached___memcached_delete_start(void); +extern int __dtraceenabled_libmemcached___memcached_delete_start(void); +extern void __dtrace_libmemcached___memcached_flush_end(void); +extern int __dtraceenabled_libmemcached___memcached_flush_end(void); +extern void __dtrace_libmemcached___memcached_flush_start(void); +extern int __dtraceenabled_libmemcached___memcached_flush_start(void); +extern void __dtrace_libmemcached___memcached_get_end(void); +extern int __dtraceenabled_libmemcached___memcached_get_end(void); +extern void __dtrace_libmemcached___memcached_get_start(void); +extern int __dtraceenabled_libmemcached___memcached_get_start(void); +extern void __dtrace_libmemcached___memcached_increment_end(void); +extern int __dtraceenabled_libmemcached___memcached_increment_end(void); +extern void __dtrace_libmemcached___memcached_increment_start(void); +extern int __dtraceenabled_libmemcached___memcached_increment_start(void); +extern void __dtrace_libmemcached___memcached_mget_end(void); +extern int __dtraceenabled_libmemcached___memcached_mget_end(void); +extern void __dtrace_libmemcached___memcached_mget_start(void); +extern int __dtraceenabled_libmemcached___memcached_mget_start(void); +extern void __dtrace_libmemcached___memcached_replace_end(void); +extern int __dtraceenabled_libmemcached___memcached_replace_end(void); +extern void __dtrace_libmemcached___memcached_replace_start(void); +extern int __dtraceenabled_libmemcached___memcached_replace_start(void); +extern void __dtrace_libmemcached___memcached_server_add_end(void); +extern int __dtraceenabled_libmemcached___memcached_server_add_end(void); +extern void __dtrace_libmemcached___memcached_server_add_start(void); +extern int __dtraceenabled_libmemcached___memcached_server_add_start(void); +extern void __dtrace_libmemcached___memcached_set_end(void); +extern int __dtraceenabled_libmemcached___memcached_set_end(void); +extern void __dtrace_libmemcached___memcached_set_start(void); +extern int __dtraceenabled_libmemcached___memcached_set_start(void); + +#else + +#define LIBMEMCACHED_MEMCACHED_ADD_END() +#define LIBMEMCACHED_MEMCACHED_ADD_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_ADD_START() +#define LIBMEMCACHED_MEMCACHED_ADD_START_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_CONNECT_END() +#define LIBMEMCACHED_MEMCACHED_CONNECT_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_CONNECT_START() +#define LIBMEMCACHED_MEMCACHED_CONNECT_START_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_DECREMENT_END() +#define LIBMEMCACHED_MEMCACHED_DECREMENT_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_DECREMENT_START() +#define LIBMEMCACHED_MEMCACHED_DECREMENT_START_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_DELETE_END() +#define LIBMEMCACHED_MEMCACHED_DELETE_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_DELETE_START() +#define LIBMEMCACHED_MEMCACHED_DELETE_START_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_FLUSH_END() +#define LIBMEMCACHED_MEMCACHED_FLUSH_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_FLUSH_START() +#define LIBMEMCACHED_MEMCACHED_FLUSH_START_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_GET_END() +#define LIBMEMCACHED_MEMCACHED_GET_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_GET_START() +#define LIBMEMCACHED_MEMCACHED_GET_START_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_INCREMENT_END() +#define LIBMEMCACHED_MEMCACHED_INCREMENT_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_INCREMENT_START() +#define LIBMEMCACHED_MEMCACHED_INCREMENT_START_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_MGET_END() +#define LIBMEMCACHED_MEMCACHED_MGET_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_MGET_START() +#define LIBMEMCACHED_MEMCACHED_MGET_START_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_REPLACE_END() +#define LIBMEMCACHED_MEMCACHED_REPLACE_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_REPLACE_START() +#define LIBMEMCACHED_MEMCACHED_REPLACE_START_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_END() +#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_START() +#define LIBMEMCACHED_MEMCACHED_SERVER_ADD_START_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_SET_END() +#define LIBMEMCACHED_MEMCACHED_SET_END_ENABLED() (0) +#define LIBMEMCACHED_MEMCACHED_SET_START() +#define LIBMEMCACHED_MEMCACHED_SET_START_ENABLED() (0) + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBMEMCACHED_PROBES_H */ diff --git a/libmemcached/md5.c b/libmemcached/md5.c new file mode 100644 index 00000000..61f8d692 --- /dev/null +++ b/libmemcached/md5.c @@ -0,0 +1,352 @@ +/* + This Library has been modified from its original form by + Brian Aker (brian@tangent.org) + + See below for original Copyright. +*/ +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +*/ + + +#include +#include + +/* POINTER defines a generic pointer type */ +typedef unsigned char *POINTER; + + +/* UINT4 defines a four byte word */ +typedef unsigned int UINT4; + + +/* MD5 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + +static void MD5Init (MD5_CTX *context); /* context */ +static void MD5Update ( MD5_CTX *context, /* context */ + unsigned char *input, /* input block */ + unsigned int inputLen); /* length of input block */ +static void MD5Final ( unsigned char digest[16], /* message digest */ + MD5_CTX *context); /* context */ + +/* Constants for MD5Transform routine. */ + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + +static void MD5Transform (UINT4 state[4], + unsigned char block[64]); +static void Encode (unsigned char *output, + UINT4 *input, + unsigned int len); +static void Decode(UINT4 *output, unsigned char *input, unsigned int len); + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + + +/* + Just a simple method for getting the signature + result must be == 16 +*/ +void md5_signature(unsigned char *key, unsigned int length, unsigned char *result) +{ + MD5_CTX my_md5; + + MD5Init(&my_md5); + (void)MD5Update(&my_md5, key, length); + MD5Final(result, &my_md5); +} + +/* MD5 initialization. Begins an MD5 operation, writing a new context. + */ +static void MD5Init (MD5_CTX *context) /* context */ +{ + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. +*/ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the + context. + */ + +static void MD5Update ( + MD5_CTX *context, /* context */ + unsigned char *input, /* input block */ + unsigned int inputLen) /* length of input block */ +{ + unsigned int i, idx, partLen; + + /* Compute number of bytes mod 64 */ + idx = (unsigned int)((context->count[0] >> 3) & 0x3F); + + + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3)) + < ((UINT4)inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - idx; + + /* Transform as many times as possible. +*/ + if (inputLen >= partLen) { + memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen); + MD5Transform(context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + idx = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i], + inputLen-i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. + */ + +static void MD5Final ( + unsigned char digest[16], /* message digest */ + MD5_CTX *context) /* context */ +{ + unsigned char bits[8]; + unsigned int idx, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. +*/ + idx = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (idx < 56) ? (56 - idx) : (120 - idx); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. +*/ + memset((POINTER)context, 0, sizeof (*context)); +} + +/* MD5 basic transformation. Transforms state based on block. + */ +static void MD5Transform ( + UINT4 state[4], + unsigned char block[64]) +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. +*/ + memset((POINTER)x, 0, sizeof (x)); +} + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is + a multiple of 4. + */ +static void Encode ( +unsigned char *output, +UINT4 *input, +unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is + a multiple of 4. + */ +static void Decode ( +UINT4 *output, +unsigned char *input, +unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); +} diff --git a/libmemcached/memcached.c b/libmemcached/memcached.c new file mode 100644 index 00000000..31c12ab3 --- /dev/null +++ b/libmemcached/memcached.c @@ -0,0 +1,106 @@ +/* + Memcached library +*/ +#include "common.h" + +memcached_st *memcached_create(memcached_st *ptr) +{ + memcached_result_st *result_ptr; + + if (ptr == NULL) + { + ptr= (memcached_st *)malloc(sizeof(memcached_st)); + + if (!ptr) + return NULL; /* MEMCACHED_MEMORY_ALLOCATION_FAILURE */ + + memset(ptr, 0, sizeof(memcached_st)); + ptr->is_allocated= MEMCACHED_ALLOCATED; + } + else + { + memset(ptr, 0, sizeof(memcached_st)); + } + result_ptr= memcached_result_create(ptr, &ptr->result); + WATCHPOINT_ASSERT(result_ptr); + ptr->poll_timeout= MEMCACHED_DEFAULT_TIMEOUT; + ptr->distribution= MEMCACHED_DISTRIBUTION_MODULA; + + return ptr; +} + +void memcached_free(memcached_st *ptr) +{ + /* If we have anything open, lets close it now */ + memcached_quit(ptr); + server_list_free(ptr, ptr->hosts); + memcached_result_free(&ptr->result); + + if (ptr->on_cleanup) + ptr->on_cleanup(ptr); + + if (ptr->is_allocated == MEMCACHED_ALLOCATED) + { + if (ptr->call_free) + ptr->call_free(ptr, ptr); + else + free(ptr); + } + else + ptr->is_allocated= MEMCACHED_USED; +} + +/* + clone is the destination, while ptr is the structure to clone. + If ptr is NULL the call is the same as if a memcached_create() was + called. +*/ +memcached_st *memcached_clone(memcached_st *clone, memcached_st *ptr) +{ + memcached_return rc= MEMCACHED_SUCCESS; + memcached_st *new_clone; + + if (ptr == NULL) + return memcached_create(clone); + + if (ptr->is_allocated == MEMCACHED_USED) + { + WATCHPOINT_ASSERT(0); + return NULL; + } + + new_clone= memcached_create(clone); + + if (new_clone == NULL) + return NULL; + + if (ptr->hosts) + rc= memcached_server_push(new_clone, ptr->hosts); + + if (rc != MEMCACHED_SUCCESS) + { + memcached_free(new_clone); + + return NULL; + } + + + new_clone->flags= ptr->flags; + new_clone->send_size= ptr->send_size; + new_clone->recv_size= ptr->recv_size; + new_clone->poll_timeout= ptr->poll_timeout; + new_clone->distribution= ptr->distribution; + new_clone->hash= ptr->hash; + new_clone->user_data= ptr->user_data; + + new_clone->on_clone= ptr->on_clone; + new_clone->on_cleanup= ptr->on_cleanup; + new_clone->call_free= ptr->call_free; + new_clone->call_malloc= ptr->call_malloc; + new_clone->call_realloc= ptr->call_realloc; + + if (ptr->on_clone) + ptr->on_clone(ptr, new_clone); + + return new_clone; +} diff --git a/libmemcached/memcached.h b/libmemcached/memcached.h new file mode 100644 index 00000000..3178866d --- /dev/null +++ b/libmemcached/memcached.h @@ -0,0 +1,473 @@ +/* + * Summary: interface for memcached server + * Description: main include file for libmemcached + * + * Copy: See Copyright for the status of this software. + * + * Author: Brian Aker + */ + +#ifndef __MEMCACHED_H__ +#define __MEMCACHED_H__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These are Private and should not be used by applications */ +#define MEMCACHED_VERSION_STRING_LENGTH 12 + +/* Public defines */ +#define MEMCACHED_DEFAULT_PORT 11211 +#define MEMCACHED_MAX_KEY 251 /* We add one to have it null terminated */ +#define MEMCACHED_MAX_BUFFER 8196 +#define MEMCACHED_MAX_HOST_LENGTH 64 +#define MEMCACHED_WHEEL_SIZE 1024 +#define MEMCACHED_STRIDE 4 +#define MEMCACHED_DEFAULT_TIMEOUT INT32_MAX + +/* string value */ +#define LIBMEMCACHED_VERSION_STRING "0.17" + +typedef enum { + MEMCACHED_SUCCESS, + MEMCACHED_FAILURE, + MEMCACHED_HOST_LOOKUP_FAILURE, + MEMCACHED_CONNECTION_FAILURE, + MEMCACHED_CONNECTION_BIND_FAILURE, + MEMCACHED_WRITE_FAILURE, + MEMCACHED_READ_FAILURE, + MEMCACHED_UNKNOWN_READ_FAILURE, + MEMCACHED_PROTOCOL_ERROR, + MEMCACHED_CLIENT_ERROR, + MEMCACHED_SERVER_ERROR, + MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE, + MEMCACHED_DATA_EXISTS, + MEMCACHED_DATA_DOES_NOT_EXIST, + MEMCACHED_NOTSTORED, + MEMCACHED_STORED, + MEMCACHED_NOTFOUND, + MEMCACHED_MEMORY_ALLOCATION_FAILURE, + MEMCACHED_PARTIAL_READ, + MEMCACHED_SOME_ERRORS, + MEMCACHED_NO_SERVERS, + MEMCACHED_END, + MEMCACHED_DELETED, + MEMCACHED_VALUE, + MEMCACHED_STAT, + MEMCACHED_ERRNO, + MEMCACHED_FAIL_UNIX_SOCKET, + MEMCACHED_NOT_SUPPORTED, + MEMCACHED_NO_KEY_PROVIDED, + MEMCACHED_FETCH_NOTFINISHED, + MEMCACHED_TIMEOUT, + MEMCACHED_BUFFERED, + MEMCACHED_BAD_KEY_PROVIDED, + MEMCACHED_MAXIMUM_RETURN, /* Always add new error code before */ +} memcached_return; + +typedef struct memcached_st memcached_st; +typedef struct memcached_stat_st memcached_stat_st; +typedef struct memcached_result_st memcached_result_st; +typedef struct memcached_string_st memcached_string_st; +typedef struct memcached_server_st memcached_server_st; +typedef memcached_return (*memcached_clone_func)(memcached_st *parent, memcached_st *clone); +typedef memcached_return (*memcached_cleanup_func)(memcached_st *ptr); +typedef void (*memcached_free_function)(memcached_st *ptr, void *mem); +typedef void *(*memcached_malloc_function)(memcached_st *ptr, const size_t size); +typedef void *(*memcached_realloc_function)(memcached_st *ptr, void *mem, const size_t size); +typedef memcached_return (*memcached_execute_function)(memcached_st *ptr, memcached_result_st *result, void *context); +typedef memcached_return (*memcached_server_function)(memcached_st *ptr, memcached_server_st *server, void *context); + +typedef enum { + MEMCACHED_DISTRIBUTION_MODULA, + MEMCACHED_DISTRIBUTION_CONSISTENT, +} memcached_server_distribution; + +typedef enum { + MEMCACHED_BEHAVIOR_NO_BLOCK, + MEMCACHED_BEHAVIOR_TCP_NODELAY, + MEMCACHED_BEHAVIOR_HASH, + MEMCACHED_BEHAVIOR_KETAMA, + MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, + MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, + MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, + MEMCACHED_BEHAVIOR_SUPPORT_CAS, + MEMCACHED_BEHAVIOR_POLL_TIMEOUT, + MEMCACHED_BEHAVIOR_DISTRIBUTION, + MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, + MEMCACHED_BEHAVIOR_USER_DATA, + MEMCACHED_BEHAVIOR_SORT_HOSTS, + MEMCACHED_BEHAVIOR_VERIFY_KEY, + MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, + MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, +} memcached_behavior; + +typedef enum { + MEMCACHED_CALLBACK_USER_DATA, + MEMCACHED_CALLBACK_CLEANUP_FUNCTION, + MEMCACHED_CALLBACK_CLONE_FUNCTION, + MEMCACHED_CALLBACK_MALLOC_FUNCTION, + MEMCACHED_CALLBACK_REALLOC_FUNCTION, + MEMCACHED_CALLBACK_FREE_FUNCTION, +} memcached_callback; + +typedef enum { + MEMCACHED_HASH_DEFAULT= 0, + MEMCACHED_HASH_MD5, + MEMCACHED_HASH_CRC, + MEMCACHED_HASH_FNV1_64, + MEMCACHED_HASH_FNV1A_64, + MEMCACHED_HASH_FNV1_32, + MEMCACHED_HASH_FNV1A_32, + MEMCACHED_HASH_KETAMA, + MEMCACHED_HASH_HSIEH, + MEMCACHED_HASH_MURMUR, +} memcached_hash; + +typedef enum { + MEMCACHED_CONNECTION_UNKNOWN, + MEMCACHED_CONNECTION_TCP, + MEMCACHED_CONNECTION_UDP, + MEMCACHED_CONNECTION_UNIX_SOCKET, +} memcached_connection; + +typedef enum { + MEMCACHED_NOT_ALLOCATED, + MEMCACHED_ALLOCATED, + MEMCACHED_USED, +} memcached_allocated; + +struct memcached_server_st { + char hostname[MEMCACHED_MAX_HOST_LENGTH]; + unsigned int port; + int fd; + int cached_errno; + unsigned int cursor_active; + char write_buffer[MEMCACHED_MAX_BUFFER]; + size_t write_buffer_offset; + char read_buffer[MEMCACHED_MAX_BUFFER]; + size_t read_data_length; + size_t read_buffer_length; + char *read_ptr; + memcached_allocated sockaddr_inited; + struct addrinfo *address_info; + memcached_connection type; + uint8_t major_version; + uint8_t minor_version; + uint8_t micro_version; + uint16_t count; + time_t next_retry; + memcached_st *root; +}; + +struct memcached_stat_st { + uint32_t pid; + uint32_t uptime; + uint32_t threads; + uint32_t time; + uint32_t pointer_size; + uint32_t rusage_user_seconds; + uint32_t rusage_user_microseconds; + uint32_t rusage_system_seconds; + uint32_t rusage_system_microseconds; + uint32_t curr_items; + uint32_t total_items; + uint64_t limit_maxbytes; + uint32_t curr_connections; + uint32_t total_connections; + uint32_t connection_structures; + uint64_t bytes; + uint64_t cmd_get; + uint64_t cmd_set; + uint64_t get_hits; + uint64_t get_misses; + uint64_t evictions; + uint64_t bytes_read; + uint64_t bytes_written; + char version[MEMCACHED_VERSION_STRING_LENGTH]; +}; + +struct memcached_string_st { + memcached_st *root; + memcached_allocated is_allocated; + char *string; + char *end; + size_t current_size; + size_t block_size; +}; + +struct memcached_result_st { + memcached_allocated is_allocated; + memcached_st *root; + char key[MEMCACHED_MAX_KEY]; + size_t key_length; + memcached_string_st value; + uint32_t flags; + uint64_t cas; + /* Add result callback function */ +}; + +struct memcached_st { + memcached_allocated is_allocated; + memcached_server_st *hosts; + unsigned int number_of_hosts; + unsigned int cursor_server; + int cached_errno; + uint32_t flags; + int send_size; + int recv_size; + int32_t poll_timeout; + int32_t connect_timeout; + int32_t retry_timeout; + memcached_result_st result; + memcached_hash hash; + memcached_server_distribution distribution; + void *user_data; + unsigned int wheel[MEMCACHED_WHEEL_SIZE]; + memcached_clone_func on_clone; + memcached_cleanup_func on_cleanup; + memcached_free_function call_free; + memcached_malloc_function call_malloc; + memcached_realloc_function call_realloc; +#ifdef NOT_USED /* Future Use */ + uint8_t replicas; + memcached_return warning; +#endif +}; + +/* Public API */ +const char * memcached_lib_version(void); + +memcached_st *memcached_create(memcached_st *ptr); +void memcached_free(memcached_st *ptr); +memcached_st *memcached_clone(memcached_st *clone, memcached_st *ptr); + +memcached_return memcached_delete(memcached_st *ptr, char *key, size_t key_length, + time_t expiration); +memcached_return memcached_increment(memcached_st *ptr, + char *key, size_t key_length, + uint32_t offset, + uint64_t *value); +memcached_return memcached_decrement(memcached_st *ptr, + char *key, size_t key_length, + uint32_t offset, + uint64_t *value); +void memcached_stat_free(memcached_st *, memcached_stat_st *); +memcached_stat_st *memcached_stat(memcached_st *ptr, char *args, memcached_return *error); +memcached_return memcached_stat_servername(memcached_stat_st *stat, char *args, + char *hostname, unsigned int port); +memcached_return memcached_flush(memcached_st *ptr, time_t expiration); +memcached_return memcached_verbosity(memcached_st *ptr, unsigned int verbosity); +void memcached_quit(memcached_st *ptr); +char *memcached_strerror(memcached_st *ptr, memcached_return rc); +memcached_return memcached_behavior_set(memcached_st *ptr, memcached_behavior flag, void *data); +uint64_t memcached_behavior_get(memcached_st *ptr, memcached_behavior flag); + +/* All of the functions for adding data to the server */ +memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags); +memcached_return memcached_add(memcached_st *ptr, char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags); +memcached_return memcached_replace(memcached_st *ptr, char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags); +memcached_return memcached_append(memcached_st *ptr, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags); +memcached_return memcached_prepend(memcached_st *ptr, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags); +memcached_return memcached_cas(memcached_st *ptr, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags, + uint64_t cas); + +/* Get functions */ +char *memcached_get(memcached_st *ptr, char *key, size_t key_length, + size_t *value_length, + uint32_t *flags, + memcached_return *error); +memcached_return memcached_mget(memcached_st *ptr, + char **keys, size_t *key_length, + unsigned int number_of_keys); +char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, + size_t *value_length, uint32_t *flags, + memcached_return *error); +memcached_result_st *memcached_fetch_result(memcached_st *ptr, + memcached_result_st *result, + memcached_return *error); + +/* Server Public functions */ +#define memcached_server_count(A) (A)->number_of_hosts +#define memcached_server_name(A,B) (B).hostname +#define memcached_server_port(A,B) (B).port +#define memcached_server_list(A) (A)->hosts +#define memcached_server_response_count(A) (A)->cursor_active + + +memcached_return memcached_server_add_udp(memcached_st *ptr, + char *hostname, + unsigned int port); +memcached_return memcached_server_add_unix_socket(memcached_st *ptr, + char *filename); +memcached_return memcached_server_add(memcached_st *ptr, char *hostname, + unsigned int port); +void memcached_server_list_free(memcached_server_st *ptr); +memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list); + +memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, + char *hostname, unsigned int port, + memcached_return *error); +unsigned int memcached_server_list_count(memcached_server_st *ptr); +memcached_server_st *memcached_servers_parse(char *server_strings); + +char *memcached_stat_get_value(memcached_st *ptr, memcached_stat_st *stat, + char *key, memcached_return *error); +char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *stat, + memcached_return *error); + +char *memcached_get_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + size_t *value_length, + uint32_t *flags, + memcached_return *error); + +memcached_return memcached_mget_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char **keys, size_t *key_length, + unsigned int number_of_keys); + +memcached_return memcached_set_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags); + +memcached_return memcached_add_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags); + +memcached_return memcached_replace_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags); + +memcached_return memcached_prepend_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags); + +memcached_return memcached_append_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags); + +memcached_return memcached_cas_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags, + uint64_t cas); +memcached_return memcached_delete_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + time_t expiration); + +memcached_return memcached_fetch_execute(memcached_st *ptr, + unsigned int (*callback[])(memcached_st *ptr, memcached_result_st *result, void *context), + void *context, + unsigned int number_of_callbacks + ); + +memcached_return memcached_callback_set(memcached_st *ptr, + memcached_callback flag, + void *data); +void *memcached_callback_get(memcached_st *ptr, + memcached_callback flag, + memcached_return *error); + +memcached_return memcached_server_cursor(memcached_st *ptr, + memcached_server_function *callback, + void *context, + unsigned int number_of_callbacks); + +/* Result Struct */ +void memcached_result_free(memcached_result_st *result); +memcached_result_st *memcached_result_create(memcached_st *ptr, + memcached_result_st *result); +#define memcached_result_key_value(A) (A)->key +#define memcached_result_key_length(A) (A)->key_length +#ifdef FIX +#define memcached_result_value(A) memcached_string_value((A)->value) +#define memcached_result_length(A) memcached_string_length((A)->value) +#else +char *memcached_result_value(memcached_result_st *ptr); +size_t memcached_result_length(memcached_result_st *ptr); +#endif +#define memcached_result_flags(A) (A)->flags +#define memcached_result_cas(A) (A)->cas + + +#ifndef __WATCHPOINT_H__ +#define __WATCHPOINT_H__ +/* Some personal debugging functions */ +#ifdef HAVE_DEBUG +#define WATCHPOINT fprintf(stderr, "\nWATCHPOINT %s:%d (%s)\n", __FILE__, __LINE__,__func__);fflush(stdout); +#ifdef __MEMCACHED_H__ +#define WATCHPOINT_ERROR(A) fprintf(stderr, "\nWATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout); +#define WATCHPOINT_IFERROR(A) if(A != MEMCACHED_SUCCESS)fprintf(stderr, "\nWATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout); +#endif +#define WATCHPOINT_STRING(A) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s\n", __FILE__, __LINE__,__func__,A);fflush(stdout); +#define WATCHPOINT_STRING_LENGTH(A,B) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %.*s\n", __FILE__, __LINE__,__func__,(int)B,A);fflush(stdout); +#define WATCHPOINT_NUMBER(A) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %zu\n", __FILE__, __LINE__,__func__,(size_t)(A));fflush(stdout); +#define WATCHPOINT_ERRNO(A) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s\n", __FILE__, __LINE__,__func__, strerror(A));fflush(stdout); +#define WATCHPOINT_ASSERT(A) assert((A)); +#else +#define WATCHPOINT +#ifdef __MEMCACHED_H__ +#define WATCHPOINT_ERROR(A) +#define WATCHPOINT_IFERROR(A) +#endif +#define WATCHPOINT_STRING(A) +#define WATCHPOINT_NUMBER(A) +#define WATCHPOINT_ERRNO(A) +#define WATCHPOINT_ASSERT(A) +#endif + +#endif /* __WATCHPOINT_H__ */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __MEMCACHED_H__ */ diff --git a/libmemcached/memcached.hh b/libmemcached/memcached.hh new file mode 100644 index 00000000..e482f4bf --- /dev/null +++ b/libmemcached/memcached.hh @@ -0,0 +1,102 @@ +#ifdef USE_PRAGMA_INTERFACE +#pragma interface /* gcc class implementation */ +#endif + +#include +#include +#include + +class Memcached +{ + memcached_st memc; + +public: + + Memcached() + { + memcached_create(&memc); + } + + Memcached(memcached_st *clone) + { + WATCHPOINT; + memcached_clone(&memc, clone); + WATCHPOINT; + } + + char *get(char *key, size_t *value_length) + { + uint32_t flags; + memcached_return rc; + + return memcached_get(&memc, key, strlen(key), + value_length, &flags, &rc); + } + + char *get_by_key(char *master_key, char *key, size_t *value_length) + { + uint32_t flags; + memcached_return rc; + + return memcached_get_by_key(&memc, master_key, strlen(master_key), key, strlen(key), + value_length, &flags, &rc); + } + + memcached_return mget(char **keys, size_t *key_length, unsigned int number_of_keys) + { + + return memcached_mget(&memc, keys, key_length, number_of_keys); + } + + memcached_return set(char *key, char *value, size_t value_length) + { + return memcached_set(&memc, key, strlen(key), + value, value_length, + (time_t)0, (uint32_t)0); + } + + memcached_return set_by_key(char *master_key, char *key, char *value, size_t value_length) + { + return memcached_set_by_key(&memc, master_key, strlen(master_key), + key, strlen(key), + value, value_length, + (time_t)0, + (uint32_t)0 ); + } + + + memcached_return add(char *key, char *value, size_t value_length) + { + return memcached_add(&memc, key, strlen(key), + value, value_length, + (time_t)0, (uint32_t)0); + } + + memcached_return replace(char *key, char *value, size_t value_length) + { + return memcached_replace(&memc, key, strlen(key), + value, value_length, + (time_t)0, (uint32_t)0); + } + + memcached_return prepend(char *key, char *value, size_t value_length) + { + return memcached_prepend(&memc, key, strlen(key), + value, value_length, + (time_t)0, + (uint32_t)0); + } + + + memcached_return append(char *key, char *value, size_t value_length) + { + return memcached_append(&memc, key, strlen(key), + value, value_length, + (time_t)0, + (uint32_t)0); + } + ~Memcached() + { + memcached_free(&memc); + } +}; diff --git a/libmemcached/memcached_auto.c b/libmemcached/memcached_auto.c new file mode 100644 index 00000000..a607ed66 --- /dev/null +++ b/libmemcached/memcached_auto.c @@ -0,0 +1,90 @@ +#include "common.h" + +static memcached_return memcached_auto(memcached_st *ptr, + char *verb, + char *key, size_t key_length, + unsigned int offset, + uint64_t *value) +{ + size_t send_length; + memcached_return rc; + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + unsigned int server_key; + + unlikely (key_length == 0) + return MEMCACHED_NO_KEY_PROVIDED; + + unlikely (ptr->hosts == NULL || ptr->number_of_hosts == 0) + return MEMCACHED_NO_SERVERS; + + if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED)) + return MEMCACHED_BAD_KEY_PROVIDED; + + server_key= memcached_generate_hash(ptr, key, key_length); + + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "%s %.*s %u\r\n", verb, + (int)key_length, key, + offset); + unlikely (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + return MEMCACHED_WRITE_FAILURE; + + rc= memcached_do(&ptr->hosts[server_key], buffer, send_length, 1); + if (rc != MEMCACHED_SUCCESS) + return rc; + + rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); + + /* + So why recheck responce? Because the protocol is brain dead :) + The number returned might end up equaling one of the string + values. Less chance of a mistake with strncmp() so we will + use it. We still called memcached_response() though since it + worked its magic for non-blocking IO. + */ + if (!strncmp(buffer, "ERROR\r\n", 7)) + { + *value= 0; + rc= MEMCACHED_PROTOCOL_ERROR; + } + else if (!strncmp(buffer, "NOT_FOUND\r\n", 11)) + { + *value= 0; + rc= MEMCACHED_NOTFOUND; + } + else + { + *value= (uint64_t)strtoll(buffer, (char **)NULL, 10); + rc= MEMCACHED_SUCCESS; + } + + return rc; +} + +memcached_return memcached_increment(memcached_st *ptr, + char *key, size_t key_length, + uint32_t offset, + uint64_t *value) +{ + memcached_return rc; + + LIBMEMCACHED_MEMCACHED_INCREMENT_START(); + rc= memcached_auto(ptr, "incr", key, key_length, offset, value); + LIBMEMCACHED_MEMCACHED_INCREMENT_END(); + + return rc; +} + +memcached_return memcached_decrement(memcached_st *ptr, + char *key, size_t key_length, + uint32_t offset, + uint64_t *value) +{ + memcached_return rc; + + LIBMEMCACHED_MEMCACHED_DECREMENT_START(); + rc= memcached_auto(ptr, "decr", key, key_length, offset, value); + LIBMEMCACHED_MEMCACHED_DECREMENT_END(); + + return rc; +} diff --git a/libmemcached/memcached_behavior.c b/libmemcached/memcached_behavior.c new file mode 100644 index 00000000..ce598fc0 --- /dev/null +++ b/libmemcached/memcached_behavior.c @@ -0,0 +1,197 @@ +#include "common.h" +#include +#include +#include + +/* + This function is used to modify the behabior of running client. + + We quit all connections so we can reset the sockets. +*/ + +void set_behavior_flag(memcached_st *ptr, memcached_flags temp_flag, void *data) +{ + uint8_t truefalse; + + if (data) + truefalse= *(unsigned int *)data; + else + truefalse= 0; + + if (truefalse) + ptr->flags|= temp_flag; + else + ptr->flags+= temp_flag; +} + +memcached_return memcached_behavior_set(memcached_st *ptr, + memcached_behavior flag, + void *data) +{ + switch (flag) + { + case MEMCACHED_BEHAVIOR_SUPPORT_CAS: + set_behavior_flag(ptr, MEM_SUPPORT_CAS, data); + break; + case MEMCACHED_BEHAVIOR_NO_BLOCK: + set_behavior_flag(ptr, MEM_NO_BLOCK, data); + memcached_quit(ptr); + case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS: + set_behavior_flag(ptr, MEM_BUFFER_REQUESTS, data); + memcached_quit(ptr); + break; + case MEMCACHED_BEHAVIOR_TCP_NODELAY: + set_behavior_flag(ptr, MEM_TCP_NODELAY, data); + memcached_quit(ptr); + break; + case MEMCACHED_BEHAVIOR_DISTRIBUTION: + ptr->distribution= *(memcached_server_distribution *)(data); + break; + case MEMCACHED_BEHAVIOR_HASH: + ptr->hash= *(memcached_hash *)(data); + break; + case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS: + set_behavior_flag(ptr, MEM_USE_CACHE_LOOKUPS, data); + memcached_quit(ptr); + break; + case MEMCACHED_BEHAVIOR_VERIFY_KEY: + set_behavior_flag(ptr, MEM_VERIFY_KEY, data); + break; + case MEMCACHED_BEHAVIOR_KETAMA: + set_behavior_flag(ptr, MEM_USE_KETAMA, data); + break; + case MEMCACHED_BEHAVIOR_SORT_HOSTS: + set_behavior_flag(ptr, MEM_USE_SORT_HOSTS, data); + break; + case MEMCACHED_BEHAVIOR_USER_DATA: + ptr->user_data= data; + break; + case MEMCACHED_BEHAVIOR_POLL_TIMEOUT: + { + int32_t timeout= (*((int32_t *)data)); + + ptr->poll_timeout= timeout; + break; + } + case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT: + { + int32_t timeout= (*((int32_t *)data)); + + ptr->connect_timeout= timeout; + break; + } + case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT: + { + ptr->retry_timeout= (int32_t)data; + break; + } + case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE: + { + ptr->send_size= (*((int *)data)); + memcached_quit(ptr); + break; + } + case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE: + { + ptr->recv_size= (*((int *)data)); + memcached_quit(ptr); + break; + } + + + } + + return MEMCACHED_SUCCESS; +} + +unsigned long long memcached_behavior_get(memcached_st *ptr, + memcached_behavior flag) +{ + memcached_flags temp_flag= 0; + + switch (flag) + { + case MEMCACHED_BEHAVIOR_SUPPORT_CAS: + temp_flag= MEM_SUPPORT_CAS; + break; + case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS: + temp_flag= MEM_USE_CACHE_LOOKUPS; + break; + case MEMCACHED_BEHAVIOR_NO_BLOCK: + temp_flag= MEM_NO_BLOCK; + break; + case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS: + temp_flag= MEM_BUFFER_REQUESTS; + break; + case MEMCACHED_BEHAVIOR_TCP_NODELAY: + temp_flag= MEM_TCP_NODELAY; + break; + case MEMCACHED_BEHAVIOR_VERIFY_KEY: + temp_flag= MEM_VERIFY_KEY; + break; + case MEMCACHED_BEHAVIOR_DISTRIBUTION: + return ptr->distribution; + case MEMCACHED_BEHAVIOR_HASH: + return ptr->hash; + case MEMCACHED_BEHAVIOR_KETAMA: + temp_flag= MEM_USE_KETAMA; + break; + case MEMCACHED_BEHAVIOR_SORT_HOSTS: + temp_flag= MEM_USE_SORT_HOSTS; + break; + case MEMCACHED_BEHAVIOR_USER_DATA: + return 0; + case MEMCACHED_BEHAVIOR_POLL_TIMEOUT: + { + return (unsigned long long)ptr->poll_timeout; + } + case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT: + { + return (unsigned long long)ptr->connect_timeout; + } + case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT: + { + return (unsigned long long)ptr->retry_timeout; + } + case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE: + { + int sock_size; + socklen_t sock_length= sizeof(int); + + /* REFACTOR */ + /* We just try the first host, and if it is down we return zero */ + if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS) + return 0; + + if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET, + SO_SNDBUF, &sock_size, &sock_length)) + return 0; /* Zero means error */ + + return sock_size; + } + case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE: + { + int sock_size; + socklen_t sock_length= sizeof(int); + + /* REFACTOR */ + /* We just try the first host, and if it is down we return zero */ + if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS) + return 0; + + if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET, + SO_RCVBUF, &sock_size, &sock_length)) + return 0; /* Zero means error */ + + return sock_size; + } + } + + WATCHPOINT_ASSERT(temp_flag); /* Programming mistake if it gets this far */ + if (ptr->flags & temp_flag) + return 1; + else + return 0; + + return MEMCACHED_SUCCESS; +} diff --git a/libmemcached/memcached_callback.c b/libmemcached/memcached_callback.c new file mode 100644 index 00000000..95d6a384 --- /dev/null +++ b/libmemcached/memcached_callback.c @@ -0,0 +1,103 @@ +#include "common.h" +#include +#include +#include + +/* + These functions provide data and function callback support +*/ + +memcached_return memcached_callback_set(memcached_st *ptr, + memcached_callback flag, + void *data) +{ + switch (flag) + { + case MEMCACHED_CALLBACK_USER_DATA: + { + ptr->user_data= data; + break; + } + case MEMCACHED_CALLBACK_CLEANUP_FUNCTION: + { + memcached_cleanup_func func= (memcached_cleanup_func)data; + ptr->on_cleanup= func; + break; + } + case MEMCACHED_CALLBACK_CLONE_FUNCTION: + { + memcached_clone_func func= (memcached_clone_func)data; + ptr->on_clone= func; + break; + } + case MEMCACHED_CALLBACK_MALLOC_FUNCTION: + { + memcached_malloc_function func= (memcached_malloc_function)data; + ptr->call_malloc= func; + break; + } + case MEMCACHED_CALLBACK_REALLOC_FUNCTION: + { + memcached_realloc_function func= (memcached_realloc_function)data; + ptr->call_realloc= func; + break; + } + case MEMCACHED_CALLBACK_FREE_FUNCTION: + { + memcached_free_function func= (memcached_free_function)data; + ptr->call_free= func; + break; + } + default: + return MEMCACHED_FAILURE; + } + + return MEMCACHED_SUCCESS; +} + +void *memcached_callback_get(memcached_st *ptr, + memcached_callback flag, + memcached_return *error) +{ + memcached_return local_error; + if (!error) + error = &local_error; + + switch (flag) + { + case MEMCACHED_CALLBACK_USER_DATA: + { + *error= ptr->user_data ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; + return (void *)ptr->user_data; + } + case MEMCACHED_CALLBACK_CLEANUP_FUNCTION: + { + *error= ptr->on_cleanup ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; + return (void *)ptr->on_cleanup; + } + case MEMCACHED_CALLBACK_CLONE_FUNCTION: + { + *error= ptr->on_clone ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; + return (void *)ptr->on_clone; + } + case MEMCACHED_CALLBACK_MALLOC_FUNCTION: + { + *error= ptr->call_malloc ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; + return (void *)ptr->call_malloc; + } + case MEMCACHED_CALLBACK_REALLOC_FUNCTION: + { + *error= ptr->call_realloc ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; + return (void *)ptr->call_realloc; + } + case MEMCACHED_CALLBACK_FREE_FUNCTION: + { + *error= ptr->call_free ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; + return (void *)ptr->call_free; + } + default: + WATCHPOINT_ASSERT(0); + *error= MEMCACHED_FAILURE; + return NULL; + } +} diff --git a/libmemcached/memcached_connect.c b/libmemcached/memcached_connect.c new file mode 100644 index 00000000..ab4b84f0 --- /dev/null +++ b/libmemcached/memcached_connect.c @@ -0,0 +1,292 @@ +#include "common.h" +#include + +static memcached_return set_hostinfo(memcached_server_st *server) +{ + struct addrinfo *ai; + struct addrinfo hints; + int e; + char str_port[NI_MAXSERV]; + + sprintf(str_port, "%u", server->port); + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family= AF_INET; + if (server->type == MEMCACHED_CONNECTION_UDP) + { + hints.ai_protocol= IPPROTO_UDP; + hints.ai_socktype= SOCK_DGRAM; + } + else + { + hints.ai_socktype= SOCK_STREAM; + hints.ai_protocol= IPPROTO_TCP; + } + + e= getaddrinfo(server->hostname, str_port, &hints, &ai); + if (e != 0) + { + WATCHPOINT_STRING(server->hostname); + WATCHPOINT_STRING(gai_strerror(e)); + return MEMCACHED_HOST_LOOKUP_FAILURE; + } + + if (server->address_info) + freeaddrinfo(server->address_info); + server->address_info= ai; + + return MEMCACHED_SUCCESS; +} + +static memcached_return set_socket_options(memcached_server_st *ptr) +{ + if (ptr->type == MEMCACHED_CONNECTION_UDP) + return MEMCACHED_SUCCESS; + + if (ptr->root->flags & MEM_NO_BLOCK) + { + int error; + struct linger linger; + struct timeval waittime; + + waittime.tv_sec= 10; + waittime.tv_usec= 0; + + linger.l_onoff= 1; + linger.l_linger= MEMCACHED_DEFAULT_TIMEOUT; + error= setsockopt(ptr->fd, SOL_SOCKET, SO_LINGER, + &linger, (socklen_t)sizeof(struct linger)); + WATCHPOINT_ASSERT(error == 0); + + error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDTIMEO, + &waittime, (socklen_t)sizeof(struct timeval)); + WATCHPOINT_ASSERT(error == 0); + + error= setsockopt(ptr->fd, SOL_SOCKET, SO_RCVTIMEO, + &waittime, (socklen_t)sizeof(struct timeval)); + WATCHPOINT_ASSERT(error == 0); + } + + if (ptr->root->flags & MEM_TCP_NODELAY) + { + int flag= 1; + int error; + + error= setsockopt(ptr->fd, IPPROTO_TCP, TCP_NODELAY, + &flag, (socklen_t)sizeof(int)); + WATCHPOINT_ASSERT(error == 0); + } + + if (ptr->root->send_size) + { + int error; + + error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDBUF, + &ptr->root->send_size, (socklen_t)sizeof(int)); + WATCHPOINT_ASSERT(error == 0); + } + + if (ptr->root->recv_size) + { + int error; + + error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDBUF, + &ptr->root->recv_size, (socklen_t)sizeof(int)); + WATCHPOINT_ASSERT(error == 0); + } + + /* For the moment, not getting a nonblocking mode will not be fatal */ + if (ptr->root->flags & MEM_NO_BLOCK) + { + int flags; + + flags= fcntl(ptr->fd, F_GETFL, 0); + unlikely (flags != -1) + { + (void)fcntl(ptr->fd, F_SETFL, flags | O_NONBLOCK); + } + } + + return MEMCACHED_SUCCESS; +} + +static memcached_return unix_socket_connect(memcached_server_st *ptr) +{ + struct sockaddr_un servAddr; + socklen_t addrlen; + + if (ptr->fd == -1) + { + if ((ptr->fd= socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + ptr->cached_errno= errno; + return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE; + } + + memset(&servAddr, 0, sizeof (struct sockaddr_un)); + servAddr.sun_family= AF_UNIX; + strcpy(servAddr.sun_path, ptr->hostname); /* Copy filename */ + + addrlen= strlen(servAddr.sun_path) + sizeof(servAddr.sun_family); + +test_connect: + if (connect(ptr->fd, + (struct sockaddr *)&servAddr, + sizeof(servAddr)) < 0) + { + switch (errno) { + case EINPROGRESS: + case EALREADY: + case EINTR: + goto test_connect; + case EISCONN: /* We were spinning waiting on connect */ + break; + default: + WATCHPOINT_ERRNO(errno); + ptr->cached_errno= errno; + return MEMCACHED_ERRNO; + } + } + } + return MEMCACHED_SUCCESS; +} + +static memcached_return network_connect(memcached_server_st *ptr) +{ + if (ptr->fd == -1) + { + struct addrinfo *use; + + /* Old connection junk still is in the structure */ + WATCHPOINT_ASSERT(ptr->cursor_active == 0); + + if (ptr->sockaddr_inited == MEMCACHED_NOT_ALLOCATED || + (!(ptr->root->flags & MEM_USE_CACHE_LOOKUPS))) + { + memcached_return rc; + + rc= set_hostinfo(ptr); + if (rc != MEMCACHED_SUCCESS) + return rc; + ptr->sockaddr_inited= MEMCACHED_ALLOCATED; + } + + use= ptr->address_info; + /* Create the socket */ + while (use != NULL) + { + if ((ptr->fd= socket(use->ai_family, + use->ai_socktype, + use->ai_protocol)) < 0) + { + ptr->cached_errno= errno; + WATCHPOINT_ERRNO(errno); + return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE; + } + + (void)set_socket_options(ptr); + + /* connect to server */ +test_connect: + if (connect(ptr->fd, + use->ai_addr, + use->ai_addrlen) < 0) + { + switch (errno) { + /* We are spinning waiting on connect */ + case EALREADY: + case EINPROGRESS: + { + struct pollfd fds[1]; + int error; + + memset(&fds, 0, sizeof(struct pollfd)); + fds[0].fd= ptr->fd; + fds[0].events= POLLOUT | POLLERR; + error= poll(fds, 1, ptr->root->connect_timeout); + + if (error != 1) + { + ptr->cached_errno= errno; + WATCHPOINT_ERRNO(ptr->cached_errno); + close(ptr->fd); + ptr->fd= -1; + return MEMCACHED_ERRNO; + } + + break; + } + /* We are spinning waiting on connect */ + case EINTR: + goto test_connect; + case EISCONN: /* We were spinning waiting on connect */ + break; + default: + ptr->cached_errno= errno; + WATCHPOINT_ERRNO(ptr->cached_errno); + close(ptr->fd); + ptr->fd= -1; + if (ptr->root->retry_timeout) + { + struct timeval next_time; + + gettimeofday(&next_time, NULL); + ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout; + } + } + } + else + { + WATCHPOINT_ASSERT(ptr->cursor_active == 0); + return MEMCACHED_SUCCESS; + } + use = use->ai_next; + } + } + + if (ptr->fd == -1) + return MEMCACHED_ERRNO; /* The last error should be from connect() */ + + return MEMCACHED_SUCCESS; /* The last error should be from connect() */ +} + + +memcached_return memcached_connect(memcached_server_st *ptr) +{ + memcached_return rc= MEMCACHED_NO_SERVERS; + LIBMEMCACHED_MEMCACHED_CONNECT_START(); + + if (ptr->root->retry_timeout) + { + struct timeval next_time; + + gettimeofday(&next_time, NULL); + if (next_time.tv_sec < ptr->next_retry) + return MEMCACHED_TIMEOUT; + } + /* 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); + break; + case MEMCACHED_CONNECTION_UNIX_SOCKET: + rc= unix_socket_connect(ptr); + break; + default: + WATCHPOINT_ASSERT(0); + } + + if (rc != MEMCACHED_SUCCESS) + WATCHPOINT_ERROR(rc); + + LIBMEMCACHED_MEMCACHED_CONNECT_END(); + + return rc; +} diff --git a/libmemcached/memcached_delete.c b/libmemcached/memcached_delete.c new file mode 100644 index 00000000..60e3bed4 --- /dev/null +++ b/libmemcached/memcached_delete.c @@ -0,0 +1,65 @@ +#include "common.h" + +memcached_return memcached_delete(memcached_st *ptr, char *key, size_t key_length, + time_t expiration) +{ + return memcached_delete_by_key(ptr, key, key_length, + key, key_length, expiration); +} + +memcached_return memcached_delete_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + time_t expiration) +{ + char to_write; + size_t send_length; + memcached_return rc; + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + unsigned int server_key; + + LIBMEMCACHED_MEMCACHED_DELETE_START(); + + unlikely (key_length == 0) + return MEMCACHED_NO_KEY_PROVIDED; + + unlikely (ptr->hosts == NULL || ptr->number_of_hosts == 0) + return MEMCACHED_NO_SERVERS; + + server_key= memcached_generate_hash(ptr, master_key, master_key_length); + + if (expiration) + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "delete %.*s %llu\r\n", (int)key_length, key, + (unsigned long long)expiration); + else + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "delete %.*s\r\n", (int)key_length, key); + + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + { + rc= MEMCACHED_WRITE_FAILURE; + goto error; + } + + to_write= (ptr->flags & MEM_BUFFER_REQUESTS) ? 0 : 1; + + rc= memcached_do(&ptr->hosts[server_key], buffer, send_length, to_write); + if (rc != MEMCACHED_SUCCESS) + goto error; + + if ((ptr->flags & MEM_BUFFER_REQUESTS)) + { + rc= MEMCACHED_BUFFERED; + } + else + { + rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); + if (rc == MEMCACHED_DELETED) + rc= MEMCACHED_SUCCESS; + } + +error: + LIBMEMCACHED_MEMCACHED_DELETE_END(); + return rc; +} diff --git a/libmemcached/memcached_do.c b/libmemcached/memcached_do.c new file mode 100644 index 00000000..c4bf574f --- /dev/null +++ b/libmemcached/memcached_do.c @@ -0,0 +1,23 @@ +#include "common.h" + +memcached_return memcached_do(memcached_server_st *ptr, char *command, + size_t command_length, uint8_t with_flush) +{ + memcached_return rc; + ssize_t sent_length; + + WATCHPOINT_ASSERT(command_length); + WATCHPOINT_ASSERT(command); + + if ((rc= memcached_connect(ptr)) != MEMCACHED_SUCCESS) + return rc; + + sent_length= memcached_io_write(ptr, command, command_length, with_flush); + + if (sent_length == -1 || sent_length != command_length) + rc= MEMCACHED_WRITE_FAILURE; + else + memcached_server_response_increment(ptr); + + return rc; +} diff --git a/libmemcached/memcached_fetch.c b/libmemcached/memcached_fetch.c new file mode 100644 index 00000000..37cec5d3 --- /dev/null +++ b/libmemcached/memcached_fetch.c @@ -0,0 +1,225 @@ +#include "common.h" +#include "memcached_io.h" + +memcached_return value_fetch(memcached_server_st *ptr, + char *buffer, + memcached_result_st *result) +{ + memcached_return rc= MEMCACHED_SUCCESS; + char *string_ptr; + char *end_ptr; + char *next_ptr; + size_t value_length; + size_t read_length; + size_t to_read; + char *value_ptr; + + end_ptr= buffer + MEMCACHED_DEFAULT_COMMAND_SIZE; + + result->key_length= 0; + result->flags= 0; + memcached_string_reset(&result->value); + + string_ptr= buffer; + string_ptr+= 6; /* "VALUE " */ + + + /* We load the key */ + { + char *key; + + key= result->key; + result->key_length= 0; + + for (; isgraph(*string_ptr); string_ptr++) + { + *key= *string_ptr; + key++; + result->key_length++; + } + result->key[result->key_length]= 0; + } + + if (end_ptr == string_ptr) + goto read_error; + + /* Flags fetch move past space */ + string_ptr++; + if (end_ptr == string_ptr) + goto read_error; + for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++); + result->flags= (uint32_t)strtol(next_ptr, &string_ptr, 10); + + if (end_ptr == string_ptr) + goto read_error; + + /* Length fetch move past space*/ + string_ptr++; + if (end_ptr == string_ptr) + goto read_error; + + for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++); + value_length= (size_t)strtoll(next_ptr, &string_ptr, 10); + + if (end_ptr == string_ptr) + goto read_error; + + /* Skip spaces */ + if (*string_ptr == '\r') + { + /* Skip past the \r\n */ + string_ptr+= 2; + result->cas= 0; + } + else + { + string_ptr++; + for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++); + result->cas= (size_t)strtoll(next_ptr, &string_ptr, 10); + } + + if (end_ptr < string_ptr) + goto read_error; + + /* We add two bytes so that we can walk the \r\n */ + rc= memcached_string_check(&result->value, value_length+2); + if (rc != MEMCACHED_SUCCESS) + { + value_length= 0; + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; + } + + value_ptr= memcached_string_value(&result->value); + read_length= 0; + /* + We read the \r\n into the string since not doing so is more + cycles then the waster of memory to do so. + + We are null terminating through, which will most likely make + some people lazy about using the return length. + */ + to_read= (value_length) + 2; + read_length= memcached_io_read(ptr, value_ptr, to_read); + if (read_length != (size_t)(value_length + 2)) + { + goto read_error; + } + +/* This next bit blows the API, but this is internal....*/ + { + char *char_ptr; + char_ptr= memcached_string_value(&result->value);; + char_ptr[value_length]= 0; + char_ptr[value_length + 1]= 0; + memcached_string_set_length(&result->value, value_length); + } + + return MEMCACHED_SUCCESS; + +read_error: + memcached_io_reset(ptr); + + return MEMCACHED_PARTIAL_READ; +} + +char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, + size_t *value_length, + uint32_t *flags, + memcached_return *error) +{ + memcached_result_st *result_buffer= &ptr->result; + + while (ptr->cursor_server < ptr->number_of_hosts) + { + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + + if (memcached_server_response_count(&ptr->hosts[ptr->cursor_server]) == 0) + { + ptr->cursor_server++; + continue; + } + + *error= memcached_response(&ptr->hosts[ptr->cursor_server], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result_buffer); + + if (*error == MEMCACHED_END) /* END means that we move on to the next */ + { + memcached_server_response_reset(&ptr->hosts[ptr->cursor_server]); + ptr->cursor_server++; + continue; + } + else if (*error == MEMCACHED_SUCCESS) + { + *value_length= memcached_string_length(&result_buffer->value); + + if (key) + { + strncpy(key, result_buffer->key, result_buffer->key_length); + *key_length= result_buffer->key_length; + } + + if (result_buffer->flags) + *flags= result_buffer->flags; + else + *flags= 0; + + return memcached_string_c_copy(&result_buffer->value); + } + else + { + *value_length= 0; + return NULL; + } + } + + ptr->cursor_server= 0; + *value_length= 0; + return NULL; +} + +memcached_result_st *memcached_fetch_result(memcached_st *ptr, + memcached_result_st *result, + memcached_return *error) +{ + if (result == NULL) + result= memcached_result_create(ptr, NULL); + + WATCHPOINT_ASSERT(result->value.is_allocated != MEMCACHED_USED); + +#ifdef UNUSED + if (ptr->flags & MEM_NO_BLOCK) + memcached_io_preread(ptr); +#endif + + while (ptr->cursor_server < ptr->number_of_hosts) + { + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + + if (memcached_server_response_count(&ptr->hosts[ptr->cursor_server]) == 0) + { + ptr->cursor_server++; + continue; + } + + *error= memcached_response(&ptr->hosts[ptr->cursor_server], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result); + + if (*error == MEMCACHED_END) /* END means that we move on to the next */ + { + memcached_server_response_reset(&ptr->hosts[ptr->cursor_server]); + ptr->cursor_server++; + continue; + } + else if (*error == MEMCACHED_SUCCESS) + return result; + else + return NULL; + } + + /* We have completed reading data */ + if (result->is_allocated == MEMCACHED_ALLOCATED) + memcached_result_free(result); + else + memcached_string_reset(&result->value); + + ptr->cursor_server= 0; + return NULL; +} diff --git a/libmemcached/memcached_fetch_execute.c b/libmemcached/memcached_fetch_execute.c new file mode 100644 index 00000000..29d76244 --- /dev/null +++ b/libmemcached/memcached_fetch_execute.c @@ -0,0 +1,48 @@ +#include "common.h" + +memcached_return memcached_fetch_execute(memcached_st *ptr, + memcached_execute_function *callback, + void *context, + unsigned int number_of_callbacks + ) +{ + memcached_result_st *result= &ptr->result; + + while (ptr->cursor_server < ptr->number_of_hosts) + { + memcached_return rc; + + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + + if (memcached_server_response_count(&ptr->hosts[ptr->cursor_server]) == 0) + { + ptr->cursor_server++; + continue; + } + + rc= memcached_response(&ptr->hosts[ptr->cursor_server], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result); + + if (rc == MEMCACHED_END) /* END means that we move on to the next */ + { + memcached_server_response_reset(&ptr->hosts[ptr->cursor_server]); + ptr->cursor_server++; + continue; + } + else if (rc == MEMCACHED_SUCCESS) + { + unsigned int x; + + for (x= 0; x < number_of_callbacks; x++) + { + memcached_return iferror; + + iferror= (*callback[x])(ptr, result, context); + + if (iferror != MEMCACHED_SUCCESS) + continue; + } + } + } + + return MEMCACHED_SUCCESS; +} diff --git a/libmemcached/memcached_flush.c b/libmemcached/memcached_flush.c new file mode 100644 index 00000000..1511adbe --- /dev/null +++ b/libmemcached/memcached_flush.c @@ -0,0 +1,31 @@ +#include "common.h" + +memcached_return memcached_flush(memcached_st *ptr, time_t expiration) +{ + unsigned int x; + size_t send_length; + memcached_return rc; + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + LIBMEMCACHED_MEMCACHED_FLUSH_START(); + + unlikely (ptr->number_of_hosts == 0) + return MEMCACHED_NO_SERVERS; + + for (x= 0; x < ptr->number_of_hosts; x++) + { + if (expiration) + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "flush_all %llu\r\n", (unsigned long long)expiration); + else + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "flush_all\r\n"); + + rc= memcached_do(&ptr->hosts[x], buffer, send_length, 1); + + if (rc == MEMCACHED_SUCCESS) + (void)memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); + } + + LIBMEMCACHED_MEMCACHED_FLUSH_END(); + return MEMCACHED_SUCCESS; +} diff --git a/libmemcached/memcached_get.c b/libmemcached/memcached_get.c new file mode 100644 index 00000000..8cc7ce30 --- /dev/null +++ b/libmemcached/memcached_get.c @@ -0,0 +1,172 @@ +#include "common.h" +#include "memcached_io.h" + +/* + What happens if no servers exist? +*/ +char *memcached_get(memcached_st *ptr, char *key, size_t key_length, + size_t *value_length, + uint32_t *flags, + memcached_return *error) +{ + return memcached_get_by_key(ptr, NULL, 0, key, key_length, value_length, + flags, error); +} + +char *memcached_get_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + size_t *value_length, + uint32_t *flags, + memcached_return *error) +{ + char *value; + size_t dummy_length; + uint32_t dummy_flags; + memcached_return dummy_error; + + /* Request the key */ + *error= memcached_mget_by_key(ptr, + master_key, + master_key_length, + &key, &key_length, 1); + + value= memcached_fetch(ptr, NULL, NULL, + value_length, flags, error); + /* This is for historical reasons */ + if (*error == MEMCACHED_END) + *error= MEMCACHED_NOTFOUND; + + if (value == NULL) + return NULL; + + (void)memcached_fetch(ptr, NULL, NULL, + &dummy_length, &dummy_flags, + &dummy_error); + WATCHPOINT_ASSERT(dummy_length == 0); + + return value; +} + +memcached_return memcached_mget(memcached_st *ptr, + char **keys, size_t *key_length, + unsigned int number_of_keys) +{ + return memcached_mget_by_key(ptr, NULL, 0, keys, key_length, number_of_keys); +} + +memcached_return memcached_mget_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char **keys, size_t *key_length, + unsigned int number_of_keys) +{ + unsigned int x; + memcached_return rc= MEMCACHED_NOTFOUND; + char *get_command= "get "; + uint8_t get_command_length= 4; + unsigned int master_server_key= 0; + + LIBMEMCACHED_MEMCACHED_MGET_START(); + ptr->cursor_server= 0; + + if (number_of_keys == 0) + return MEMCACHED_NOTFOUND; + + if (ptr->number_of_hosts == 0) + return MEMCACHED_NO_SERVERS; + + if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(keys, key_length, number_of_keys) == MEMCACHED_BAD_KEY_PROVIDED)) + return MEMCACHED_BAD_KEY_PROVIDED; + + if (ptr->flags & MEM_SUPPORT_CAS) + { + get_command= "gets "; + get_command_length= 5; + } + + if (master_key && master_key_length) + master_server_key= memcached_generate_hash(ptr, master_key, master_key_length); + + /* + Here is where we pay for the non-block API. We need to remove any data sitting + in the queue before we start our get. + + It might be optimum to bounce the connection if count > some number. + */ + for (x= 0; x < ptr->number_of_hosts; x++) + { + if (memcached_server_response_count(&ptr->hosts[x])) + { + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + + if (ptr->flags & MEM_NO_BLOCK) + (void)memcached_io_write(&ptr->hosts[x], NULL, 0, 1); + + while(memcached_server_response_count(&ptr->hosts[x])) + (void)memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, &ptr->result); + } + } + + /* + If a server fails we warn about errors and start all over with sending keys + to the server. + */ + for (x= 0; x < number_of_keys; x++) + { + unsigned int server_key; + + if (master_server_key) + server_key= master_server_key; + else + server_key= memcached_generate_hash(ptr, keys[x], key_length[x]); + + if (memcached_server_response_count(&ptr->hosts[server_key]) == 0) + { + rc= memcached_connect(&ptr->hosts[server_key]); + + if (rc != MEMCACHED_SUCCESS) + continue; + + if ((memcached_io_write(&ptr->hosts[server_key], get_command, get_command_length, 0)) == -1) + { + rc= MEMCACHED_SOME_ERRORS; + continue; + } + WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 0); + memcached_server_response_increment(&ptr->hosts[server_key]); + WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 1); + } + + if ((memcached_io_write(&ptr->hosts[server_key], keys[x], key_length[x], 0)) == -1) + { + memcached_server_response_reset(&ptr->hosts[server_key]); + rc= MEMCACHED_SOME_ERRORS; + continue; + } + + if ((memcached_io_write(&ptr->hosts[server_key], " ", 1, 0)) == -1) + { + memcached_server_response_reset(&ptr->hosts[server_key]); + rc= MEMCACHED_SOME_ERRORS; + continue; + } + } + + /* + Should we muddle on if some servers are dead? + */ + for (x= 0; x < ptr->number_of_hosts; x++) + { + if (memcached_server_response_count(&ptr->hosts[x])) + { + /* We need to do something about non-connnected hosts in the future */ + if ((memcached_io_write(&ptr->hosts[x], "\r\n", 2, 1)) == -1) + { + rc= MEMCACHED_SOME_ERRORS; + } + } + } + + LIBMEMCACHED_MEMCACHED_MGET_END(); + return rc; +} diff --git a/libmemcached/memcached_hash.c b/libmemcached/memcached_hash.c new file mode 100644 index 00000000..f365cc0e --- /dev/null +++ b/libmemcached/memcached_hash.c @@ -0,0 +1,156 @@ +#include "common.h" + +/* Defines */ +static uint64_t FNV_64_INIT= 0xcbf29ce484222325LL; +static uint64_t FNV_64_PRIME= 0x100000001b3LL; + +static uint32_t FNV_32_INIT= 2166136261UL; +static uint32_t FNV_32_PRIME= 16777619; + +/* Prototypes */ +static uint32_t internal_generate_hash(char *key, size_t key_length); +static uint32_t internal_generate_md5(char *key, size_t key_length); +static uint32_t internal_generate_ketama_md5(char *key, size_t key_length); + +unsigned int memcached_generate_hash(memcached_st *ptr, char *key, size_t key_length) +{ + uint32_t hash= 1; /* Just here to remove compile warning */ + unsigned int x; + + WATCHPOINT_ASSERT(ptr->number_of_hosts); + + if (ptr->number_of_hosts == 1) + return 0; + + switch (ptr->hash) + { + case MEMCACHED_HASH_DEFAULT: + hash= internal_generate_hash(key, key_length); + break; + case MEMCACHED_HASH_MD5: + hash= internal_generate_md5(key, key_length); + break; + case MEMCACHED_HASH_CRC: + hash= ((hash_crc32(key, key_length) >> 16) & 0x7fff); + if (hash == 0) + hash= 1; + break; + /* FNV hash'es lifted from Dustin Sallings work */ + case MEMCACHED_HASH_FNV1_64: + { + /* Thanks to pierre@demartines.com for the pointer */ + uint64_t temp_hash; + + temp_hash= FNV_64_INIT; + for (x= 0; x < key_length; x++) + { + temp_hash *= FNV_64_PRIME; + temp_hash ^= key[x]; + } + hash= (uint32_t)temp_hash; + } + break; + case MEMCACHED_HASH_FNV1A_64: + { + hash= FNV_64_INIT; + for (x= 0; x < key_length; x++) + { + hash ^= key[x]; + hash *= FNV_64_PRIME; + } + } + break; + case MEMCACHED_HASH_FNV1_32: + { + hash= FNV_32_INIT; + for (x= 0; x < key_length; x++) + { + hash *= FNV_32_PRIME; + hash ^= key[x]; + } + } + break; + case MEMCACHED_HASH_FNV1A_32: + { + hash= FNV_32_INIT; + for (x= 0; x < key_length; x++) + { + hash ^= key[x]; + hash *= FNV_32_PRIME; + } + } + break; + case MEMCACHED_HASH_KETAMA: + { + hash= internal_generate_ketama_md5(key, key_length); + break; + } + case MEMCACHED_HASH_HSIEH: + { + hash= hsieh_hash(key, key_length); + break; + } + case MEMCACHED_HASH_MURMUR: + { + hash= murmur_hash(key, key_length); + break; + } + } + + WATCHPOINT_ASSERT(hash); + + if (ptr->distribution == MEMCACHED_DISTRIBUTION_MODULA) + { + return hash % ptr->number_of_hosts; + } + else + { + unsigned int server_key; + + server_key= hash % MEMCACHED_WHEEL_SIZE; + + return ptr->wheel[server_key]; + } +} + +static uint32_t internal_generate_hash(char *key, size_t key_length) +{ + char *ptr= key; + uint32_t value= 0; + + while (--key_length) + { + value += *ptr++; + value += (value << 10); + value ^= (value >> 6); + } + value += (value << 3); + value ^= (value >> 11); + value += (value << 15); + + return value == 0 ? 1 : value; +} + +static uint32_t internal_generate_md5(char *key, size_t key_length) +{ + unsigned char results[16]; + + md5_signature((unsigned char*)key, (unsigned int)key_length, results); + + return (uint32_t)(( results[3] << 24 ) + | ( results[2] << 16 ) + | ( results[1] << 8 ) + | results[0] ); +} + +static uint32_t internal_generate_ketama_md5(char *key, size_t key_length) +{ + unsigned char results[16]; + + md5_signature((unsigned char*)key, (unsigned int)key_length, results); + + return ((uint32_t) (results[3] & 0xFF) << 24) + | ((uint32_t) (results[2] & 0xFF) << 16) + | ((uint32_t) (results[1] & 0xFF) << 8) + | (results[0] & 0xFF); +} diff --git a/libmemcached/memcached_hosts.c b/libmemcached/memcached_hosts.c new file mode 100644 index 00000000..fb53fa22 --- /dev/null +++ b/libmemcached/memcached_hosts.c @@ -0,0 +1,250 @@ +#include +#include "common.h" + +/* Protoypes (static) */ +static memcached_return server_add(memcached_st *ptr, char *hostname, + unsigned int port, + memcached_connection type); + +#define MEMCACHED_WHEEL_SIZE 1024 +#define MEMCACHED_STRIDE 4 +static void rebalance_wheel(memcached_st *ptr) +{ + unsigned int x; + unsigned int y; + unsigned int latch; + + /* Seed the Wheel */ + memset(ptr->wheel, 0, sizeof(unsigned int) * MEMCACHED_WHEEL_SIZE); + + for (latch= y= x= 0; x < MEMCACHED_WHEEL_SIZE; x++, latch++) + { + if (latch == MEMCACHED_STRIDE) + { + y++; + if (y == ptr->number_of_hosts) + y= 0; + latch= 0; + } + + ptr->wheel[x]= y; + } +} + +static int compare_servers(const void *p1, const void *p2) +{ + int return_value; + memcached_server_st *a= (memcached_server_st *)p1; + memcached_server_st *b= (memcached_server_st *)p2; + + return_value= strcmp(a->hostname, b->hostname); + + if (return_value == 0) + { + if (a->port > b->port) + return_value++; + else + return_value--; + } + + return return_value; +} + +static void host_reset(memcached_st *ptr, memcached_server_st *host, + char *hostname, unsigned int port, + memcached_connection type) +{ + memset(host, 0, sizeof(memcached_server_st)); + strncpy(host->hostname, hostname, MEMCACHED_MAX_HOST_LENGTH - 1); + host->root= ptr ? ptr : NULL; + host->port= port; + host->fd= -1; + host->type= type; + host->read_ptr= host->read_buffer; + if (ptr) + host->next_retry= ptr->retry_timeout; + host->sockaddr_inited= MEMCACHED_NOT_ALLOCATED; +} + +void server_list_free(memcached_st *ptr, memcached_server_st *servers) +{ + unsigned int x; + + if (servers == NULL) + return; + + for (x= 0; x < servers->count; x++) + if (servers[x].address_info) + freeaddrinfo(servers[x].address_info); + + if (ptr && ptr->call_free) + ptr->call_free(ptr, servers); + else + free(servers); +} + +memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list) +{ + unsigned int x; + uint16_t count; + memcached_server_st *new_host_list; + + if (!list) + return MEMCACHED_SUCCESS; + + count= list[0].count; + + if (ptr->call_realloc) + new_host_list= + (memcached_server_st *)ptr->call_realloc(ptr, ptr->hosts, + sizeof(memcached_server_st) * (count + ptr->number_of_hosts)); + else + new_host_list= + (memcached_server_st *)realloc(ptr->hosts, + sizeof(memcached_server_st) * (count + ptr->number_of_hosts)); + + if (!new_host_list) + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; + + ptr->hosts= new_host_list; + + for (x= 0; x < count; x++) + { + WATCHPOINT_ASSERT(list[x].hostname[0] != 0); + host_reset(ptr, &ptr->hosts[ptr->number_of_hosts], list[x].hostname, + list[x].port, list[x].type); + ptr->number_of_hosts++; + } + ptr->hosts[0].count= ptr->number_of_hosts; + + if (ptr->number_of_hosts > 1) + qsort(ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st), compare_servers); + + rebalance_wheel(ptr); + + return MEMCACHED_SUCCESS; +} + +memcached_return memcached_server_add_unix_socket(memcached_st *ptr, char *filename) +{ + if (!filename) + return MEMCACHED_FAILURE; + + return server_add(ptr, filename, 0, MEMCACHED_CONNECTION_UNIX_SOCKET); +} + +memcached_return memcached_server_add_udp(memcached_st *ptr, + char *hostname, + unsigned int port) +{ + if (!port) + port= MEMCACHED_DEFAULT_PORT; + + if (!hostname) + hostname= "localhost"; + + return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_UDP); +} + +memcached_return memcached_server_add(memcached_st *ptr, + char *hostname, + unsigned int port) +{ + if (!port) + port= MEMCACHED_DEFAULT_PORT; + + if (!hostname) + hostname= "localhost"; + + return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_TCP); +} + +static memcached_return server_add(memcached_st *ptr, char *hostname, + unsigned int port, + memcached_connection type) +{ + memcached_server_st *new_host_list; + LIBMEMCACHED_MEMCACHED_SERVER_ADD_START(); + + + if (ptr->call_realloc) + new_host_list= (memcached_server_st *)ptr->call_realloc(ptr, ptr->hosts, + sizeof(memcached_server_st) * (ptr->number_of_hosts+1)); + else + new_host_list= (memcached_server_st *)realloc(ptr->hosts, + sizeof(memcached_server_st) * (ptr->number_of_hosts+1)); + if (new_host_list == NULL) + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; + + ptr->hosts= new_host_list; + + host_reset(ptr, &ptr->hosts[ptr->number_of_hosts], hostname, port, type); + ptr->number_of_hosts++; + ptr->hosts[0].count++; + + if (ptr->number_of_hosts > 1) + qsort(ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st), compare_servers); + + rebalance_wheel(ptr); + + LIBMEMCACHED_MEMCACHED_SERVER_ADD_END(); + + return MEMCACHED_SUCCESS; +} + +memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, + char *hostname, unsigned int port, + memcached_return *error) +{ + unsigned int count; + memcached_server_st *new_host_list; + + if (hostname == NULL || error == NULL) + return NULL; + + if (!port) + port= MEMCACHED_DEFAULT_PORT; + + /* Increment count for hosts */ + count= 1; + if (ptr != NULL) + { + count+= ptr[0].count; + } + + new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count); + if (!new_host_list) + { + *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; + return NULL; + } + + host_reset(NULL, &new_host_list[count-1], hostname, port, MEMCACHED_CONNECTION_TCP); + + /* Backwards compatibility hack */ + new_host_list[0].count++; + + count= new_host_list[0].count; + + if (new_host_list[0].count > 1) + qsort(new_host_list, count, sizeof(memcached_server_st), compare_servers); + + new_host_list[0].count= count; + + + *error= MEMCACHED_SUCCESS; + return new_host_list; +} + +unsigned int memcached_server_list_count(memcached_server_st *ptr) +{ + if (ptr == NULL) + return 0; + + return ptr[0].count; +} + +void memcached_server_list_free(memcached_server_st *ptr) +{ + server_list_free(NULL, ptr); +} diff --git a/libmemcached/memcached_io.c b/libmemcached/memcached_io.c new file mode 100644 index 00000000..b9261f3d --- /dev/null +++ b/libmemcached/memcached_io.c @@ -0,0 +1,312 @@ +/* + Basic socket buffered IO +*/ + +#include "common.h" +#include "memcached_io.h" +#include +#include + +typedef enum { + MEM_READ, + MEM_WRITE, +} memc_read_or_write; + +static ssize_t io_flush(memcached_server_st *ptr, memcached_return *error); + +static memcached_return io_wait(memcached_server_st *ptr, + memc_read_or_write read_or_write) +{ + struct pollfd fds[1]; + short flags= 0; + int error; + + if (read_or_write == MEM_WRITE) /* write */ + flags= POLLOUT | POLLERR; + else + flags= POLLIN | POLLERR; + + memset(&fds, 0, sizeof(struct pollfd)); + fds[0].fd= ptr->fd; + fds[0].events= flags; + + error= poll(fds, 1, ptr->root->poll_timeout); + + if (error == 1) + return MEMCACHED_SUCCESS; + else if (error == 0) + { + return MEMCACHED_TIMEOUT; + } + + /* Imposssible for anything other then -1 */ + WATCHPOINT_ASSERT(error == -1); + memcached_quit_server(ptr, 1); + + return MEMCACHED_FAILURE; + +} + +#ifdef UNUSED +void memcached_io_preread(memcached_st *ptr) +{ + unsigned int x; + + return; + + for (x= 0; x < ptr->number_of_hosts; x++) + { + if (memcached_server_response_count(ptr, x) && + ptr->hosts[x].read_data_length < MEMCACHED_MAX_BUFFER ) + { + size_t data_read; + + data_read= read(ptr->hosts[x].fd, + ptr->hosts[x].read_ptr + ptr->hosts[x].read_data_length, + MEMCACHED_MAX_BUFFER - ptr->hosts[x].read_data_length); + if (data_read == -1) + continue; + + ptr->hosts[x].read_buffer_length+= data_read; + ptr->hosts[x].read_data_length+= data_read; + } + } +} +#endif + +ssize_t memcached_io_read(memcached_server_st *ptr, + char *buffer, size_t length) +{ + char *buffer_ptr; + + buffer_ptr= buffer; + + while (length) + { + uint8_t found_eof= 0; + if (!ptr->read_buffer_length) + { + ssize_t data_read; + + while (1) + { + data_read= read(ptr->fd, + ptr->read_buffer, + MEMCACHED_MAX_BUFFER); + if (data_read > 0) + break; + else if (data_read == -1) + { + ptr->cached_errno= errno; + switch (errno) + { + case EAGAIN: + { + memcached_return rc; + + rc= io_wait(ptr, MEM_READ); + + if (rc == MEMCACHED_SUCCESS) + continue; + } + /* fall trough */ + default: + { + memcached_quit_server(ptr, 1); + return -1; + } + } + } + else + { + found_eof= 1; + break; + } + } + + ptr->read_data_length= data_read; + ptr->read_buffer_length= data_read; + ptr->read_ptr= ptr->read_buffer; + } + + if (length > 1) + { + size_t difference; + + difference= (length > ptr->read_buffer_length) ? ptr->read_buffer_length : length; + + memcpy(buffer_ptr, ptr->read_ptr, difference); + length -= difference; + ptr->read_ptr+= difference; + ptr->read_buffer_length-= difference; + buffer_ptr+= difference; + } + else + { + *buffer_ptr= *ptr->read_ptr; + ptr->read_ptr++; + ptr->read_buffer_length--; + buffer_ptr++; + break; + } + + if (found_eof) + break; + } + + return (size_t)(buffer_ptr - buffer); +} + +ssize_t memcached_io_write(memcached_server_st *ptr, + char *buffer, size_t length, char with_flush) +{ + size_t original_length; + char* buffer_ptr; + + original_length= length; + buffer_ptr= buffer; + + while (length) + { + char *write_ptr; + size_t should_write; + + should_write= MEMCACHED_MAX_BUFFER - ptr->write_buffer_offset; + write_ptr= ptr->write_buffer + ptr->write_buffer_offset; + + should_write= (should_write < length) ? should_write : length; + + memcpy(write_ptr, buffer_ptr, should_write); + ptr->write_buffer_offset+= should_write; + buffer_ptr+= should_write; + length-= should_write; + + if (ptr->write_buffer_offset == MEMCACHED_MAX_BUFFER) + { + memcached_return rc; + ssize_t sent_length; + + sent_length= io_flush(ptr, &rc); + if (sent_length == -1) + return -1; + + WATCHPOINT_ASSERT(sent_length == MEMCACHED_MAX_BUFFER); + } + } + + if (with_flush) + { + memcached_return rc; + if (io_flush(ptr, &rc) == -1) + return -1; + } + + return original_length; +} + +memcached_return memcached_io_close(memcached_server_st *ptr) +{ + close(ptr->fd); + + return MEMCACHED_SUCCESS; +} + +static ssize_t io_flush(memcached_server_st *ptr, + memcached_return *error) +{ + size_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; + + if (ptr->write_buffer_offset == 0) + return 0; + + /* Looking for memory overflows */ + 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)); + + return_length= 0; + while (write_length) + { + WATCHPOINT_ASSERT(write_length > 0); + sent_length= 0; + if (ptr->type == MEMCACHED_CONNECTION_UDP) + { + struct addrinfo *ai; + + ai= ptr->address_info; + + /* Crappy test code */ + char buffer[HUGE_STRING_LEN + 8]; + memset(buffer, 0, HUGE_STRING_LEN + 8); + memcpy (buffer+8, local_write_ptr, write_length); + buffer[0]= 0; + buffer[1]= 0; + buffer[2]= 0; + buffer[3]= 0; + buffer[4]= 0; + buffer[5]= 1; + buffer[6]= 0; + buffer[7]= 0; + sent_length= sendto(ptr->fd, buffer, write_length + 8, 0, + (struct sockaddr *)ai->ai_addr, + ai->ai_addrlen); + if (sent_length == -1) + { + WATCHPOINT_ERRNO(errno); + WATCHPOINT_ASSERT(0); + } + sent_length-= 8; /* We remove the header */ + } + else + { + if ((ssize_t)(sent_length= write(ptr->fd, local_write_ptr, + write_length)) == -1) + { + switch (errno) + { + case ENOBUFS: + continue; + case EAGAIN: + { + memcached_return rc; + rc= io_wait(ptr, MEM_WRITE); + + if (rc == MEMCACHED_SUCCESS) + continue; + + memcached_quit_server(ptr, 1); + return -1; + } + default: + memcached_quit_server(ptr, 1); + ptr->cached_errno= errno; + *error= MEMCACHED_ERRNO; + return -1; + } + } + } + + local_write_ptr+= sent_length; + write_length-= sent_length; + return_length+= sent_length; + } + + WATCHPOINT_ASSERT(write_length == 0); + WATCHPOINT_ASSERT(return_length == ptr->write_buffer_offset); + ptr->write_buffer_offset= 0; + + return return_length; +} + +/* + Eventually we will just kill off the server with the problem. +*/ +void memcached_io_reset(memcached_server_st *ptr) +{ + memcached_quit_server(ptr, 0); +} diff --git a/libmemcached/memcached_io.h b/libmemcached/memcached_io.h new file mode 100644 index 00000000..30ac18b2 --- /dev/null +++ b/libmemcached/memcached_io.h @@ -0,0 +1,9 @@ +/* Server IO, Not public! */ +#include + +ssize_t memcached_io_write(memcached_server_st *ptr, + char *buffer, size_t length, char with_flush); +void memcached_io_reset(memcached_server_st *ptr); +ssize_t memcached_io_read(memcached_server_st *ptr, + char *buffer, size_t length); +memcached_return memcached_io_close(memcached_server_st *ptr); diff --git a/libmemcached/memcached_key.c b/libmemcached/memcached_key.c new file mode 100644 index 00000000..ef1fe15f --- /dev/null +++ b/libmemcached/memcached_key.c @@ -0,0 +1,20 @@ +#include "common.h" + +memcached_return memcachd_key_test(char **keys, size_t *key_length, + unsigned int number_of_keys) +{ + int x; + + for (x= 0; x < number_of_keys; x++) + { + int y; + for (y= 0; y < key_length[x]; y++) + { + if ((isgraph(keys[x][y])) == 0) + return MEMCACHED_BAD_KEY_PROVIDED; + } + } + + return MEMCACHED_SUCCESS; +} + diff --git a/libmemcached/memcached_parse.c b/libmemcached/memcached_parse.c new file mode 100644 index 00000000..366e77b5 --- /dev/null +++ b/libmemcached/memcached_parse.c @@ -0,0 +1,64 @@ +/* + I debated about putting this in the client library since it does an + action I don't really believe belongs in the library. + + Frankly its too damn useful not to be here though. +*/ + +#include +#include "common.h" + +memcached_server_st *memcached_servers_parse(char *server_strings) +{ + char *string; + unsigned int port; + char *begin_ptr; + char *end_ptr; + memcached_server_st *servers= NULL; + memcached_return rc; + + WATCHPOINT_ASSERT(server_strings); + + end_ptr= server_strings + strlen(server_strings); + + for (begin_ptr= server_strings, string= index(server_strings, ','); + begin_ptr != end_ptr; + string= index(begin_ptr, ',')) + { + char buffer[HUGE_STRING_LEN]; + char *ptr; + port= 0; + + if (string) + { + memcpy(buffer, begin_ptr, string - begin_ptr); + buffer[(unsigned int)(string - begin_ptr)]= 0; + begin_ptr= string+1; + } + else + { + size_t length= strlen(begin_ptr); + memcpy(buffer, begin_ptr, length); + buffer[length]= 0; + begin_ptr= end_ptr; + } + + ptr= index(buffer, ':'); + + if (ptr) + { + ptr[0]= 0; + + ptr++; + + port= strtol(ptr, (char **)NULL, 10); + } + + servers= memcached_server_list_append(servers, buffer, port, &rc); + + if (isspace(*begin_ptr)) + begin_ptr++; + } + + return servers; +} diff --git a/libmemcached/memcached_quit.c b/libmemcached/memcached_quit.c new file mode 100644 index 00000000..9874bb6e --- /dev/null +++ b/libmemcached/memcached_quit.c @@ -0,0 +1,60 @@ +#include "common.h" + +/* + This closes all connections (forces flush of input as well). + + Maybe add a host specific, or key specific version? + + The reason we send "quit" is that in case we have buffered IO, this + will force data to be completed. +*/ + +void memcached_quit_server(memcached_server_st *ptr, uint8_t io_death) +{ + if (ptr->fd != -1) + { + if (io_death == 0) + { + memcached_return rc; + ssize_t read_length; + char buffer[MEMCACHED_MAX_BUFFER]; + + rc= memcached_do(ptr, "quit\r\n", 6, 1); + WATCHPOINT_ASSERT(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_FETCH_NOTFINISHED); + + /* read until socket is closed, or there is an error + * closing the socket before all data is read + * results in server throwing away all data which is + * not read + */ + while ((read_length= + memcached_io_read(ptr, buffer, sizeof(buffer)/sizeof(*buffer))) + > 0) + { + ; + } + memcached_io_close(ptr); + } + + ptr->fd= -1; + ptr->write_buffer_offset= 0; + ptr->read_buffer_length= 0; + ptr->read_ptr= ptr->read_buffer; + memcached_server_response_reset(ptr); + } +} + +void memcached_quit(memcached_st *ptr) +{ + unsigned int x; + + if (ptr->hosts == NULL || + ptr->number_of_hosts == 0) + return; + + if (ptr->hosts && ptr->number_of_hosts) + { + for (x= 0; x < ptr->number_of_hosts; x++) + memcached_quit_server(&ptr->hosts[x], 0); + } +} diff --git a/libmemcached/memcached_response.c b/libmemcached/memcached_response.c new file mode 100644 index 00000000..6f9e7c33 --- /dev/null +++ b/libmemcached/memcached_response.c @@ -0,0 +1,181 @@ +/* + Memcached library + + memcached_response() is used to determine the return result + from an issued command. +*/ + +#include "common.h" +#include "memcached_io.h" + +memcached_return memcached_response(memcached_server_st *ptr, + char *buffer, size_t buffer_length, + memcached_result_st *result) +{ + unsigned int x; + size_t send_length; + char *buffer_ptr; + unsigned int max_messages; + + + send_length= 0; + /* UDP at the moment is odd...*/ + if (ptr->type == MEMCACHED_CONNECTION_UDP) + { + char buffer[8]; + ssize_t read_length; + + return MEMCACHED_SUCCESS; + + read_length= memcached_io_read(ptr, buffer, 8); + } + + /* We may have old commands in the buffer not set, first purge */ + if (ptr->root->flags & MEM_NO_BLOCK) + (void)memcached_io_write(ptr, NULL, 0, 1); + + max_messages= memcached_server_response_count(ptr); + for (x= 0; x < max_messages; x++) + { + size_t total_length= 0; + buffer_ptr= buffer; + + + while (1) + { + ssize_t read_length; + + read_length= memcached_io_read(ptr, buffer_ptr, 1); + WATCHPOINT_ASSERT(isgraph(*buffer_ptr) || isspace(*buffer_ptr)); + + if (read_length != 1) + { + memcached_io_reset(ptr); + return MEMCACHED_UNKNOWN_READ_FAILURE; + } + + if (*buffer_ptr == '\n') + break; + else + buffer_ptr++; + + total_length++; + WATCHPOINT_ASSERT(total_length <= buffer_length); + + if (total_length >= buffer_length) + { + memcached_io_reset(ptr); + return MEMCACHED_PROTOCOL_ERROR; + } + } + buffer_ptr++; + *buffer_ptr= 0; + + memcached_server_response_decrement(ptr); + } + + switch(buffer[0]) + { + case 'V': /* VALUE || VERSION */ + if (buffer[1] == 'A') /* VALUE */ + { + memcached_return rc; + + /* We add back in one because we will need to search for END */ + memcached_server_response_increment(ptr); + if (result) + rc= value_fetch(ptr, buffer, result); + else + rc= value_fetch(ptr, buffer, &ptr->root->result); + + return rc; + } + else if (buffer[1] == 'E') /* VERSION */ + { + return MEMCACHED_SUCCESS; + } + else + { + WATCHPOINT_STRING(buffer); + WATCHPOINT_ASSERT(0); + memcached_io_reset(ptr); + return MEMCACHED_UNKNOWN_READ_FAILURE; + } + case 'O': /* OK */ + return MEMCACHED_SUCCESS; + case 'S': /* STORED STATS SERVER_ERROR */ + { + if (buffer[2] == 'A') /* STORED STATS */ + { + memcached_server_response_increment(ptr); + return MEMCACHED_STAT; + } + else if (buffer[1] == 'E') + return MEMCACHED_SERVER_ERROR; + else if (buffer[1] == 'T') + return MEMCACHED_STORED; + else + { + WATCHPOINT_STRING(buffer); + WATCHPOINT_ASSERT(0); + memcached_io_reset(ptr); + return MEMCACHED_UNKNOWN_READ_FAILURE; + } + } + case 'D': /* DELETED */ + return MEMCACHED_DELETED; + case 'N': /* NOT_FOUND */ + { + if (buffer[4] == 'F') + return MEMCACHED_NOTFOUND; + else if (buffer[4] == 'S') + return MEMCACHED_NOTSTORED; + else + { + memcached_io_reset(ptr); + return MEMCACHED_UNKNOWN_READ_FAILURE; + } + } + case 'E': /* PROTOCOL ERROR or END */ + { + if (buffer[1] == 'N') + return MEMCACHED_END; + else if (buffer[1] == 'R') + { + memcached_io_reset(ptr); + return MEMCACHED_PROTOCOL_ERROR; + } + else if (buffer[1] == 'X') + { + memcached_io_reset(ptr); + return MEMCACHED_DATA_EXISTS; + } + else + { + memcached_io_reset(ptr); + return MEMCACHED_UNKNOWN_READ_FAILURE; + } + } + case 'C': /* CLIENT ERROR */ + memcached_io_reset(ptr); + return MEMCACHED_CLIENT_ERROR; + default: + memcached_io_reset(ptr); + return MEMCACHED_UNKNOWN_READ_FAILURE; + + } + + return MEMCACHED_SUCCESS; +} + +char *memcached_result_value(memcached_result_st *ptr) +{ + memcached_string_st *sptr= &ptr->value; + return memcached_string_value(sptr); +} + +size_t memcached_result_length(memcached_result_st *ptr) +{ + memcached_string_st *sptr= &ptr->value; + return memcached_string_length(sptr); +} diff --git a/libmemcached/memcached_result.c b/libmemcached/memcached_result.c new file mode 100644 index 00000000..cf3894be --- /dev/null +++ b/libmemcached/memcached_result.c @@ -0,0 +1,50 @@ +/* + memcached_result_st are used to internally represent the return values from + memcached. We use a structure so that long term as identifiers are added + to memcached we will be able to absorb new attributes without having + to addjust the entire API. +*/ +#include "common.h" + +memcached_result_st *memcached_result_create(memcached_st *memc, + memcached_result_st *ptr) +{ + /* Saving malloc calls :) */ + if (ptr) + { + memset(ptr, 0, sizeof(memcached_result_st)); + ptr->is_allocated= MEMCACHED_NOT_ALLOCATED; + } + else + { + if (memc->call_malloc) + ptr= (memcached_result_st *)memc->call_malloc(memc, sizeof(memcached_result_st)); + else + ptr= (memcached_result_st *)malloc(sizeof(memcached_result_st)); + + if (ptr == NULL) + return NULL; + memset(ptr, 0, sizeof(memcached_result_st)); + ptr->is_allocated= MEMCACHED_ALLOCATED; + } + + ptr->root= memc; + memcached_string_create(memc, &ptr->value, 0); + WATCHPOINT_ASSERT(ptr->value.string == NULL); + WATCHPOINT_ASSERT(ptr->value.is_allocated == MEMCACHED_NOT_ALLOCATED); + + return ptr; +} + +void memcached_result_free(memcached_result_st *ptr) +{ + if (ptr == NULL) + return; + + memcached_string_free(&ptr->value); + + if (ptr->is_allocated == MEMCACHED_ALLOCATED) + free(ptr); + else + ptr->is_allocated= MEMCACHED_USED; +} diff --git a/libmemcached/memcached_server.c b/libmemcached/memcached_server.c new file mode 100644 index 00000000..fd86e6d6 --- /dev/null +++ b/libmemcached/memcached_server.c @@ -0,0 +1,26 @@ +#include "common.h" + +memcached_return memcached_server_cursor(memcached_st *ptr, + memcached_server_function *callback, + void *context, + unsigned int number_of_callbacks) +{ + unsigned int y; + + for (y= 0; y < ptr->number_of_hosts; y++) + { + unsigned int x; + + for (x= 0; x < number_of_callbacks; x++) + { + unsigned int iferror; + + iferror= (*callback[x])(ptr, &ptr->hosts[y], context); + + if (iferror) + continue; + } + } + + return MEMCACHED_SUCCESS; +} diff --git a/libmemcached/memcached_stats.c b/libmemcached/memcached_stats.c new file mode 100644 index 00000000..a1ef99f3 --- /dev/null +++ b/libmemcached/memcached_stats.c @@ -0,0 +1,365 @@ +/* +*/ + +#include "common.h" + +static char *memcached_stat_keys[] = { + "pid", + "uptime", + "time", + "version", + "pointer_size", + "rusage_user", + "rusage_system", + "curr_items", + "total_items", + "bytes", + "curr_connections", + "total_connections", + "connection_structures", + "cmd_get", + "cmd_set", + "get_hits", + "get_misses", + "evictions", + "bytes_read", + "bytes_written", + "limit_maxbytes", + "threads", + NULL +}; + + +static void set_data(memcached_stat_st *stat, char *key, char *value) +{ + + if(strlen(key) < 1) + { + fprintf(stderr, "Invalid key %s\n", key); + } + else if (!strcmp("pid", key)) + { + stat->pid= strtol(value, (char **)NULL, 10); + } + else if (!strcmp("uptime", key)) + { + stat->uptime= strtol(value, (char **)NULL, 10); + } + else if (!strcmp("time", key)) + { + stat->time= strtol(value, (char **)NULL, 10); + } + else if (!strcmp("version", key)) + { + memcpy(stat->version, value, strlen(value)); + stat->version[strlen(value)]= 0; + } + else if (!strcmp("pointer_size", key)) + { + stat->pointer_size= strtol(value, (char **)NULL, 10); + } + else if (!strcmp("rusage_user", key)) + { + char *walk_ptr; + for (walk_ptr= value; (!ispunct(*walk_ptr)); walk_ptr++); + *walk_ptr= 0; + walk_ptr++; + stat->rusage_user_seconds= strtol(value, (char **)NULL, 10); + stat->rusage_user_microseconds= strtol(walk_ptr, (char **)NULL, 10); + } + else if (!strcmp("rusage_system", key)) + { + char *walk_ptr; + for (walk_ptr= value; (!ispunct(*walk_ptr)); walk_ptr++); + *walk_ptr= 0; + walk_ptr++; + stat->rusage_system_seconds= strtol(value, (char **)NULL, 10); + stat->rusage_system_microseconds= strtol(walk_ptr, (char **)NULL, 10); + } + else if (!strcmp("curr_items", key)) + { + stat->curr_items= strtol(value, (char **)NULL, 10); + } + else if (!strcmp("total_items", key)) + { + stat->total_items= strtol(value, (char **)NULL, 10); + } + else if (!strcmp("bytes", key)) + { + stat->bytes= strtoll(value, (char **)NULL, 10); + } + else if (!strcmp("curr_connections", key)) + { + stat->curr_connections= strtoll(value, (char **)NULL, 10); + } + else if (!strcmp("total_connections", key)) + { + stat->total_connections= strtoll(value, (char **)NULL, 10); + } + else if (!strcmp("connection_structures", key)) + { + stat->connection_structures= strtol(value, (char **)NULL, 10); + } + else if (!strcmp("cmd_get", key)) + { + stat->cmd_get= strtoll(value, (char **)NULL, 10); + } + else if (!strcmp("cmd_set", key)) + { + stat->cmd_set= strtoll(value, (char **)NULL, 10); + } + else if (!strcmp("get_hits", key)) + { + stat->get_hits= strtoll(value, (char **)NULL, 10); + } + else if (!strcmp("get_misses", key)) + { + stat->get_misses= (uint64_t)strtoll(value, (char **)NULL, 10); + } + else if (!strcmp("evictions", key)) + { + stat->evictions= (uint64_t)strtoll(value, (char **)NULL, 10); + } + else if (!strcmp("bytes_read", key)) + { + stat->bytes_read= strtoll(value, (char **)NULL, 10); + } + else if (!strcmp("bytes_written", key)) + { + stat->bytes_written= strtoll(value, (char **)NULL, 10); + } + else if (!strcmp("limit_maxbytes", key)) + { + stat->limit_maxbytes= strtol(value, (char **)NULL, 10); + } + else if (!strcmp("threads", key)) + { + stat->threads= strtol(key, (char **)NULL, 10); + } + else + { + fprintf(stderr, "Unknown key %s\n", key); + } +} + +char *memcached_stat_get_value(memcached_st *ptr, memcached_stat_st *stat, + char *key, memcached_return *error) +{ + char buffer[SMALL_STRING_LEN]; + size_t length; + char *ret; + + *error= MEMCACHED_SUCCESS; + + if (!memcmp("pid", key, strlen("pid"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->pid); + else if (!memcmp("uptime", key, strlen("uptime"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->uptime); + else if (!memcmp("time", key, strlen("time"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->time); + else if (!memcmp("version", key, strlen("version"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%s", stat->version); + else if (!memcmp("pointer_size", key, strlen("pointer_size"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->pointer_size); + else if (!memcmp("rusage_user", key, strlen("rusage_user"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u.%u", stat->rusage_user_seconds, stat->rusage_user_microseconds); + else if (!memcmp("rusage_system", key, strlen("rusage_system"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u.%u", stat->rusage_system_seconds, stat->rusage_system_microseconds); + else if (!memcmp("curr_items", key, strlen("curr_items"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->curr_items); + else if (!memcmp("total_items", key, strlen("total_items"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->total_items); + else if (!memcmp("bytes", key, strlen("bytes"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes); + else if (!memcmp("curr_connections", key, strlen("curr_connections"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->curr_connections); + else if (!memcmp("total_connections", key, strlen("total_connections"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->total_connections); + else if (!memcmp("connection_structures", key, strlen("connection_structures"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->connection_structures); + else if (!memcmp("cmd_get", key, strlen("cmd_get"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->cmd_get); + else if (!memcmp("cmd_set", key, strlen("cmd_set"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->cmd_set); + else if (!memcmp("get_hits", key, strlen("get_hits"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->get_hits); + else if (!memcmp("get_misses", key, strlen("get_misses"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->get_misses); + else if (!memcmp("evictions", key, strlen("evictions"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->evictions); + else if (!memcmp("bytes_read", key, strlen("bytes_read"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes_read); + else if (!memcmp("bytes_written", key, strlen("bytes_written"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes_written); + else if (!memcmp("limit_maxbytes", key, strlen("limit_maxbytes"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%llu", stat->limit_maxbytes); + else if (!memcmp("threads", key, strlen("threads"))) + length= snprintf(buffer, SMALL_STRING_LEN,"%u", stat->threads); + else + { + *error= MEMCACHED_NOTFOUND; + return NULL; + } + + if (ptr->call_malloc) + ret= ptr->call_malloc(ptr, length + 1); + else + ret= malloc(length + 1); + memcpy(ret, buffer, length); + ret[length]= '\0'; + + return ret; +} + +static memcached_return memcached_stats_fetch(memcached_st *ptr, + memcached_stat_st *stat, + char *args, + unsigned int server_key) +{ + memcached_return rc; + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + size_t send_length; + + if (args) + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "stats %s\r\n", args); + else + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "stats\r\n"); + + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + return MEMCACHED_WRITE_FAILURE; + + rc= memcached_do(&ptr->hosts[server_key], buffer, send_length, 1); + if (rc != MEMCACHED_SUCCESS) + goto error; + + while (1) + { + rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); + + if (rc == MEMCACHED_STAT) + { + char *string_ptr, *end_ptr; + char *key, *value; + + string_ptr= buffer; + string_ptr+= 5; /* Move past STAT */ + for (end_ptr= string_ptr; isgraph(*end_ptr); end_ptr++); + key= string_ptr; + key[(size_t)(end_ptr-string_ptr)]= 0; + + string_ptr= end_ptr + 1; + for (end_ptr= string_ptr; !(isspace(*end_ptr)); end_ptr++); + value= string_ptr; + value[(size_t)(end_ptr-string_ptr)]= 0; + string_ptr= end_ptr + 2; + set_data(stat, key, value); + } + else + break; + } + +error: + if (rc == MEMCACHED_END) + return MEMCACHED_SUCCESS; + else + return rc; +} + +memcached_stat_st *memcached_stat(memcached_st *ptr, char *args, memcached_return *error) +{ + unsigned int x; + memcached_return rc; + memcached_stat_st *stats; + + if (ptr->call_malloc) + stats= (memcached_stat_st *)ptr->call_malloc(ptr, sizeof(memcached_stat_st)*(ptr->number_of_hosts)); + else + stats= (memcached_stat_st *)malloc(sizeof(memcached_stat_st)*(ptr->number_of_hosts)); + + if (!stats) + { + *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; + if (ptr->call_free) + ptr->call_free(ptr, stats); + else + free(stats); + + return NULL; + } + memset(stats, 0, sizeof(memcached_stat_st)*(ptr->number_of_hosts)); + + rc= MEMCACHED_SUCCESS; + for (x= 0; x < ptr->number_of_hosts; x++) + { + memcached_return temp_return; + + temp_return= memcached_stats_fetch(ptr, stats + x, args, x); + if (temp_return != MEMCACHED_SUCCESS) + rc= MEMCACHED_SOME_ERRORS; + } + + *error= rc; + return stats; +} + +memcached_return memcached_stat_servername(memcached_stat_st *stat, char *args, + char *hostname, unsigned int port) +{ + memcached_return rc; + memcached_st memc; + + memcached_create(&memc); + + memcached_server_add(&memc, hostname, port); + + rc= memcached_stats_fetch(&memc, stat, args, 0); + + memcached_free(&memc); + + return rc; +} + +/* + We make a copy of the keys since at some point in the not so distant future + we will add support for "found" keys. +*/ +char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *stat, + memcached_return *error) +{ + char **list; + size_t length= sizeof(memcached_stat_keys); + + if (ptr->call_malloc) + list= (char **)ptr->call_malloc(ptr, length); + else + list= (char **)malloc(length); + + if (!list) + { + *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; + return NULL; + } + memset(list, 0, sizeof(memcached_stat_keys)); + + memcpy(list, memcached_stat_keys, sizeof(memcached_stat_keys)); + + *error= MEMCACHED_SUCCESS; + + return list; +} + +void memcached_stat_free(memcached_st *ptr, memcached_stat_st *stat) +{ + if (stat == NULL) + { + WATCHPOINT_ASSERT(0); /* Be polite, but when debugging catch this as an error */ + return; + } + + if (ptr && ptr->call_free) + ptr->call_free(ptr, stat); + else + free(stat); +} diff --git a/libmemcached/memcached_storage.c b/libmemcached/memcached_storage.c new file mode 100644 index 00000000..fb3e6b2b --- /dev/null +++ b/libmemcached/memcached_storage.c @@ -0,0 +1,302 @@ +/* + Memcached library + + memcached_set() + memcached_replace() + memcached_add() + +*/ + +#include "common.h" +#include "memcached_io.h" + +typedef enum { + SET_OP, + REPLACE_OP, + ADD_OP, + PREPEND_OP, + APPEND_OP, + CAS_OP, +} memcached_storage_action; + +/* Inline this */ +static char *storage_op_string(memcached_storage_action 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"; + }; + + return SET_OP; +} + +static inline memcached_return memcached_send(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags, + uint64_t cas, + memcached_storage_action verb) +{ + char to_write; + size_t write_length; + ssize_t sent_length; + memcached_return rc; + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + unsigned int server_key; + + WATCHPOINT_ASSERT(!(value == NULL && value_length > 0)); + WATCHPOINT_ASSERT(!(value && value_length == 0)); + + unlikely (key_length == 0) + return MEMCACHED_NO_KEY_PROVIDED; + + unlikely (ptr->number_of_hosts == 0) + return MEMCACHED_NO_SERVERS; + + if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED)) + return MEMCACHED_BAD_KEY_PROVIDED; + + server_key= memcached_generate_hash(ptr, master_key, master_key_length); + + if (cas) + write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "%s %.*s %u %llu %zu %llu\r\n", storage_op_string(verb), + (int)key_length, key, flags, + (unsigned long long)expiration, value_length, + (unsigned long long)cas); + else + write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "%s %.*s %u %llu %zu\r\n", storage_op_string(verb), + (int)key_length, key, flags, + (unsigned long long)expiration, value_length); + + if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + { + rc= MEMCACHED_WRITE_FAILURE; + goto error; + } + + rc= memcached_do(&ptr->hosts[server_key], buffer, write_length, 0); + if (rc != MEMCACHED_SUCCESS) + goto error; + + if ((sent_length= memcached_io_write(&ptr->hosts[server_key], value, value_length, 0)) == -1) + { + rc= MEMCACHED_WRITE_FAILURE; + goto error; + } + + if ((ptr->flags & MEM_BUFFER_REQUESTS) && verb == SET_OP) + to_write= 0; + else + to_write= 1; + + if ((sent_length= memcached_io_write(&ptr->hosts[server_key], "\r\n", 2, to_write)) == -1) + { + rc= MEMCACHED_WRITE_FAILURE; + goto error; + } + + if (to_write == 0) + return MEMCACHED_BUFFERED; + + rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); + + if (rc == MEMCACHED_STORED) + return MEMCACHED_SUCCESS; + else + return rc; + +error: + memcached_io_reset(&ptr->hosts[server_key]); + + return rc; +} + +memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_SET_START(); + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, 0, SET_OP); + LIBMEMCACHED_MEMCACHED_SET_END(); + return rc; +} + +memcached_return memcached_add(memcached_st *ptr, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_ADD_START(); + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, 0, ADD_OP); + LIBMEMCACHED_MEMCACHED_ADD_END(); + return rc; +} + +memcached_return memcached_replace(memcached_st *ptr, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_REPLACE_START(); + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, 0, REPLACE_OP); + LIBMEMCACHED_MEMCACHED_REPLACE_END(); + return rc; +} + +memcached_return memcached_prepend(memcached_st *ptr, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, 0, PREPEND_OP); + return rc; +} + +memcached_return memcached_append(memcached_st *ptr, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, 0, APPEND_OP); + return rc; +} + +memcached_return memcached_cas(memcached_st *ptr, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags, + uint64_t cas) +{ + memcached_return rc; + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, cas, CAS_OP); + return rc; +} + +memcached_return memcached_set_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_SET_START(); + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, 0, SET_OP); + LIBMEMCACHED_MEMCACHED_SET_END(); + return rc; +} + +memcached_return memcached_add_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_ADD_START(); + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, 0, ADD_OP); + LIBMEMCACHED_MEMCACHED_ADD_END(); + return rc; +} + +memcached_return memcached_replace_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_REPLACE_START(); + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, 0, REPLACE_OP); + LIBMEMCACHED_MEMCACHED_REPLACE_END(); + return rc; +} + +memcached_return memcached_prepend_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, 0, PREPEND_OP); + return rc; +} + +memcached_return memcached_append_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, 0, APPEND_OP); + return rc; +} + +memcached_return memcached_cas_by_key(memcached_st *ptr, + char *master_key, size_t master_key_length, + char *key, size_t key_length, + char *value, size_t value_length, + time_t expiration, + uint32_t flags, + uint64_t cas) +{ + memcached_return rc; + rc= memcached_send(ptr, key, key_length, + key, key_length, value, value_length, + expiration, flags, cas, CAS_OP); + return rc; +} diff --git a/libmemcached/memcached_strerror.c b/libmemcached/memcached_strerror.c new file mode 100644 index 00000000..3271682d --- /dev/null +++ b/libmemcached/memcached_strerror.c @@ -0,0 +1,78 @@ +#include "common.h" + +char *memcached_strerror(memcached_st *ptr, memcached_return rc) +{ + switch (rc) + { + case MEMCACHED_SUCCESS: + return "SUCCESS"; + case MEMCACHED_FAILURE: + return "FAILURE"; + case MEMCACHED_HOST_LOOKUP_FAILURE: + return "HOSTNAME LOOKUP FAILURE"; + case MEMCACHED_CONNECTION_FAILURE: + return "CONNECTION FAILURE"; + case MEMCACHED_CONNECTION_BIND_FAILURE: + return "CONNECTION BIND FAILURE"; + case MEMCACHED_READ_FAILURE: + return "READ FAILURE"; + case MEMCACHED_UNKNOWN_READ_FAILURE: + return "UNKNOWN READ FAILURE"; + case MEMCACHED_PROTOCOL_ERROR: + return "PROTOCOL ERROR"; + case MEMCACHED_CLIENT_ERROR: + return "CLIENT ERROR"; + case MEMCACHED_SERVER_ERROR: + return "SERVER ERROR"; + case MEMCACHED_WRITE_FAILURE: + return "WRITE FAILURE"; + case MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE: + return "CONNECTION SOCKET CREATE FAILURE"; + case MEMCACHED_DATA_EXISTS: + return "CONNECTION DATA EXISTS"; + case MEMCACHED_DATA_DOES_NOT_EXIST: + return "CONNECTION DATA DOES NOT EXIST"; + case MEMCACHED_NOTSTORED: + return "NOT STORED"; + case MEMCACHED_STORED: + return "STORED"; + case MEMCACHED_NOTFOUND: + return "NOT FOUND"; + case MEMCACHED_MEMORY_ALLOCATION_FAILURE: + return "MEMORY ALLOCATION FAILURE"; + case MEMCACHED_PARTIAL_READ: + return "PARTIAL READ"; + case MEMCACHED_SOME_ERRORS: + return "SOME ERRORS WERE REPORTED"; + case MEMCACHED_NO_SERVERS: + return "NO SERVERS DEFINED"; + case MEMCACHED_END: + return "SERVER END"; + case MEMCACHED_DELETED: + return "SERVER DELETE"; + case MEMCACHED_VALUE: + return "SERVER VALUE"; + case MEMCACHED_STAT: + return "STAT VALUE"; + case MEMCACHED_ERRNO: + return "SYSTEM ERROR"; + case MEMCACHED_FAIL_UNIX_SOCKET: + return "COULD NOT OPEN UNIX SOCKET"; + case MEMCACHED_NOT_SUPPORTED: + return "ACTION NOT SUPPORTED"; + case MEMCACHED_FETCH_NOTFINISHED: + return "FETCH WAS NOT COMPLETED"; + case MEMCACHED_NO_KEY_PROVIDED: + return "A KEY LENGTH OF ZERO WAS PROVIDED"; + case MEMCACHED_BUFFERED: + return "ACTION QUEUED"; + case MEMCACHED_TIMEOUT: + return "A TIMEOUT OCCURRED"; + case MEMCACHED_BAD_KEY_PROVIDED: + return "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE"; + case MEMCACHED_MAXIMUM_RETURN: + return "Gibberish returned!"; + default: + return "Gibberish returned!"; + }; +} diff --git a/libmemcached/memcached_string.c b/libmemcached/memcached_string.c new file mode 100644 index 00000000..1595ec61 --- /dev/null +++ b/libmemcached/memcached_string.c @@ -0,0 +1,190 @@ +#include "common.h" + +memcached_return memcached_string_check(memcached_string_st *string, size_t need) +{ + if (need && need > (size_t)(string->current_size - (size_t)(string->end - string->string))) + { + size_t current_offset= string->end - string->string; + char *new_value; + size_t adjust; + size_t new_size; + + /* This is the block multiplier. To keep it larger and surive division errors we must round it up */ + adjust= (need - (size_t)(string->current_size - (size_t)(string->end - string->string))) / string->block_size; + adjust++; + + new_size= sizeof(char) * (size_t)((adjust * string->block_size) + string->current_size); + /* Test for overflow */ + if (new_size < need) + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; + + if (string->root->call_realloc) + new_value= (char *)string->root->call_realloc(string->root, string->string, new_size); + else + new_value= (char *)realloc(string->string, new_size); + + if (new_value == NULL) + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; + + string->string= new_value; + string->end= string->string + current_offset; + + string->current_size+= (string->block_size * adjust); + } + + return MEMCACHED_SUCCESS; +} + +memcached_string_st *memcached_string_create(memcached_st *ptr, memcached_string_st *string, size_t initial_size) +{ + memcached_return rc; + + /* Saving malloc calls :) */ + if (string) + { + memset(string, 0, sizeof(memcached_string_st)); + string->is_allocated= MEMCACHED_NOT_ALLOCATED; + } + else + { + if (ptr->call_malloc) + string= (memcached_string_st *)ptr->call_malloc(ptr, sizeof(memcached_string_st)); + else + string= (memcached_string_st *)malloc(sizeof(memcached_string_st)); + + if (string == NULL) + return NULL; + memset(string, 0, sizeof(memcached_string_st)); + string->is_allocated= MEMCACHED_ALLOCATED; + } + string->block_size= MEMCACHED_BLOCK_SIZE; + string->root= ptr; + + rc= memcached_string_check(string, initial_size); + if (rc != MEMCACHED_SUCCESS) + { + if (ptr->call_free) + ptr->call_free(ptr, string); + else + free(string); + + return NULL; + } + + WATCHPOINT_ASSERT(string->string == string->end); + + return string; +} + +memcached_return memcached_string_append_character(memcached_string_st *string, + char character) +{ + memcached_return rc; + + WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); + + rc= memcached_string_check(string, 1); + + if (rc != MEMCACHED_SUCCESS) + return rc; + + *string->end= ' '; + string->end++; + + return MEMCACHED_SUCCESS; +} + +memcached_return memcached_string_append(memcached_string_st *string, + char *value, size_t length) +{ + memcached_return rc; + + WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); + + rc= memcached_string_check(string, length); + + if (rc != MEMCACHED_SUCCESS) + return rc; + + WATCHPOINT_ASSERT(length <= string->current_size); + WATCHPOINT_ASSERT(string->string); + WATCHPOINT_ASSERT(string->end >= string->string); + + memcpy(string->end, value, length); + string->end+= length; + + return MEMCACHED_SUCCESS; +} + +size_t memcached_string_backspace(memcached_string_st *string, size_t remove) +{ + WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); + + if (string->end - string->string > remove) + { + size_t difference; + + difference= string->end - string->string; + string->end= string->string; + + return difference; + } + string->end-= remove; + + return remove; +} + +char *memcached_string_c_copy(memcached_string_st *string) +{ + char *c_ptr; + + WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); + + if (memcached_string_length(string) == 0) + return NULL; + + if (string->root->call_malloc) + c_ptr= (char *)string->root->call_malloc(string->root, (memcached_string_length(string)+1) * sizeof(char)); + else + c_ptr= (char *)malloc((memcached_string_length(string)+1) * sizeof(char)); + + if (c_ptr == NULL) + return NULL; + + memcpy(c_ptr, memcached_string_value(string), memcached_string_length(string)); + c_ptr[memcached_string_length(string)]= 0; + + return c_ptr; +} + +memcached_return memcached_string_reset(memcached_string_st *string) +{ + WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); + string->end= string->string; + + return MEMCACHED_SUCCESS; +} + +void memcached_string_free(memcached_string_st *ptr) +{ + if (ptr == NULL) + return; + + if (ptr->string) + { + if (ptr->root->call_free) + ptr->root->call_free(ptr->root, ptr->string); + else + free(ptr->string); + } + + if (ptr->is_allocated == MEMCACHED_ALLOCATED) + { + if (ptr->root->call_free) + ptr->root->call_free(ptr->root, ptr); + else + free(ptr); + } + else + ptr->is_allocated= MEMCACHED_USED; +} diff --git a/libmemcached/memcached_verbosity.c b/libmemcached/memcached_verbosity.c new file mode 100644 index 00000000..7cfb073f --- /dev/null +++ b/libmemcached/memcached_verbosity.c @@ -0,0 +1,33 @@ +#include "common.h" + +memcached_return memcached_verbosity(memcached_st *ptr, unsigned int verbosity) +{ + unsigned int x; + size_t send_length; + memcached_return rc; + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "verbosity %u\r\n", verbosity); + unlikely (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + return MEMCACHED_WRITE_FAILURE; + + rc= MEMCACHED_SUCCESS; + for (x= 0; x < ptr->number_of_hosts; x++) + { + memcached_return rrc; + + rrc= memcached_do(&ptr->hosts[x], buffer, send_length, 1); + if (rrc != MEMCACHED_SUCCESS) + { + rc= MEMCACHED_SOME_ERRORS; + continue; + } + + rrc= memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); + if (rrc != MEMCACHED_SUCCESS) + rc= MEMCACHED_SOME_ERRORS; + } + + return rc; +} diff --git a/libmemcached/memcached_version.c b/libmemcached/memcached_version.c new file mode 100644 index 00000000..e49d76f0 --- /dev/null +++ b/libmemcached/memcached_version.c @@ -0,0 +1,49 @@ +#include "common.h" + +const char * memcached_lib_version(void) +{ + return LIBMEMCACHED_VERSION_STRING; +} + +memcached_return memcached_version(memcached_st *ptr) +{ + unsigned int x; + size_t send_length; + memcached_return rc; + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + char *response_ptr; + char *command= "version\r\n"; + + send_length= strlen(command); + + rc= MEMCACHED_SUCCESS; + for (x= 0; x < ptr->number_of_hosts; x++) + { + memcached_return rrc; + + rrc= memcached_do(&ptr->hosts[x], command, send_length, 1); + if (rrc != MEMCACHED_SUCCESS) + { + rc= MEMCACHED_SOME_ERRORS; + continue; + } + + rrc= memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); + if (rrc != MEMCACHED_SUCCESS) + rc= MEMCACHED_SOME_ERRORS; + + /* Find the space, and then move one past it to copy version */ + response_ptr= index(buffer, ' '); + response_ptr++; + + ptr->hosts[x].major_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10); + response_ptr= index(response_ptr, '.'); + response_ptr++; + ptr->hosts[x].minor_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10); + response_ptr= index(response_ptr, '.'); + response_ptr++; + ptr->hosts[x].micro_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10); + } + + return rc; +} diff --git a/libmemcached/murmur_hash.c b/libmemcached/murmur_hash.c new file mode 100644 index 00000000..abb2deda --- /dev/null +++ b/libmemcached/murmur_hash.c @@ -0,0 +1,48 @@ +#include "common.h" + +/* + "Murmur"hash provided by Austin, tanjent@gmail.com +#define MURMUR_POSTMIX +*/ + +uint32_t murmur_hash(char *key, size_t length) +{ + const unsigned int m= 0x7fd652ad; + const int r= 16; + + uint32_t h= 0xdeadbeef; + + while(length >= 4) + { + h += *(unsigned int *)key; + h *= m; + h ^= h >> r; + + key += 4; + length -= 4; + } + + switch(length) + { + case 3: + h += key[2] << 16; + case 2: + h += key[1] << 8; + case 1: + default: + h += key[0]; + h *= m; + h ^= h >> r; + }; + +#ifdef MURMUR_POSTMIX + + h *= m; + h ^= h >> 10; + h *= m; + h ^= h >> 17; + +#endif + + return h; +} diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 004f2e1a..00000000 --- a/src/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -INCLUDES = -I$(top_builddir)/include -LDADDS = $(top_builddir)/lib/libmemcached.la - -bin_PROGRAMS = memcat memcp memstat memrm memflush memslap memerror - -noinst_HEADERS = client_options.h \ - utilities.h \ - generator.h \ - execute.h - -memcat_SOURCES = memcat.c utilities.c -memcat_LDADD = $(LDADDS) -memcat_LDFLAGS = -rpath $(pkglibdir) - -memcp_SOURCES = memcp.c utilities.c -memcp_LDADD = $(LDADDS) -memcp_LDFLAGS = -rpath $(pkglibdir) - -memstat_SOURCES = memstat.c utilities.c -memstat_LDADD = $(LDADDS) -memstat_LDFLAGS = -rpath $(pkglibdir) - -memrm_SOURCES = memrm.c utilities.c -memrm_LDADD = $(LDADDS) -memrm_LDFLAGS = -rpath $(pkglibdir) - -memflush_SOURCES = memflush.c utilities.c -memflush_LDADD = $(LDADDS) -memflush_LDFLAGS = -rpath $(pkglibdir) - - -memerror_SOURCES = memerror.c utilities.c -memerror_LDADD = $(LDADDS) -memerror_LDFLAGS = -rpath $(pkglibdir) - -memslap_SOURCES = memslap.c utilities.c generator.c execute.c -memslap_LDADD = $(LDADDS) -lpthread -memslap_LDFLAGS = -rpath $(pkglibdir) diff --git a/src/client_options.h b/src/client_options.h deleted file mode 100644 index b7ba5a96..00000000 --- a/src/client_options.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __CLIENT_OPTIONS_H__ -#define __CLIENT_OPTIONS_H__ - -typedef struct memcached_help_text_st memcached_help_text_st; - -typedef enum { - OPT_SERVERS= 's', - OPT_VERSION= 'V', - OPT_HELP= 'h', - OPT_VERBOSE= 'v', - OPT_DEBUG= 'd', - OPT_FLAG= 257, - OPT_EXPIRE, - OPT_SET, - OPT_REPLACE, - OPT_ADD, - OPT_SLAP_EXECUTE_NUMBER, - OPT_SLAP_INITIAL_LOAD, - OPT_SLAP_TEST, - OPT_SLAP_CONCURRENCY, - OPT_SLAP_NON_BLOCK, - OPT_SLAP_TCP_NODELAY, - OPT_FLUSH, - OPT_HASH, -} memcached_options; - -#endif /* CLIENT_OPTIONS */ diff --git a/src/execute.c b/src/execute.c deleted file mode 100644 index e623825c..00000000 --- a/src/execute.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - Execute a memcached_set() a set of pairs. - Return the number of rows set. -*/ - -#include -#include "execute.h" - -unsigned int execute_set(memcached_st *memc, pairs_st *pairs, unsigned int number_of) -{ - memcached_return rc; - unsigned int x; - unsigned int pairs_sent; - - for (x= 0, pairs_sent= 0; x < number_of; x++) - { - rc= memcached_set(memc, pairs[x].key, pairs[x].key_length, - pairs[x].value, pairs[x].value_length, - 0, 0); - if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED) - fprintf(stderr, "Failured on insert of %.*s\n", - (unsigned int)pairs[x].key_length, pairs[x].key); - else - pairs_sent++; - } - - return pairs_sent; -} - -/* - Execute a memcached_get() on a set of pairs. - Return the number of rows retrieved. -*/ -unsigned int execute_get(memcached_st *memc, pairs_st *pairs, unsigned int number_of) -{ - memcached_return rc; - unsigned int x; - unsigned int retrieved; - - - for (retrieved= 0,x= 0; x < number_of; x++) - { - char *value; - size_t value_length; - uint32_t flags; - unsigned int fetch_key; - - fetch_key= random() % number_of; - - value= memcached_get(memc, pairs[fetch_key].key, pairs[fetch_key].key_length, - &value_length, &flags, &rc); - - if (rc != MEMCACHED_SUCCESS) - fprintf(stderr, "Failured on read of %.*s\n", - (unsigned int)pairs[fetch_key].key_length, pairs[fetch_key].key); - else - retrieved++; - - free(value); - } - - return retrieved; -} diff --git a/src/execute.h b/src/execute.h deleted file mode 100644 index fc041312..00000000 --- a/src/execute.h +++ /dev/null @@ -1,5 +0,0 @@ -#include -#include "generator.h" - -unsigned int execute_set(memcached_st *memc, pairs_st *pairs, unsigned int number_of); -unsigned int execute_get(memcached_st *memc, pairs_st *pairs, unsigned int number_of); diff --git a/src/generator.c b/src/generator.c deleted file mode 100644 index 793157ef..00000000 --- a/src/generator.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include - -#include "generator.h" - -/* Use this for string generation */ -static const char ALPHANUMERICS[]= - "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz"; - -#define ALPHANUMERICS_SIZE (sizeof(ALPHANUMERICS)-1) - -static void get_random_string(char *buffer, size_t size) -{ - char *buffer_ptr= buffer; - - while (--size) - *buffer_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE]; - *buffer_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE]; -} - -void pairs_free(pairs_st *pairs) -{ - unsigned int x; - - if (!pairs) - return; - - /* We free until we hit the null pair we stores during creation */ - for (x= 0; pairs[x].key; x++) - { - free(pairs[x].key); - free(pairs[x].value); - } - - free(pairs); -} - -pairs_st *pairs_generate(unsigned long long number_of, size_t value_length) -{ - unsigned int x; - pairs_st *pairs; - - pairs= (pairs_st*)malloc(sizeof(pairs_st) * (number_of+1)); - - if (!pairs) - goto error; - - memset(pairs, 0, sizeof(pairs_st) * (number_of+1)); - - for (x= 0; x < number_of; x++) - { - pairs[x].key= (char *)malloc(sizeof(char) * 100); - if (!pairs[x].key) - goto error; - get_random_string(pairs[x].key, 100); - pairs[x].key_length= 100; - - pairs[x].value= (char *)malloc(sizeof(char) * value_length); - if (!pairs[x].value) - goto error; - get_random_string(pairs[x].value, value_length); - pairs[x].value_length= value_length; - } - - return pairs; -error: - fprintf(stderr, "Memory Allocation failure in pairs_generate.\n"); - exit(0); -} diff --git a/src/generator.h b/src/generator.h deleted file mode 100644 index c3fcab32..00000000 --- a/src/generator.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - Code to generate data to be pushed into memcached -*/ - -#ifndef __GENERATOR_H__ -#define __GENERATOR_H__ - -typedef struct pairs_st pairs_st; - -struct pairs_st { - char *key; - size_t key_length; - char *value; - size_t value_length; -}; - -pairs_st *pairs_generate(unsigned long long number_of, size_t length); -void pairs_free(pairs_st *pairs); - -#endif diff --git a/src/memcat.c b/src/memcat.c deleted file mode 100644 index 7d2c14db..00000000 --- a/src/memcat.c +++ /dev/null @@ -1,152 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "utilities.h" - -#define PROGRAM_NAME "memcat" -#define PROGRAM_DESCRIPTION "Cat a set of key values to stdout." - - -/* Prototypes */ -void options_parse(int argc, char *argv[]); - -static int opt_verbose= 0; -static int opt_displayflag= 0; -static char *opt_servers= NULL; -static char *opt_hash= NULL; - -int main(int argc, char *argv[]) -{ - memcached_st *memc; - char *string; - size_t string_length; - uint32_t flags; - memcached_return rc; - memcached_server_st *servers; - - options_parse(argc, argv); - - if (!opt_servers) - { - char *temp; - - if ((temp= getenv("MEMCACHED_SERVERS"))) - opt_servers= strdup(temp); - else - { - fprintf(stderr, "No Servers provided\n"); - exit(1); - } - } - - memc= memcached_create(NULL); - process_hash_option(memc, opt_hash); - - servers= memcached_servers_parse(opt_servers); - - memcached_server_push(memc, servers); - memcached_server_list_free(servers); - - while (optind < argc) - { - string= memcached_get(memc, argv[optind], strlen(argv[optind]), - &string_length, &flags, &rc); - if (rc == MEMCACHED_SUCCESS) - { - if (opt_displayflag) - { - if (opt_verbose) - printf("key: %s\nflags: ", argv[optind]); - printf("%x\n", flags); - } - else - { - if (opt_verbose) - printf("key: %s\nflags: %x\nlength: %zu\nvalue: ", - argv[optind], flags, string_length); - printf("%.*s\n", (int)string_length, string); - free(string); - } - } - else if (rc != MEMCACHED_NOTFOUND) - { - fprintf(stderr, "memcat: %s: memcache error %s", - argv[optind], memcached_strerror(memc, rc)); - if (memc->cached_errno) - fprintf(stderr, " system error %s", strerror(memc->cached_errno)); - fprintf(stderr, "\n"); - } - optind++; - } - - memcached_free(memc); - - if (opt_servers) - free(opt_servers); - if (opt_hash) - free(opt_hash); - - return 0; -} - - -void options_parse(int argc, char *argv[]) -{ - int option_index= 0; - int option_rv; - - memcached_programs_help_st help_options[]= - { - {0}, - }; - - static struct option long_options[]= - { - {"version", no_argument, NULL, OPT_VERSION}, - {"help", no_argument, NULL, OPT_HELP}, - {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, - {"debug", no_argument, &opt_verbose, OPT_DEBUG}, - {"servers", required_argument, NULL, OPT_SERVERS}, - {"flag", no_argument, &opt_displayflag, OPT_FLAG}, - {"hash", required_argument, NULL, OPT_HASH}, - {0, 0, 0, 0}, - }; - - while (1) - { - option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); - if (option_rv == -1) break; - switch (option_rv) - { - case 0: - break; - case OPT_VERBOSE: /* --verbose or -v */ - opt_verbose = OPT_VERBOSE; - break; - case OPT_DEBUG: /* --debug or -d */ - opt_verbose = OPT_DEBUG; - break; - case OPT_VERSION: /* --version or -V */ - version_command(PROGRAM_NAME); - break; - case OPT_HELP: /* --help or -h */ - help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); - break; - case OPT_SERVERS: /* --servers or -s */ - opt_servers= strdup(optarg); - break; - case OPT_HASH: - opt_hash= strdup(optarg); - break; - case '?': - /* getopt_long already printed an error message. */ - exit(1); - default: - abort(); - } - } -} diff --git a/src/memcp.c b/src/memcp.c deleted file mode 100644 index cbdbf449..00000000 --- a/src/memcp.c +++ /dev/null @@ -1,222 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "client_options.h" -#include "utilities.h" - -#define PROGRAM_NAME "memcp" -#define PROGRAM_DESCRIPTION "Copy a set of files to a memcached cluster." - -/* Prototypes */ -void options_parse(int argc, char *argv[]); - -static int opt_verbose= 0; -static char *opt_servers= NULL; -static char *opt_hash= NULL; -static int opt_method= OPT_SET; -static uint32_t opt_flags= 0; -static time_t opt_expires= 0; - -int main(int argc, char *argv[]) -{ - memcached_st *memc; - memcached_return rc; - memcached_server_st *servers; - - options_parse(argc, argv); - - memc= memcached_create(NULL); - process_hash_option(memc, opt_hash); - - if (!opt_servers) - { - char *temp; - - if ((temp= getenv("MEMCACHED_SERVERS"))) - opt_servers= strdup(temp); - else - { - fprintf(stderr, "No Servers provided\n"); - exit(1); - } - } - - if (opt_servers) - servers= memcached_servers_parse(opt_servers); - else - servers= memcached_servers_parse(argv[--argc]); - - memcached_server_push(memc, servers); - memcached_server_list_free(servers); - - while (optind < argc) - { - struct stat sbuf; - int fd; - char *ptr; - ssize_t read_length; - char *file_buffer_ptr; - - fd= open(argv[optind], O_RDONLY); - if (fd < 0) - { - fprintf(stderr, "memcp: %s: %s\n", argv[optind], strerror(errno)); - optind++; - continue; - } - - (void)fstat(fd, &sbuf); - - ptr= rindex(argv[optind], '/'); - if (ptr) - ptr++; - else - ptr= argv[optind]; - - if (opt_verbose) - { - static char *opstr[] = { "set", "add", "replace" }; - printf("op: %s\nsource file: %s\nlength: %zu\n" - "key: %s\nflags: %x\nexpires: %llu\n", - opstr[opt_method - OPT_SET], argv[optind], (size_t)sbuf.st_size, - ptr, opt_flags, (unsigned long long)opt_expires); - } - - if ((file_buffer_ptr= (char *)malloc(sizeof(char) * sbuf.st_size)) == NULL) - { - fprintf(stderr, "malloc: %s\n", strerror(errno)); - exit(1); - } - - if ((read_length= read(fd, file_buffer_ptr, sbuf.st_size)) == -1) - { - fprintf(stderr, "read: %s\n", strerror(errno)); - exit(1); - } - assert(read_length == sbuf.st_size); - - if (opt_method == OPT_ADD) - rc= memcached_add(memc, ptr, strlen(ptr), - file_buffer_ptr, sbuf.st_size, - opt_expires, opt_flags); - else if (opt_method == OPT_REPLACE) - rc= memcached_replace(memc, ptr, strlen(ptr), - file_buffer_ptr, sbuf.st_size, - opt_expires, opt_flags); - else - rc= memcached_set(memc, ptr, strlen(ptr), - file_buffer_ptr, sbuf.st_size, - opt_expires, opt_flags); - - if (rc != MEMCACHED_SUCCESS) - { - fprintf(stderr, "memcp: %s: memcache error %s", - ptr, memcached_strerror(memc, rc)); - if (memc->cached_errno) - fprintf(stderr, " system error %s", strerror(memc->cached_errno)); - fprintf(stderr, "\n"); - } - - free(file_buffer_ptr); - close(fd); - optind++; - } - - memcached_free(memc); - - if (opt_servers) - free(opt_servers); - if (opt_hash) - free(opt_hash); - - return 0; -} - -void options_parse(int argc, char *argv[]) -{ - int option_index= 0; - int option_rv; - - memcached_programs_help_st help_options[]= - { - {0}, - }; - - static struct option long_options[]= - { - {"version", no_argument, NULL, OPT_VERSION}, - {"help", no_argument, NULL, OPT_HELP}, - {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, - {"debug", no_argument, &opt_verbose, OPT_DEBUG}, - {"servers", required_argument, NULL, OPT_SERVERS}, - {"flag", required_argument, NULL, OPT_FLAG}, - {"expire", required_argument, NULL, OPT_EXPIRE}, - {"set", no_argument, NULL, OPT_SET}, - {"add", no_argument, NULL, OPT_ADD}, - {"replace", no_argument, NULL, OPT_REPLACE}, - {"hash", required_argument, NULL, OPT_HASH}, - {0, 0, 0, 0}, - }; - - while (1) - { - option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); - - if (option_rv == -1) break; - - switch (option_rv) - { - case 0: - break; - case OPT_VERBOSE: /* --verbose or -v */ - opt_verbose = OPT_VERBOSE; - break; - case OPT_DEBUG: /* --debug or -d */ - opt_verbose = OPT_DEBUG; - break; - case OPT_VERSION: /* --version or -V */ - version_command(PROGRAM_NAME); - break; - case OPT_HELP: /* --help or -h */ - help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); - break; - case OPT_SERVERS: /* --servers or -s */ - opt_servers= strdup(optarg); - break; - case OPT_FLAG: /* --flag */ - opt_flags= (uint32_t)strtol(optarg, (char **)NULL, 16); - break; - case OPT_EXPIRE: /* --expire */ - opt_expires= (time_t)strtoll(optarg, (char **)NULL, 10); - break; - case OPT_SET: - opt_method= OPT_SET; - break; - case OPT_REPLACE: - opt_method= OPT_REPLACE; - break; - case OPT_ADD: - opt_method= OPT_ADD; - case OPT_HASH: - opt_hash= strdup(optarg); - break; - case '?': - /* getopt_long already printed an error message. */ - exit(1); - default: - abort(); - } - } -} diff --git a/src/memerror.c b/src/memerror.c deleted file mode 100644 index f6cf1aba..00000000 --- a/src/memerror.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "utilities.h" - -#define PROGRAM_NAME "memerror" -#define PROGRAM_DESCRIPTION "Translate a memcached errror code into a string." - - -/* Prototypes */ -void options_parse(int argc, char *argv[]); - -static int opt_verbose= 0; - -int main(int argc, char *argv[]) -{ - options_parse(argc, argv); - - if (argc != 2) - return 1; - - printf("%s\n", memcached_strerror(NULL, atoi(argv[1]))); - - return 0; -} - - -void options_parse(int argc, char *argv[]) -{ - int option_index= 0; - int option_rv; - - memcached_programs_help_st help_options[]= - { - {0}, - }; - - static struct option long_options[]= - { - {"version", no_argument, NULL, OPT_VERSION}, - {"help", no_argument, NULL, OPT_HELP}, - {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, - {"debug", no_argument, &opt_verbose, OPT_DEBUG}, - {0, 0, 0, 0}, - }; - - while (1) - { - option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); - if (option_rv == -1) break; - switch (option_rv) - { - case 0: - break; - case OPT_VERBOSE: /* --verbose or -v */ - opt_verbose = OPT_VERBOSE; - break; - case OPT_DEBUG: /* --debug or -d */ - opt_verbose = OPT_DEBUG; - break; - case OPT_VERSION: /* --version or -V */ - version_command(PROGRAM_NAME); - break; - case OPT_HELP: /* --help or -h */ - help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); - break; - case '?': - /* getopt_long already printed an error message. */ - exit(1); - default: - abort(); - } - } -} diff --git a/src/memflush.c b/src/memflush.c deleted file mode 100644 index ed3a5f81..00000000 --- a/src/memflush.c +++ /dev/null @@ -1,117 +0,0 @@ -#include -#include -#include -#include -#include -#include "client_options.h" -#include "utilities.h" - -static int opt_verbose= 0; -static time_t opt_expire= 0; -static char *opt_servers= NULL; - -#define PROGRAM_NAME "memflush" -#define PROGRAM_DESCRIPTION "Erase all data in a server of memcached servers." - -/* Prototypes */ -void options_parse(int argc, char *argv[]); - -int main(int argc, char *argv[]) -{ - memcached_st *memc; - memcached_return rc; - memcached_server_st *servers; - - options_parse(argc, argv); - - if (!opt_servers) - { - char *temp; - - if ((temp= getenv("MEMCACHED_SERVERS"))) - opt_servers= strdup(temp); - else - { - fprintf(stderr, "No Servers provided\n"); - exit(1); - } - } - - memc= memcached_create(NULL); - - servers= memcached_servers_parse(opt_servers); - memcached_server_push(memc, servers); - memcached_server_list_free(servers); - - rc = memcached_flush(memc, opt_expire); - if (rc != MEMCACHED_SUCCESS) - { - fprintf(stderr, "memflush: memcache error %s", - memcached_strerror(memc, rc)); - if (memc->cached_errno) - fprintf(stderr, " system error %s", strerror(memc->cached_errno)); - fprintf(stderr, "\n"); - } - - memcached_free(memc); - - free(opt_servers); - - return 0; -} - - -void options_parse(int argc, char *argv[]) -{ - memcached_programs_help_st help_options[]= - { - {0}, - }; - - static struct option long_options[]= - { - {"version", no_argument, NULL, OPT_VERSION}, - {"help", no_argument, NULL, OPT_HELP}, - {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, - {"debug", no_argument, &opt_verbose, OPT_DEBUG}, - {"servers", required_argument, NULL, OPT_SERVERS}, - {"expire", required_argument, NULL, OPT_EXPIRE}, - {0, 0, 0, 0}, - }; - int option_index= 0; - int option_rv; - - while (1) - { - option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); - if (option_rv == -1) break; - switch (option_rv) - { - case 0: - break; - case OPT_VERBOSE: /* --verbose or -v */ - opt_verbose = OPT_VERBOSE; - break; - case OPT_DEBUG: /* --debug or -d */ - opt_verbose = OPT_DEBUG; - break; - case OPT_VERSION: /* --version or -V */ - version_command(PROGRAM_NAME); - break; - case OPT_HELP: /* --help or -h */ - help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); - break; - case OPT_SERVERS: /* --servers or -s */ - opt_servers= strdup(optarg); - break; - case OPT_EXPIRE: /* --expire */ - opt_expire= (time_t)strtoll(optarg, (char **)NULL, 10); - break; - case '?': - /* getopt_long already printed an error message. */ - exit(1); - default: - abort(); - } - } -} diff --git a/src/memrm.c b/src/memrm.c deleted file mode 100644 index 7b774d72..00000000 --- a/src/memrm.c +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include -#include -#include -#include -#include "client_options.h" -#include "utilities.h" - -static int opt_verbose= 0; -static time_t opt_expire= 0; -static char *opt_servers= NULL; -static char *opt_hash= NULL; - -#define PROGRAM_NAME "memrm" -#define PROGRAM_DESCRIPTION "Erase a key or set of keys from a memcached cluster." - -/* Prototypes */ -void options_parse(int argc, char *argv[]); - -int main(int argc, char *argv[]) -{ - memcached_st *memc; - memcached_return rc; - memcached_server_st *servers; - - options_parse(argc, argv); - - if (!opt_servers) - { - char *temp; - - if ((temp= getenv("MEMCACHED_SERVERS"))) - opt_servers= strdup(temp); - else - { - fprintf(stderr, "No Servers provided\n"); - exit(1); - } - } - - memc= memcached_create(NULL); - process_hash_option(memc, opt_hash); - - servers= memcached_servers_parse(opt_servers); - memcached_server_push(memc, servers); - memcached_server_list_free(servers); - - while (optind < argc) - { - if (opt_verbose) - printf("key: %s\nexpires: %llu\n", argv[optind], (unsigned long long)opt_expire); - rc = memcached_delete(memc, argv[optind], strlen(argv[optind]), opt_expire); - - if (rc != MEMCACHED_SUCCESS) - { - fprintf(stderr, "memrm: %s: memcache error %s", - argv[optind], memcached_strerror(memc, rc)); - if (memc->cached_errno) - fprintf(stderr, " system error %s", strerror(memc->cached_errno)); - fprintf(stderr, "\n"); - } - - optind++; - } - - memcached_free(memc); - - if (opt_servers) - free(opt_servers); - if (opt_hash) - free(opt_hash); - - return 0; -} - - -void options_parse(int argc, char *argv[]) -{ - memcached_programs_help_st help_options[]= - { - {0}, - }; - - static struct option long_options[]= - { - {"version", no_argument, NULL, OPT_VERSION}, - {"help", no_argument, NULL, OPT_HELP}, - {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, - {"debug", no_argument, &opt_verbose, OPT_DEBUG}, - {"servers", required_argument, NULL, OPT_SERVERS}, - {"expire", required_argument, NULL, OPT_EXPIRE}, - {"hash", required_argument, NULL, OPT_HASH}, - {0, 0, 0, 0}, - }; - int option_index= 0; - int option_rv; - - while (1) - { - option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); - if (option_rv == -1) break; - switch (option_rv) - { - case 0: - break; - case OPT_VERBOSE: /* --verbose or -v */ - opt_verbose = OPT_VERBOSE; - break; - case OPT_DEBUG: /* --debug or -d */ - opt_verbose = OPT_DEBUG; - break; - case OPT_VERSION: /* --version or -V */ - version_command(PROGRAM_NAME); - break; - case OPT_HELP: /* --help or -h */ - help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); - break; - case OPT_SERVERS: /* --servers or -s */ - opt_servers= strdup(optarg); - break; - case OPT_EXPIRE: /* --expire */ - opt_expire= (time_t)strtoll(optarg, (char **)NULL, 10); - break; - case OPT_HASH: - opt_hash= strdup(optarg); - break; - case '?': - /* getopt_long already printed an error message. */ - exit(1); - default: - abort(); - } - } -} diff --git a/src/memslap.c b/src/memslap.c deleted file mode 100644 index 899d8b81..00000000 --- a/src/memslap.c +++ /dev/null @@ -1,388 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "client_options.h" -#include "utilities.h" -#include "generator.h" -#include "execute.h" - -#define DEFAULT_INITIAL_LOAD 10000 -#define DEFAULT_EXECUTE_NUMBER 10000 -#define DEFAULT_CONCURRENCY 1 - -#define PROGRAM_NAME "memslap" -#define PROGRAM_DESCRIPTION "Generates a load against a memcached custer of servers." - -/* Global Thread counter */ -volatile unsigned int thread_counter; -pthread_mutex_t counter_mutex; -pthread_cond_t count_threshhold; -volatile unsigned int master_wakeup; -pthread_mutex_t sleeper_mutex; -pthread_cond_t sleep_threshhold; - -void *run_task(void *p); - -/* Types */ -typedef struct conclusions_st conclusions_st; -typedef struct thread_context_st thread_context_st; -typedef enum { - SET_TEST, - GET_TEST, -} test_type; - -struct thread_context_st { - unsigned int key_count; - pairs_st *initial_pairs; - unsigned int initial_number; - pairs_st *execute_pairs; - unsigned int execute_number; - test_type test; - memcached_st *memc; -}; - -struct conclusions_st { - long int load_time; - long int read_time; - unsigned int rows_loaded; - unsigned int rows_read; -}; - -/* Prototypes */ -void options_parse(int argc, char *argv[]); -void conclusions_print(conclusions_st *conclusion); -void scheduler(memcached_server_st *servers, conclusions_st *conclusion); -pairs_st *load_create_data(memcached_st *memc, unsigned int number_of, - unsigned int *actual_loaded); -void flush_all(memcached_st *memc); - -static int opt_verbose= 0; -static int opt_flush= 0; -static int opt_non_blocking_io= 0; -static int opt_tcp_nodelay= 0; -static unsigned int opt_execute_number= 0; -static unsigned int opt_createial_load= 0; -static unsigned int opt_concurrency= 0; -static int opt_displayflag= 0; -static char *opt_servers= NULL; -test_type opt_test= SET_TEST; - -int main(int argc, char *argv[]) -{ - conclusions_st conclusion; - memcached_server_st *servers; - - memset(&conclusion, 0, sizeof(conclusions_st)); - - srandom(time(NULL)); - options_parse(argc, argv); - - if (!opt_servers) - { - char *temp; - - if ((temp= getenv("MEMCACHED_SERVERS"))) - opt_servers= strdup(temp); - else - { - fprintf(stderr, "No Servers provided\n"); - exit(1); - } - } - - servers= memcached_servers_parse(opt_servers); - - pthread_mutex_init(&counter_mutex, NULL); - pthread_cond_init(&count_threshhold, NULL); - pthread_mutex_init(&sleeper_mutex, NULL); - pthread_cond_init(&sleep_threshhold, NULL); - - scheduler(servers, &conclusion); - - free(opt_servers); - - (void)pthread_mutex_destroy(&counter_mutex); - (void)pthread_cond_destroy(&count_threshhold); - (void)pthread_mutex_destroy(&sleeper_mutex); - (void)pthread_cond_destroy(&sleep_threshhold); - conclusions_print(&conclusion); - memcached_server_list_free(servers); - - return 0; -} - -void scheduler(memcached_server_st *servers, conclusions_st *conclusion) -{ - unsigned int x; - unsigned int actual_loaded= 0; /* Fix warning */ - memcached_st *memc; - - struct timeval start_time, end_time; - pthread_t mainthread; /* Thread descriptor */ - pthread_attr_t attr; /* Thread attributes */ - pairs_st *pairs= NULL; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, - PTHREAD_CREATE_DETACHED); - - memc= memcached_create(NULL); - memcached_server_push(memc, servers); - - if (opt_flush) - flush_all(memc); - if (opt_createial_load) - pairs= load_create_data(memc, opt_createial_load, &actual_loaded); - - /* We set this after we have loaded */ - { - unsigned int value= 1; - if (opt_non_blocking_io) - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &value); - if (opt_tcp_nodelay) - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &value); - } - - - pthread_mutex_lock(&counter_mutex); - thread_counter= 0; - - pthread_mutex_lock(&sleeper_mutex); - master_wakeup= 1; - pthread_mutex_unlock(&sleeper_mutex); - - for (x= 0; x < opt_concurrency; x++) - { - thread_context_st *context; - context= (thread_context_st *)malloc(sizeof(thread_context_st)); - memset(context, 0, sizeof(thread_context_st)); - - context->memc= memcached_clone(NULL, memc); - context->test= opt_test; - - context->initial_pairs= pairs; - context->initial_number= actual_loaded; - - if (opt_test == SET_TEST) - { - context->execute_pairs= pairs_generate(opt_execute_number, 400); - context->execute_number= opt_execute_number; - } - - /* now you create the thread */ - if (pthread_create(&mainthread, &attr, run_task, - (void *)context) != 0) - { - fprintf(stderr,"Could not create thread\n"); - exit(1); - } - thread_counter++; - } - - pthread_mutex_unlock(&counter_mutex); - pthread_attr_destroy(&attr); - - pthread_mutex_lock(&sleeper_mutex); - master_wakeup= 0; - pthread_mutex_unlock(&sleeper_mutex); - pthread_cond_broadcast(&sleep_threshhold); - - gettimeofday(&start_time, NULL); - /* - We loop until we know that all children have cleaned up. - */ - pthread_mutex_lock(&counter_mutex); - while (thread_counter) - { - struct timespec abstime; - - memset(&abstime, 0, sizeof(struct timespec)); - abstime.tv_sec= 1; - - pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime); - } - pthread_mutex_unlock(&counter_mutex); - - gettimeofday(&end_time, NULL); - - conclusion->load_time= timedif(end_time, start_time); - conclusion->read_time= timedif(end_time, start_time); - pairs_free(pairs); -} - -void options_parse(int argc, char *argv[]) -{ - memcached_programs_help_st help_options[]= - { - {0}, - }; - - static struct option long_options[]= - { - {"concurrency", required_argument, NULL, OPT_SLAP_CONCURRENCY}, - {"debug", no_argument, &opt_verbose, OPT_DEBUG}, - {"execute-number", required_argument, NULL, OPT_SLAP_EXECUTE_NUMBER}, - {"flag", no_argument, &opt_displayflag, OPT_FLAG}, - {"flush", no_argument, &opt_flush, OPT_FLUSH}, - {"help", no_argument, NULL, OPT_HELP}, - {"initial-load", required_argument, NULL, OPT_SLAP_INITIAL_LOAD}, /* Number to load initially */ - {"non-blocking", no_argument, &opt_non_blocking_io, OPT_SLAP_NON_BLOCK}, - {"servers", required_argument, NULL, OPT_SERVERS}, - {"tcp-nodelay", no_argument, &opt_tcp_nodelay, OPT_SLAP_TCP_NODELAY}, - {"test", required_argument, NULL, OPT_SLAP_TEST}, - {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, - {"version", no_argument, NULL, OPT_VERSION}, - {0, 0, 0, 0}, - }; - - int option_index= 0; - int option_rv; - - while (1) - { - option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); - if (option_rv == -1) break; - switch (option_rv) - { - case 0: - break; - case OPT_VERBOSE: /* --verbose or -v */ - opt_verbose = OPT_VERBOSE; - break; - case OPT_DEBUG: /* --debug or -d */ - opt_verbose = OPT_DEBUG; - break; - case OPT_VERSION: /* --version or -V */ - version_command(PROGRAM_NAME); - break; - case OPT_HELP: /* --help or -h */ - help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); - break; - case OPT_SERVERS: /* --servers or -s */ - opt_servers= strdup(optarg); - break; - case OPT_SLAP_TEST: - if (!strcmp(optarg, "get")) - opt_test= GET_TEST ; - else if (!strcmp(optarg, "set")) - opt_test= SET_TEST; - else - { - fprintf(stderr, "Your test, %s, is not a known test\n", optarg); - exit(1); - } - break; - case OPT_SLAP_CONCURRENCY: - opt_concurrency= strtol(optarg, (char **)NULL, 10); - case OPT_SLAP_EXECUTE_NUMBER: - opt_execute_number= strtol(optarg, (char **)NULL, 10); - break; - case OPT_SLAP_INITIAL_LOAD: - opt_createial_load= strtol(optarg, (char **)NULL, 10); - break; - case '?': - /* getopt_long already printed an error message. */ - exit(1); - default: - abort(); - } - } - - if (opt_test == GET_TEST && opt_createial_load == 0) - opt_createial_load= DEFAULT_INITIAL_LOAD; - - if (opt_execute_number == 0) - opt_execute_number= DEFAULT_EXECUTE_NUMBER; - - if (opt_concurrency == 0) - opt_concurrency= DEFAULT_CONCURRENCY; -} - -void conclusions_print(conclusions_st *conclusion) -{ - printf("\tThreads connecting to servers %u\n", opt_concurrency); -#ifdef NOT_FINISHED - printf("\tLoaded %u rows\n", conclusion->rows_loaded); - printf("\tRead %u rows\n", conclusion->rows_read); -#endif - if (opt_test == SET_TEST) - printf("\tTook %ld.%03ld seconds to load data\n", conclusion->load_time / 1000, - conclusion->load_time % 1000); - else - printf("\tTook %ld.%03ld seconds to read data\n", conclusion->read_time / 1000, - conclusion->read_time % 1000); -} - -void *run_task(void *p) -{ - thread_context_st *context= (thread_context_st *)p; - memcached_st *memc; - - memc= context->memc; - - pthread_mutex_lock(&sleeper_mutex); - while (master_wakeup) - { - pthread_cond_wait(&sleep_threshhold, &sleeper_mutex); - } - pthread_mutex_unlock(&sleeper_mutex); - - /* Do Stuff */ - switch (context->test) - { - case SET_TEST: - execute_set(memc, context->execute_pairs, context->execute_number); - break; - case GET_TEST: - execute_get(memc, context->initial_pairs, context->initial_number); - break; - } - - memcached_free(memc); - - if (context->execute_pairs) - pairs_free(context->execute_pairs); - free(context); - - pthread_mutex_lock(&counter_mutex); - thread_counter--; - pthread_cond_signal(&count_threshhold); - pthread_mutex_unlock(&counter_mutex); - - return NULL; -} - -void flush_all(memcached_st *memc) -{ - memcached_flush(memc, 0); -} - -pairs_st *load_create_data(memcached_st *memc, unsigned int number_of, - unsigned int *actual_loaded) -{ - memcached_st *clone; - pairs_st *pairs; - - clone= memcached_clone(NULL, memc); - /* We always used non-blocking IO for load since it is faster */ - memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL ); - - pairs= pairs_generate(number_of, 400); - *actual_loaded= execute_set(clone, pairs, number_of); - - memcached_free(clone); - - return pairs; -} diff --git a/src/memstat.c b/src/memstat.c deleted file mode 100644 index 540d3f4f..00000000 --- a/src/memstat.c +++ /dev/null @@ -1,151 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "client_options.h" -#include "utilities.h" - -#define PROGRAM_NAME "memstat" -#define PROGRAM_DESCRIPTION "Output the state of a memcached cluster." - -/* Prototypes */ -void options_parse(int argc, char *argv[]); - -static int opt_verbose= 0; -static int opt_displayflag= 0; -static char *opt_servers= NULL; - -int main(int argc, char *argv[]) -{ - unsigned int x; - memcached_return rc; - memcached_st *memc; - memcached_stat_st *stat; - memcached_server_st *servers; - memcached_server_st *server_list; - - options_parse(argc, argv); - - if (!opt_servers) - { - char *temp; - - if ((temp= getenv("MEMCACHED_SERVERS"))) - opt_servers= strdup(temp); - else - { - fprintf(stderr, "No Servers provided\n"); - exit(1); - } - } - - memc= memcached_create(NULL); - - servers= memcached_servers_parse(opt_servers); - memcached_server_push(memc, servers); - memcached_server_list_free(servers); - - stat= memcached_stat(memc, NULL, &rc); - - if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_SOME_ERRORS) - { - printf("Failure to communicate with servers (%s)\n", - memcached_strerror(memc, rc)); - exit(1); - } - - server_list= memcached_server_list(memc); - - printf("Listing %u Server\n\n", memcached_server_count(memc)); - for (x= 0; x < memcached_server_count(memc); x++) - { - char **list; - char **ptr; - - list= memcached_stat_get_keys(memc, &stat[x], &rc); - assert(list); - assert(rc == MEMCACHED_SUCCESS); - - printf("Server: %s (%u)\n", memcached_server_name(memc, server_list[x]), - memcached_server_port(memc, server_list[x])); - for (ptr= list; *ptr; ptr++) - { - memcached_return rc; - char *value= memcached_stat_get_value(memc, &stat[x], *ptr, &rc); - - printf("\t %s: %s\n", *ptr, value); - free(value); - } - - free(list); - printf("\n"); - } - - free(stat); - free(opt_servers); - - memcached_free(memc); - - return 0; -} - -void options_parse(int argc, char *argv[]) -{ - memcached_programs_help_st help_options[]= - { - {0}, - }; - - static struct option long_options[]= - { - {"version", no_argument, NULL, OPT_VERSION}, - {"help", no_argument, NULL, OPT_HELP}, - {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, - {"debug", no_argument, &opt_verbose, OPT_DEBUG}, - {"servers", required_argument, NULL, OPT_SERVERS}, - {"flag", no_argument, &opt_displayflag, OPT_FLAG}, - {0, 0, 0, 0}, - }; - - int option_index= 0; - int option_rv; - - while (1) - { - option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); - if (option_rv == -1) break; - switch (option_rv) - { - case 0: - break; - case OPT_VERBOSE: /* --verbose or -v */ - opt_verbose = OPT_VERBOSE; - break; - case OPT_DEBUG: /* --debug or -d */ - opt_verbose = OPT_DEBUG; - break; - case OPT_VERSION: /* --version or -V */ - version_command(PROGRAM_NAME); - break; - case OPT_HELP: /* --help or -h */ - help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); - break; - case OPT_SERVERS: /* --servers or -s */ - opt_servers= strdup(optarg); - break; - case '?': - /* getopt_long already printed an error message. */ - exit(1); - default: - abort(); - } - } -} diff --git a/src/utilities.c b/src/utilities.c deleted file mode 100644 index 2a63f9e5..00000000 --- a/src/utilities.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include -#include "utilities.h" - - -long int timedif(struct timeval a, struct timeval b) -{ - register int us, s; - - us = a.tv_usec - b.tv_usec; - us /= 1000; - s = a.tv_sec - b.tv_sec; - s *= 1000; - return s + us; -} - -void version_command(char *command_name) -{ - printf("%s v%u.%u\n", command_name, 1, 0); - exit(0); -} - -char *lookup_help(memcached_options option) -{ - switch (option) - { - case OPT_SERVERS: return("List which servers you wish to connect to."); - case OPT_VERSION: return("Display the version of the application and then exit."); - case OPT_HELP: return("Diplay this message and then exit."); - case OPT_VERBOSE: return("Give more details on the progression of the application."); - case OPT_DEBUG: return("Provide output only useful for debugging."); - case OPT_FLAG: return("Provide flag information for storage operation."); - case OPT_EXPIRE: return("Set the expire option for the object."); - case OPT_SET: return("Use set command with memcached when storing."); - case OPT_REPLACE: return("Use replace command with memcached when storing."); - case OPT_ADD: return("Use add command with memcached when storing."); - case OPT_SLAP_EXECUTE_NUMBER: return("Number of times to execute the given test."); - case OPT_SLAP_INITIAL_LOAD: return("Number of key pairs to load before executing tests."); - case OPT_SLAP_TEST: return("Test to run."); - case OPT_SLAP_CONCURRENCY: return("Number of users to simulate with load."); - case OPT_SLAP_NON_BLOCK: return("Set TCP up to use non-blocking IO."); - case OPT_SLAP_TCP_NODELAY: return("Set TCP socket up to use nodelay."); - case OPT_FLUSH: return("Flush servers before running tests."); - case OPT_HASH: return("Select hash type."); - }; - - WATCHPOINT_ASSERT(0); - return "forgot to document this function :)"; -} - -void help_command(char *command_name, char *description, - const struct option *long_options, - memcached_programs_help_st *options) -{ - unsigned int x; - - printf("%s v%u.%u\n\n", command_name, 1, 0); - printf("\t%s\n\n", description); - printf("Current options. A '=' means the option takes a value.\n\n"); - - for (x= 0; long_options[x].name; x++) - { - char *help_message; - - printf("\t --%s%c\n", long_options[x].name, - long_options[x].has_arg ? '=' : ' '); - if ((help_message= lookup_help(long_options[x].val))) - printf("\t\t%s\n", help_message); - } - - printf("\n"); - exit(0); -} - -void process_hash_option(memcached_st *memc, char *opt_hash) -{ - uint64_t set; - memcached_return rc; - - if (opt_hash == NULL) - return; - - if (!strcasecmp(opt_hash, "CRC")) - set= MEMCACHED_HASH_CRC; - else if (!strcasecmp(opt_hash, "FNV1_64")) - set= MEMCACHED_HASH_FNV1_64; - else if (!strcasecmp(opt_hash, "FNV1A_64")) - set= MEMCACHED_HASH_FNV1A_64; - else if (!strcasecmp(opt_hash, "FNV1_32")) - set= MEMCACHED_HASH_FNV1_32; - else if (!strcasecmp(opt_hash, "FNV1A_32")) - set= MEMCACHED_HASH_FNV1A_32; - else if (!strcasecmp(opt_hash, "KETAMA")) - set= MEMCACHED_HASH_KETAMA; - else - { - fprintf(stderr, "hash: type not recognized %s\n", opt_hash); - exit(1); - } - - rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set); - if (rc != MEMCACHED_SUCCESS) - { - fprintf(stderr, "hash: memcache error %s\n", memcached_strerror(memc, rc)); - exit(1); - } -} - diff --git a/src/utilities.h b/src/utilities.h deleted file mode 100644 index 6d4d72d4..00000000 --- a/src/utilities.h +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include -#include "client_options.h" -#include "libmemcached_config.h" - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -typedef struct memcached_programs_help_st memcached_programs_help_st; - -struct memcached_programs_help_st -{ - char *not_used_yet; -}; - -char *strdup_cleanup(const char *str); -void cleanup(void); -long int timedif(struct timeval a, struct timeval b); -void version_command(char *command_name); -void help_command(char *command_name, char *description, - const struct option *long_options, - memcached_programs_help_st *options); -void process_hash_option(memcached_st *memc, char *opt_hash); diff --git a/tests/Makefile.am b/tests/Makefile.am index f23fde0b..664ce008 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,5 +1,5 @@ -INCLUDES = -I$(top_builddir)/include -I$(top_builddir)/lib -LDADDS = ../lib/libmemcached.la +INCLUDES = +LDADDS = $(top_builddir)/libmemcached/libmemcached.la EXTRA_DIST = output.res output2.res\ r/memcat.res\ @@ -18,7 +18,7 @@ LIBS = noinst_HEADERS = test.h server.h noinst_PROGRAMS = testapp testplus udptest atomsmasher startservers -testapp_SOURCES = test.c function.c ../src/generator.c ../src/execute.c server.c +testapp_SOURCES = test.c function.c server.c ../clients/generator.c ../clients/execute.c testapp_LDADD = $(LDADDS) testplus_SOURCES = test.c plus.cpp server.c @@ -27,7 +27,7 @@ testplus_LDADD = $(LDADDS) udptest_SOURCES = test.c udp.c server.c udptest_LDADD = $(LDADDS) -atomsmasher_SOURCES = test.c atomsmasher.c server.c ../src/generator.c ../src/execute.c +atomsmasher_SOURCES = test.c atomsmasher.c server.c ../clients/generator.c ../clients/execute.c atomsmasher_LDADD = $(LDADDS) startservers_SOURCES = start.c server.c diff --git a/tests/atomsmasher.c b/tests/atomsmasher.c index c4378877..a039fc4d 100644 --- a/tests/atomsmasher.c +++ b/tests/atomsmasher.c @@ -2,7 +2,7 @@ Sample test application. */ #include -#include +#include #include #include #include @@ -12,9 +12,9 @@ #include #include #include "server.h" -#include "../lib/common.h" -#include "../src/generator.h" -#include "../src/execute.h" +#include "../libmemcached/common.h" +#include "../clients/generator.h" +#include "../clients/execute.h" #ifndef INT64_MAX #define INT64_MAX LONG_MAX diff --git a/tests/function.c b/tests/function.c index 8d84c16f..f36110ea 100644 --- a/tests/function.c +++ b/tests/function.c @@ -2,7 +2,7 @@ Sample test application. */ #include -#include +#include #include #include #include @@ -12,9 +12,9 @@ #include #include #include "server.h" -#include "../lib/common.h" -#include "../src/generator.h" -#include "../src/execute.h" +#include "../libmemcached/common.h" +#include "../clients/generator.h" +#include "../clients/execute.h" #ifndef INT64_MAX #define INT64_MAX LONG_MAX diff --git a/tests/server.c b/tests/server.c index ce8db70b..58f45233 100644 --- a/tests/server.c +++ b/tests/server.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include "server.h" diff --git a/tests/test.h b/tests/test.h index 1c6b87be..0cbb5f0d 100644 --- a/tests/test.h +++ b/tests/test.h @@ -5,8 +5,8 @@ extern "C" { #endif -#include -#include "../lib/common.h" +#include +#include "../libmemcached/common.h" typedef struct world_st world_st; typedef struct collection_st collection_st; diff --git a/tests/udp.c b/tests/udp.c index df73b261..b6ad2065 100644 --- a/tests/udp.c +++ b/tests/udp.c @@ -2,7 +2,7 @@ Sample test application. */ #include -#include +#include #include #include #include