From 5ca41b85020ca9acbf5df62dc4af3557cda89f0e Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Wed, 19 Dec 2007 11:51:09 -0800 Subject: [PATCH] Multi branch work. --- docs/Makefile.am | 9 +- lib/Makefile.am | 1 + lib/memcached_multistorage.c | 328 +++++++++++++++++++++++++++++++++++ lib/memcached_storage.c | 2 +- tests/function.c | 21 ++- 5 files changed, 357 insertions(+), 4 deletions(-) create mode 100644 lib/memcached_multistorage.c diff --git a/docs/Makefile.am b/docs/Makefile.am index 2b0c4321..bfcf66ee 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -262,5 +262,10 @@ memflush.1: memflush.pod pod2man -c "libmemcached" -r "" -s 1 memflush.pod > memflush.1 clean: - rm *.1 - rm *.3 + rm -f *.1 + rm -f *.3 + +distclean: + rm -f *.1 + rm -f *.3 + rm -f Makefile diff --git a/lib/Makefile.am b/lib/Makefile.am index a6209369..0c632f0d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -40,6 +40,7 @@ libmemcached_la_SOURCES = crc.c \ memcached_hosts.c \ memcached_io.c \ md5.c \ + memcached_multistorage.c \ memcached_quit.c \ memcached_parse.c \ memcached_response.c \ diff --git a/lib/memcached_multistorage.c b/lib/memcached_multistorage.c new file mode 100644 index 00000000..da093c9d --- /dev/null +++ b/lib/memcached_multistorage.c @@ -0,0 +1,328 @@ +/* + 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 memcached_return memcached_msend(memcached_st *ptr, + char *master_key, size_t master_key_length, + char **key, size_t *key_length, + char **value, size_t *value_length, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags, + uint64_t cas, + memcached_storage_action verb) +{ + size_t write_length; + ssize_t sent_length; + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + unsigned int x; + unsigned int master_server_key= 0; + memcached_return rc= MEMCACHED_SUCCESS; + + WATCHPOINT_ASSERT(key && key_length && value && value_length); + + if (key_length == 0) + return MEMCACHED_NO_KEY_PROVIDED; + + if (ptr->number_of_hosts == 0) + return MEMCACHED_NO_SERVERS; + + if (master_key && master_key_length) + master_server_key= memcached_generate_hash(ptr, master_key, master_key_length); + + for (x= 0; x < number_of_keys; x++) + { + unsigned int server_key; + memcached_return tried; + + if (master_server_key) + server_key= master_server_key; + else + server_key= memcached_generate_hash(ptr, key[x], key_length[x]); + + + 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[x], key[x], flags, + (unsigned long long)expiration, value_length[x], + (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[x], key[x], flags, + (unsigned long long)expiration, value_length[x]); + + if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + goto error; + + tried= memcached_do(ptr, server_key, buffer, write_length, 0); + if (tried != MEMCACHED_SUCCESS) + goto error; + + if ((sent_length= memcached_io_write(ptr, server_key, value[x], value_length[x], 0)) == -1) + goto error; + + if ((sent_length= memcached_io_write(ptr, server_key, "\r\n", 2, 0)) == -1) + goto error; + + continue; + +error: + memcached_quit_server(ptr, server_key, 1); + continue; + } + + for (x= 0; x < ptr->number_of_hosts; x++) + { + if (memcached_server_response_count(ptr, x)) + { + /* We need to do something about non-connnected hosts in the future */ + if ((memcached_io_write(ptr, x, NULL, 0, 1)) == -1) + { + rc= MEMCACHED_SOME_ERRORS; + } + } + } + + return rc; +} + +memcached_return memcached_mset(memcached_st *ptr, + char **key, size_t *key_length, + char **value, size_t *value_length, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_SET_START(); + rc= memcached_msend(ptr, NULL, 0, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, 0, SET_OP); + LIBMEMCACHED_MEMCACHED_SET_END(); + return rc; +} + +memcached_return memcached_madd(memcached_st *ptr, + char **key, size_t *key_length, + char **value, size_t *value_length, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_ADD_START(); + rc= memcached_msend(ptr, NULL, 0, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, 0, ADD_OP); + LIBMEMCACHED_MEMCACHED_ADD_END(); + return rc; +} + +memcached_return memcached_mreplace(memcached_st *ptr, + char **key, size_t *key_length, + char **value, size_t *value_length, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_REPLACE_START(); + rc= memcached_msend(ptr, NULL, 0, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, 0, REPLACE_OP); + LIBMEMCACHED_MEMCACHED_REPLACE_END(); + return rc; +} + +memcached_return memcached_mprepend(memcached_st *ptr, + char **key, size_t *key_length, + char **value, size_t *value_length, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + rc= memcached_msend(ptr, NULL, 0, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, 0, PREPEND_OP); + return rc; +} + +memcached_return memcached_mappend(memcached_st *ptr, + char **key, size_t *key_length, + char **value, size_t *value_length, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + rc= memcached_msend(ptr, NULL, 0, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, 0, APPEND_OP); + return rc; +} + +memcached_return memcached_mcas(memcached_st *ptr, + char **key, size_t *key_length, + char **value, size_t *value_length, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags, + uint64_t cas) +{ + memcached_return rc; + rc= memcached_msend(ptr, NULL, 0, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, cas, APPEND_OP); + return rc; +} + +memcached_return memcached_mset_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, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_SET_START(); + rc= memcached_msend(ptr, master_key, master_key_length, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, 0, SET_OP); + LIBMEMCACHED_MEMCACHED_SET_END(); + return rc; +} + +memcached_return memcached_madd_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, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_ADD_START(); + rc= memcached_msend(ptr, master_key, master_key_length, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, 0, ADD_OP); + LIBMEMCACHED_MEMCACHED_ADD_END(); + return rc; +} + +memcached_return memcached_mreplace_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, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + LIBMEMCACHED_MEMCACHED_REPLACE_START(); + rc= memcached_msend(ptr, master_key, master_key_length, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, 0, REPLACE_OP); + LIBMEMCACHED_MEMCACHED_REPLACE_END(); + return rc; +} + +memcached_return memcached_mprepend_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, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + rc= memcached_msend(ptr, master_key, master_key_length, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, 0, PREPEND_OP); + return rc; +} + +memcached_return memcached_mappend_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, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags) +{ + memcached_return rc; + rc= memcached_msend(ptr, master_key, master_key_length, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, 0, APPEND_OP); + return rc; +} + +memcached_return memcached_mcas_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, + unsigned int number_of_keys, + time_t expiration, + uint32_t flags, + uint64_t cas) +{ + memcached_return rc; + rc= memcached_msend(ptr, master_key, master_key_length, + key, key_length, value, value_length, + number_of_keys, + expiration, flags, cas, APPEND_OP); + return rc; +} diff --git a/lib/memcached_storage.c b/lib/memcached_storage.c index 4c36edc6..43a96636 100644 --- a/lib/memcached_storage.c +++ b/lib/memcached_storage.c @@ -20,7 +20,7 @@ typedef enum { } memcached_storage_action; /* Inline this */ -char *storage_op_string(memcached_storage_action verb) +static char *storage_op_string(memcached_storage_action verb) { switch (verb) { diff --git a/tests/function.c b/tests/function.c index 5b598003..3b1e6d45 100644 --- a/tests/function.c +++ b/tests/function.c @@ -29,6 +29,8 @@ static pairs_st *global_pairs; static char *global_keys[GLOBAL_COUNT]; static size_t global_keys_length[GLOBAL_COUNT]; +static char *global_values[GLOBAL_COUNT]; +static size_t global_values_length[GLOBAL_COUNT]; uint8_t init_test(memcached_st *not_used) { @@ -1643,6 +1645,22 @@ uint8_t generate_data(memcached_st *memc) return 0; } +uint8_t mset_data(memcached_st *memc) +{ + unsigned long long x; + global_pairs= pairs_generate(GLOBAL_COUNT); + + (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0); + + for (x= 0; x < GLOBAL_COUNT; x++) + { + global_keys[x]= global_pairs[x].key; + global_keys_length[x]= global_pairs[x].key_length; + } + + return 0; +} + uint8_t get_read(memcached_st *memc) { unsigned int x; @@ -2036,10 +2054,11 @@ test_st user_tests[] ={ test_st generate_tests[] ={ {"generate_data", 0, generate_data }, {"get_read", 0, get_read }, + {"delete_generate", 0, delete_generate }, + {"generate_data", 0, generate_data }, {"mget_read", 0, mget_read }, {"mget_read_result", 0, mget_read_result }, {"mdelete_generate", 0, mdelete_generate }, - {"delete_generate", 0, delete_generate }, {"cleanup", 0, cleanup_pairs }, {0, 0, 0} }; -- 2.30.2