NEw string type.
author <brian@gir.tangent.org> <>
Wed, 26 Sep 2007 09:34:23 +0000 (02:34 -0700)
committer <brian@gir.tangent.org> <>
Wed, 26 Sep 2007 09:34:23 +0000 (02:34 -0700)
Better multi get keysupport.

include/memcached.h
lib/Makefile.am
lib/memcached_connect.c
lib/memcached_flush.c
lib/memcached_get.c
lib/memcached_stats.c
lib/memcached_string.c [new file with mode: 0644]

index fc732c2702adc1927f1d119a6f348931b5e83ec6..3e8cea8857d1489001ab0d8859ae812915da3945 100644 (file)
@@ -30,10 +30,12 @@ extern "C" {
 
 typedef struct memcached_st memcached_st;
 typedef struct memcached_stat_st memcached_stat_st;
+typedef struct memcached_string_st memcached_string_st;
 typedef struct memcached_host_st memcached_host_st;
 
 #define MEMCACHED_DEFAULT_PORT 11211
 #define MEMCACHED_DEFAULT_COMMAND_SIZE 350
+#define SMALL_STRING_LEN 1024
 #define HUGE_STRING_LEN 8196
 #define MEMCACHED_MAX_KEY 251 /* We add one to have it null terminated */
 
@@ -101,6 +103,13 @@ struct memcached_stat_st {
   unsigned int limit_maxbytes;
 };
 
+struct memcached_string_st {
+  char *string;
+  char *end;
+  size_t current_size;
+  size_t block_size;
+};
+
 struct memcached_st {
   memcached_allocated is_allocated;
   memcached_host_st *hosts;
@@ -165,6 +174,21 @@ memcached_return memcached_stat_get_value(memcached_stat_st *stat, char *key,
                                           char *value, size_t value_length);
 char ** memcached_stat_get_keys(memcached_stat_st *stat, memcached_return *error);
 
+/* String Struct */
+#define memcached_string_length(A, B) (size_t)(B->end - B->string)
+#define memcached_string_size(A, B) B->current_size
+#define memcached_string_value(A, B) B->string
+
+memcached_string_st *memcached_string_init(memcached_st *ptr, size_t initial_size);
+memcached_return memcached_string_append_character(memcached_st *ptr, 
+                                                   memcached_string_st *string, 
+                                                   char character);
+memcached_return memcached_string_append(memcached_st *ptr, memcached_string_st *string,
+                                         char *value, size_t length);
+size_t memcached_string_backspace(memcached_st *ptr, memcached_string_st *string, size_t remove);
+memcached_return memcached_string_reset(memcached_st *ptr, memcached_string_st *string);
+void memcached_string_free(memcached_st *ptr, memcached_string_st *string);
+
 #ifdef __cplusplus
 }
 #endif
index 93ab95edcc26e2f154ec28952f08e3c337e52b11..f65971865c1871d712f28077d52b62b8f70d3d75 100644 (file)
@@ -14,4 +14,5 @@ libmemcached_la_SOURCES = memcached.c \
                          memcached_verbosity.c \\r
                          memcached_quit.c \\r
                          memcached_flush.c \\r
+                         memcached_string.c \\r
                          memcached_stats.c\r
index a0c8737c31df48e6e6b7b98e5549d06344408e42..d0658f33e57d2e92c267b8442154d49cba06e7a2 100644 (file)
@@ -2,6 +2,9 @@
 
 memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigned int port)
 {
+  memcached_host_st *new_host_list;
+  char *new_hostname;
+
   if (!port)
     port= MEMCACHED_DEFAULT_PORT; 
 
@@ -9,11 +12,23 @@ memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigne
     hostname= "localhost"; 
 
 
-  ptr->hosts= (memcached_host_st *)realloc(ptr->hosts, sizeof(memcached_host_st) * (ptr->number_of_hosts+1));
-  ptr->hosts[ptr->number_of_hosts].hostname=
+  new_host_list= (memcached_host_st *)realloc(ptr->hosts, sizeof(memcached_host_st) * (ptr->number_of_hosts+1));
+  memset((new_host_list + (sizeof(memcached_host_st) * ptr->number_of_hosts)) - sizeof(memcached_host_st), 
+         0, sizeof(memcached_host_st));
+  
+  if (!new_host_list)
+    return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+
+  ptr->hosts= new_host_list;
+
+  new_hostname=
     (char *)malloc(sizeof(char) * (strlen(hostname)+1));
-  memset(ptr->hosts[ptr->number_of_hosts].hostname, 0, strlen(hostname)+1);
-  memcpy(ptr->hosts[ptr->number_of_hosts].hostname, hostname, strlen(hostname));
+  if (!new_hostname)
+    return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+
+  memset(new_hostname, 0, strlen(hostname)+1);
+  memcpy(new_hostname, hostname, strlen(hostname));
+  ptr->hosts[ptr->number_of_hosts].hostname= new_hostname;
   ptr->hosts[ptr->number_of_hosts].port= port;
   ptr->hosts[ptr->number_of_hosts].fd= -1;
   ptr->number_of_hosts++;
index 58372c6a84813b7762ec853424d6c8d5cd964461..a822f4ad64d05b07eb5b881c2c68f1112df59455 100644 (file)
@@ -12,6 +12,7 @@ memcached_return memcached_flush(memcached_st *ptr, time_t expiration)
   if (rc != MEMCACHED_SUCCESS)
     rc= MEMCACHED_SOME_ERRORS;
 
+  memset(buffer, 0, MEMCACHED_DEFAULT_COMMAND_SIZE);
   for (x= 0; x < ptr->number_of_hosts; x++)
   {
     if (expiration)
index a29deab3bfac2818f2385cb9bd500f777b5d074e..b920df3f4fd55b5162fca8a4ace8c8c24f6cea89 100644 (file)
@@ -117,9 +117,9 @@ memcached_return memcached_mget(memcached_st *ptr,
                                 unsigned int number_of_keys)
 {
   char buffer[HUGE_STRING_LEN];
-  char *buffer_ptr;
   unsigned int x;
   memcached_return rc;
+  memcached_string_st **cursor_key_exec;
 
   ptr->cursor_server= 0;
   memset(buffer, 0, HUGE_STRING_LEN);
@@ -129,34 +129,60 @@ memcached_return memcached_mget(memcached_st *ptr,
   if (rc != MEMCACHED_SUCCESS)
     return rc;
 
-  memcpy(buffer, "get", strlen("get"));
-  buffer_ptr= buffer;
-  buffer_ptr+=strlen("get");
+  cursor_key_exec= (memcached_string_st **)malloc(sizeof(memcached_string_st *) * ptr->number_of_hosts);
+  memset(cursor_key_exec, 0, sizeof(memcached_string_st *) * ptr->number_of_hosts);
+
 
   for (x= 0; x < number_of_keys; x++)
   {
-    *buffer_ptr= ' ';
-    buffer_ptr++;
-    memcpy(buffer_ptr, keys[x], key_length[x]);
-    buffer_ptr+= key_length[x];
+    unsigned int server_key;
+
+    server_key= memcached_generate_hash(keys[x], key_length[x]) % ptr->number_of_hosts;
+
+    if (cursor_key_exec[server_key])
+    {
+      memcached_string_st *string= cursor_key_exec[server_key];
+
+      memcached_string_append_character(ptr, string, ' ');
+      memcached_string_append(ptr, string, keys[x], key_length[x]);
+    }
+    else
+    {
+      memcached_string_st *string= memcached_string_init(ptr, SMALL_STRING_LEN);
+
+      if (!string)
+        assert(0);
+
+      memcached_string_append(ptr, string, "get ", 4);
+      memcached_string_append(ptr, string, keys[x], key_length[x]);
+
+      cursor_key_exec[server_key]= string;
+    }
   }
 
-  memcpy(buffer_ptr, "\r\n", 2);
-  buffer_ptr+=2;
 
   /*
-    This must be fixed. Right now we hit every server, and send keys
-    to all servers. We should fix this quickly.
+    Should we muddle on if some servers are dead?
   */
   for (x= 0; x < ptr->number_of_hosts; x++)
   {
-    if ((write(ptr->hosts[x].fd, buffer, (size_t)(buffer_ptr - buffer)) == -1))
+    if (cursor_key_exec[x])
     {
-      memcached_quit(ptr);
-      rc= MEMCACHED_SOME_ERRORS;
+      memcached_string_st *string= cursor_key_exec[x];
+      memcached_string_append(ptr, string, "\r\n", 2);
+
+      if ((write(ptr->hosts[x].fd, string->string, 
+                 memcached_string_length(ptr, string)) == -1))
+      {
+        memcached_quit(ptr);
+        rc= MEMCACHED_SOME_ERRORS;
+      }
+      memcached_string_free(ptr, string);
     }
   }
 
+  free(cursor_key_exec);
+
   return rc;
 }
 
index 48e62ccee299d949c3cadd00d964e1a891ad3425..5b917fca10357a37e2cacb61be68a57328d56a9e 100644 (file)
@@ -385,7 +385,15 @@ char ** memcached_stat_get_keys(memcached_stat_st *stat, memcached_return *error
 {
   char **list= (char **)malloc(sizeof(memcached_stat_keys));
 
+  if (!list)
+  {
+    *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+    return NULL;
+  }
+
   memcpy(list, memcached_stat_keys, sizeof(memcached_stat_keys));
 
+  *error= MEMCACHED_SUCCESS;
+
   return list;
 }
diff --git a/lib/memcached_string.c b/lib/memcached_string.c
new file mode 100644 (file)
index 0000000..5b2b9d5
--- /dev/null
@@ -0,0 +1,103 @@
+#include <memcached.h>
+
+memcached_return memcached_string_check(memcached_string_st *string, size_t need)
+{
+  if (need > (string->current_size - (string->end - string->string)))
+  {
+    size_t current_offset= string->end - string->string;
+    char *new_value;
+
+    new_value= (char *)realloc(string->string, sizeof(char) * string->block_size);
+
+    if (!new_value)
+      return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+
+    string->string= new_value;
+    string->end= string->string + current_offset;
+
+    string->current_size+= string->block_size;
+
+    /* We zero the block structure we just realloced */
+    memset((string + string->current_size) - string->block_size , 0, 
+           sizeof(char) * string->block_size);
+  }
+
+  return MEMCACHED_SUCCESS;
+}
+
+memcached_string_st *memcached_string_init(memcached_st *ptr, size_t initial_size)
+{
+  memcached_string_st *string;
+
+  /* Saving malloc calls :) */
+  string= (memcached_string_st *)malloc(sizeof(memcached_string_st) + (sizeof(char) * initial_size));
+  if (!string)
+    return NULL;
+  memset(string, 0, sizeof(memcached_string_st));
+  string->block_size= initial_size;
+  memcached_string_check(string, initial_size);
+
+  return string;
+}
+
+memcached_return memcached_string_append_character(memcached_st *ptr, 
+                                                   memcached_string_st *string, 
+                                                   char character)
+{
+  memcached_string_check(string, 1);
+  *string->end= ' ';
+  string->end++;
+
+  return MEMCACHED_SUCCESS;
+}
+
+memcached_return memcached_string_append(memcached_st *ptr, memcached_string_st *string,
+                                         char *value, size_t length)
+{
+  memcached_string_check(string, length);
+  memcpy(string->end, value, length);
+  string->end+= length;
+
+  return MEMCACHED_SUCCESS;
+}
+
+#ifdef CRAP
+size_t memcached_string_length(memcached_st *ptr, memcached_string_st *string)
+{
+  return (size_t)(string->end - string->string);
+}
+
+size_t memcached_string_size(memcached_st *ptr, memcached_string_st *string)
+{
+  return string->current_size;
+}
+#endif
+
+size_t memcached_string_backspace(memcached_st *ptr, memcached_string_st *string, size_t remove)
+{
+  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;
+}
+
+memcached_return memcached_string_reset(memcached_st *ptr, memcached_string_st *string)
+{
+  string->end= string->string;
+  
+  return MEMCACHED_SUCCESS;
+}
+
+void memcached_string_free(memcached_st *ptr, memcached_string_st *string)
+{
+  free(string->string);
+  free(string);
+}