From d5ffc30a6f369ea210e92e6a55333121d32b9a55 Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Tue, 20 May 2008 17:57:36 -0700 Subject: [PATCH] MEMCACHED_CALLBACK_PREFIX_KEY added (so domaining keys is now aailable in the driver). --- ChangeLog | 2 ++ docs/memcached_callback.pod | 8 ++++++ libmemcached/memcached.c | 3 +++ libmemcached/memcached.h | 2 ++ libmemcached/memcached_auto.c | 3 ++- libmemcached/memcached_callback.c | 27 +++++++++++++++++++++ libmemcached/memcached_constants.h | 2 ++ libmemcached/memcached_delete.c | 8 ++++-- libmemcached/memcached_fetch.c | 15 +++++++++--- libmemcached/memcached_get.c | 11 +++++++++ libmemcached/memcached_storage.c | 6 +++-- tests/function.c | 39 +++++++++++++++++++++++++++++- 12 files changed, 116 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index f85b6295..4f3bffb5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 0.21 * Change of char * to const char * for all key based functions. + * New MEMCACHED_CALLBACK_PREFIX_KEY added. You can now create domains for + values. 0.20 Mon May 5 08:34:26 PDT 2008 * New consistent distribution tests. diff --git a/docs/memcached_callback.pod b/docs/memcached_callback.pod index a9c0ac41..9b56a5fc 100755 --- a/docs/memcached_callback.pod +++ b/docs/memcached_callback.pod @@ -47,6 +47,14 @@ point of its execution all connections have been closed. When memcached_delete() is called this function will be excuted. At the point of its execution all connections have been closed. +=item MEMCACHED_CALLBACK_PREFIX_KEY + +You can set a value which will be used to create a domain for your keys. +The value specified here will be appended to each of your keys. The value can not +be greater then MEMCACHED_PREFIX_KEY_MAX_SIZE and will reduce MEMCACHED_MAX_KEY by +the value of your key. The prefix key is only applied to the primary key, +not the master key. + =item MEMCACHED_CALLBACK_USER_DATA This allows you to store a pointer to a specifc piece of data. This can be diff --git a/libmemcached/memcached.c b/libmemcached/memcached.c index b681f6cb..74e75706 100644 --- a/libmemcached/memcached.c +++ b/libmemcached/memcached.c @@ -121,6 +121,9 @@ memcached_st *memcached_clone(memcached_st *clone, memcached_st *ptr) new_clone->get_key_failure= ptr->get_key_failure; new_clone->delete_trigger= ptr->delete_trigger; + if (ptr->prefix_key[0] != 0) + strcpy(new_clone->prefix_key, ptr->prefix_key); + rc= run_distribution(new_clone); if (rc != MEMCACHED_SUCCESS) { diff --git a/libmemcached/memcached.h b/libmemcached/memcached.h index b907809d..e753dc65 100644 --- a/libmemcached/memcached.h +++ b/libmemcached/memcached.h @@ -93,6 +93,8 @@ struct memcached_st { memcached_realloc_function call_realloc; memcached_trigger_key get_key_failure; memcached_trigger_delete_key delete_trigger; + char prefix_key[MEMCACHED_PREFIX_KEY_MAX_SIZE]; + size_t prefix_key_length; #ifdef NOT_USED /* Future Use */ uint8_t replicas; memcached_return warning; diff --git a/libmemcached/memcached_auto.c b/libmemcached/memcached_auto.c index bc6adc0f..b3eae3b6 100644 --- a/libmemcached/memcached_auto.c +++ b/libmemcached/memcached_auto.c @@ -23,7 +23,8 @@ static memcached_return memcached_auto(memcached_st *ptr, server_key= memcached_generate_hash(ptr, key, key_length); send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "%s %.*s %u\r\n", verb, + "%s %s%.*s %u\r\n", verb, + ptr->prefix_key, (int)key_length, key, offset); unlikely (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) diff --git a/libmemcached/memcached_callback.c b/libmemcached/memcached_callback.c index 6db2db82..c231716d 100644 --- a/libmemcached/memcached_callback.c +++ b/libmemcached/memcached_callback.c @@ -13,6 +13,28 @@ memcached_return memcached_callback_set(memcached_st *ptr, { switch (flag) { + case MEMCACHED_CALLBACK_PREFIX_KEY: + { + char *key= (char *)data; + + if (key) + { + ptr->prefix_key_length= strlen(key); + if ((ptr->prefix_key_length > MEMCACHED_PREFIX_KEY_MAX_SIZE -1) + || (strcpy(ptr->prefix_key, key) == NULL)) + { + ptr->prefix_key_length= 0; + return MEMCACHED_BAD_KEY_PROVIDED; + } + } + else + { + memset(ptr->prefix_key, 0, MEMCACHED_PREFIX_KEY_MAX_SIZE); + ptr->prefix_key_length= 0; + } + + break; + } case MEMCACHED_CALLBACK_USER_DATA: { ptr->user_data= data; @@ -77,6 +99,11 @@ void *memcached_callback_get(memcached_st *ptr, switch (flag) { + case MEMCACHED_CALLBACK_PREFIX_KEY: + { + *error= ptr->prefix_key[0] != 0 ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; + return (void *)ptr->prefix_key; + } case MEMCACHED_CALLBACK_USER_DATA: { *error= ptr->user_data ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; diff --git a/libmemcached/memcached_constants.h b/libmemcached/memcached_constants.h index f1dd52e9..f698cff6 100644 --- a/libmemcached/memcached_constants.h +++ b/libmemcached/memcached_constants.h @@ -24,6 +24,7 @@ extern "C" { #define MEMCACHED_STRIDE 4 #define MEMCACHED_DEFAULT_TIMEOUT 1000 #define MEMCACHED_CONTINUUM_ADDITION 10 /* How many extra slots we should build for in the continuum */ +#define MEMCACHED_PREFIX_KEY_MAX_SIZE 12 typedef enum { MEMCACHED_SUCCESS, @@ -89,6 +90,7 @@ typedef enum { } memcached_behavior; typedef enum { + MEMCACHED_CALLBACK_PREFIX_KEY, MEMCACHED_CALLBACK_USER_DATA, MEMCACHED_CALLBACK_CLEANUP_FUNCTION, MEMCACHED_CALLBACK_CLONE_FUNCTION, diff --git a/libmemcached/memcached_delete.c b/libmemcached/memcached_delete.c index 5df976ad..a105f552 100644 --- a/libmemcached/memcached_delete.c +++ b/libmemcached/memcached_delete.c @@ -30,11 +30,15 @@ memcached_return memcached_delete_by_key(memcached_st *ptr, if (expiration) send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "delete %.*s %llu\r\n", (int)key_length, key, + "delete %s%.*s %llu\r\n", + ptr->prefix_key, + (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); + "delete %s%.*s\r\n", + ptr->prefix_key, + (int)key_length, key); if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) { diff --git a/libmemcached/memcached_fetch.c b/libmemcached/memcached_fetch.c index 303e8cc3..2cefe65f 100644 --- a/libmemcached/memcached_fetch.c +++ b/libmemcached/memcached_fetch.c @@ -14,6 +14,7 @@ memcached_return value_fetch(memcached_server_st *ptr, size_t to_read; char *value_ptr; + WATCHPOINT_ASSERT(ptr->root); end_ptr= buffer + MEMCACHED_DEFAULT_COMMAND_SIZE; memcached_result_reset(result); @@ -25,15 +26,21 @@ memcached_return value_fetch(memcached_server_st *ptr, /* We load the key */ { char *key; + size_t prefix_length; key= result->key; result->key_length= 0; - for (; isgraph(*string_ptr); string_ptr++) + for (prefix_length= ptr->root->prefix_key_length; isgraph(*string_ptr); string_ptr++) { - *key= *string_ptr; - key++; - result->key_length++; + if (prefix_length == 0) + { + *key= *string_ptr; + key++; + result->key_length++; + } + else + prefix_length--; } result->key[result->key_length]= 0; } diff --git a/libmemcached/memcached_get.c b/libmemcached/memcached_get.c index a2f7716d..f6c81338 100644 --- a/libmemcached/memcached_get.c +++ b/libmemcached/memcached_get.c @@ -180,6 +180,17 @@ memcached_return memcached_mget_by_key(memcached_st *ptr, WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 1); } + /* Only called when we have a prefix key */ + if (ptr->prefix_key[0] != 0) + { + if ((memcached_io_write(&ptr->hosts[server_key], ptr->prefix_key, ptr->prefix_key_length, 0)) == -1) + { + memcached_server_response_reset(&ptr->hosts[server_key]); + rc= MEMCACHED_SOME_ERRORS; + continue; + } + } + if ((memcached_io_write(&ptr->hosts[server_key], keys[x], key_length[x], 0)) == -1) { memcached_server_response_reset(&ptr->hosts[server_key]); diff --git a/libmemcached/memcached_storage.c b/libmemcached/memcached_storage.c index 8f04c528..7dcc9b7a 100644 --- a/libmemcached/memcached_storage.c +++ b/libmemcached/memcached_storage.c @@ -72,13 +72,15 @@ static inline memcached_return memcached_send(memcached_st *ptr, if (cas) write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "%s %.*s %u %llu %zu %llu\r\n", storage_op_string(verb), + "%s %s%.*s %u %llu %zu %llu\r\n", storage_op_string(verb), + ptr->prefix_key, (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), + "%s %s%.*s %u %llu %zu\r\n", storage_op_string(verb), + ptr->prefix_key, (int)key_length, key, flags, (unsigned long long)expiration, value_length); diff --git a/tests/function.c b/tests/function.c index d3d23e47..5e371537 100644 --- a/tests/function.c +++ b/tests/function.c @@ -633,7 +633,7 @@ test_return read_through(memcached_st *memc) return 0; } -memcached_return delete_trigger(memcached_st *ptr, char *key, size_t key_length) +memcached_return delete_trigger(memcached_st *ptr, const char *key, size_t key_length) { assert(key); @@ -2463,6 +2463,42 @@ void *my_realloc(memcached_st *ptr, void *mem, const size_t size) return realloc(mem, size); } +memcached_return set_prefix(memcached_st *memc) +{ + memcached_return rc; + const char *key= "mine"; + char *value; + + /* Make sure be default none exists */ + value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc); + assert(rc == MEMCACHED_FAILURE); + + /* Test a clean set */ + rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key); + assert(rc == MEMCACHED_SUCCESS); + + value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc); + assert(memcmp(value, key, 4) == 0); + assert(rc == MEMCACHED_SUCCESS); + + /* Test that we can turn it off */ + rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL); + assert(rc == MEMCACHED_SUCCESS); + + value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc); + assert(rc == MEMCACHED_FAILURE); + + /* Now setup for main test */ + rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key); + assert(rc == MEMCACHED_SUCCESS); + + value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc); + assert(rc == MEMCACHED_SUCCESS); + assert(memcmp(value, key, 4) == 0); + + return MEMCACHED_SUCCESS; +} + memcached_return set_memory_alloc(memcached_st *memc) { { @@ -2758,6 +2794,7 @@ collection_st collection[] ={ {"consistent", enable_consistent, 0, tests}, {"wheel", enable_wheel, 0, tests}, {"memory_allocators", set_memory_alloc, 0, tests}, + {"prefix", set_prefix, 0, tests}, // {"udp", pre_udp, 0, tests}, {"version_1_2_3", check_for_1_2_3, 0, version_1_2_3}, {"string", 0, 0, string_tests}, -- 2.30.2