MEMCACHED_CALLBACK_PREFIX_KEY added (so domaining keys is now aailable in
authorBrian Aker <brian@tangent.org>
Wed, 21 May 2008 00:57:36 +0000 (17:57 -0700)
committerBrian Aker <brian@tangent.org>
Wed, 21 May 2008 00:57:36 +0000 (17:57 -0700)
the driver).

12 files changed:
ChangeLog
docs/memcached_callback.pod
libmemcached/memcached.c
libmemcached/memcached.h
libmemcached/memcached_auto.c
libmemcached/memcached_callback.c
libmemcached/memcached_constants.h
libmemcached/memcached_delete.c
libmemcached/memcached_fetch.c
libmemcached/memcached_get.c
libmemcached/memcached_storage.c
tests/function.c

index f85b6295d58dac1c6f17a3cc3bac435e6bd7afef..4f3bffb594ba6e6fc2a6565566f3d9c5894ba19e 100644 (file)
--- 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.
index a9c0ac417b570af4f8ac5458035edf25dbdd3c42..9b56a5fcf7f363c08018ce8741b491ec037176bb 100755 (executable)
@@ -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
index b681f6cb42d9c03e6b5ab457d9a93e1d76c2620c..74e75706875451277f9971a9a163d97155a54d8e 100644 (file)
@@ -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)
   {
index b907809da0fa5fe65312d1e496a8ae9484a9ed46..e753dc652a77e54c7e6c08facbbeab2a54659354 100644 (file)
@@ -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;
index bc6adc0f23f1f0f21524c89f784fc6a3a340846e..b3eae3b6119931ebe113882e8cddcaa82fe8bdf8 100644 (file)
@@ -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)
index 6db2db82d3dbe1e86329f33157ecdca339370bb6..c231716d9b8ca9a35dab5fe67519b27d8b24cd4b 100644 (file)
@@ -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;
index f1dd52e9ca2b2c5e1b14d71ef461f17267999592..f698cff63e436e1af43c49fbd449110530d9b5f4 100644 (file)
@@ -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,
index 5df976ad18919cccb16cab219fd8b545b14f68ef..a105f552e096a29be1075e2cfb3287ffe500faba 100644 (file)
@@ -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)
   {
index 303e8cc3ae4d68a7f5c4f31f1ad39099454e5fc3..2cefe65f21828dd7e39fffbddb473174be647de9 100644 (file)
@@ -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;
   }
index a2f7716d485d3e190b694899ef8074a487229c92..f6c81338a1bf817f376c789fb179756a1cafa658 100644 (file)
@@ -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]);
index 8f04c528e24ca24e4c6bfcfc6a0d707802c30b50..7dcc9b7a72b7d98a2f3be54c1221d13e91454b5f 100644 (file)
@@ -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);
 
index d3d23e4739eecb98cb28552b8201377b9cf79d3b..5e37153783d90b2a404338f76ad2da12a9c5a5d6 100644 (file)
@@ -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},