IPV6 support, plus cleanup around consistent hashing.
author <brian@gir.tangent.org> <>
Thu, 29 Nov 2007 16:59:19 +0000 (08:59 -0800)
committer <brian@gir.tangent.org> <>
Thu, 29 Nov 2007 16:59:19 +0000 (08:59 -0800)
ChangeLog
configure.ac
include/memcached.h
lib/memcached.c
lib/memcached_connect.c
lib/memcached_hash.c
lib/memcached_hosts.c
lib/memcached_io.c
tests/function.c

index 99391fceef42303134201b1ee50d60891e7a75c7..ffb487e229564add2a825b8c893d982d548ab14e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+0.12 
+  * Updates for consistent hashing
+  * IPV6 support
+  * Static allocation for hostname (performance)
+
 0.11 Mon Nov 26 01:05:52 PST 2007
   * Added option to memcache_behavior_set() so that poll() can be timed out.
   * Fixed memory leak in case of using memcached_fetch_result() where no
index 3c2310eb7794796e8cb784be05125d2969069ad2..0c8be6ff75f996521a2349e51cd1336d262085e1 100644 (file)
@@ -6,7 +6,7 @@ MEMCACHED_LIBRARY_NAME=libmemcached
 
 #release versioning
 MEMCACHED_MAJOR_VERSION=0
-MEMCACHED_MINOR_VERSION=11
+MEMCACHED_MINOR_VERSION=12
 MEMCACHED_MICRO_VERSION=0
 
 #API version
@@ -68,5 +68,4 @@ fi
 
 AC_C_CONST
 AC_TYPE_SIZE_T
-AC_CHECK_FUNC(gethostbyname_r, AC_DEFINE([HAVE_GETHOSTBYNAME_R], [], [Looking for gethostbyname_r]))
 AC_OUTPUT(Makefile src/Makefile tests/Makefile docs/Makefile lib/Makefile include/Makefile support/Makefile support/libmemcached.pc support/libmemcached.spec)
index 194170ef1427959f0e067ac940e69e1e3a40c38f..971b4ab43ee0d2b840eb475aba175969b5fae01f 100644 (file)
@@ -70,7 +70,7 @@ typedef enum {
 } memcached_return;
 
 typedef enum {
-  MEMCACHED_DISTRIBUTION_MODULUS,
+  MEMCACHED_DISTRIBUTION_MODULO,
   MEMCACHED_DISTRIBUTION_CONSISTENT,
 } memcached_server_distribution;
 
@@ -124,7 +124,7 @@ struct memcached_server_st {
   size_t read_buffer_length;
   char *read_ptr;
   memcached_allocated sockaddr_inited;
-  struct sockaddr_in servAddr;
+  struct addrinfo *address_info;
   memcached_connection type;
   uint8_t major_version;
   uint8_t minor_version;
index 1ed39a915feb628e759369dba68be4f5acb4079e..861bafda95dbaf76dba54503cf90efc558268b6f 100644 (file)
@@ -23,20 +23,16 @@ memcached_st *memcached_create(memcached_st *ptr)
   string_ptr= memcached_string_create(ptr, &ptr->result_buffer, 0);
   WATCHPOINT_ASSERT(string_ptr);
   ptr->poll_timeout= -1;
-  ptr->distribution= MEMCACHED_DISTRIBUTION_MODULUS;
+  ptr->distribution= MEMCACHED_DISTRIBUTION_MODULO;
 
   return ptr;
 }
 
 void memcached_free(memcached_st *ptr)
 {
-  if (ptr->hosts)
-  {
-    memcached_quit(ptr);
-    memcached_server_list_free(ptr->hosts);
-    ptr->hosts= NULL;
-  }
-
+  /* If we have anything open, lets close it now */
+  memcached_quit(ptr);
+  memcached_server_list_free(ptr->hosts);
   memcached_string_free(&ptr->result_buffer);
 
   if (ptr->is_allocated == MEMCACHED_ALLOCATED)
@@ -57,6 +53,12 @@ memcached_st *memcached_clone(memcached_st *clone, memcached_st *ptr)
 
   if (ptr == NULL)
     return memcached_create(clone);
+
+  if (ptr->is_allocated == MEMCACHED_USED)
+  {
+    WATCHPOINT_ASSERT(0);
+    return NULL;
+  }
   
   new_clone= memcached_create(clone);
 
index 0135fc9a31f66bb723bb29a3174d8753a8618089..672b1c23b65e5ce4f1d0c29c9502352186425d42 100644 (file)
@@ -6,36 +6,33 @@
 #include <sys/un.h>
 #include <netinet/tcp.h>
 #include <netdb.h>
+#include <netinet/in.h>
 
 static memcached_return set_hostinfo(memcached_server_st *server)
 {
-  struct hostent *h;
-#ifdef HAVE_GETHOSTBYNAME_R
-  struct hostent h_static;
-  char buffer[SMALL_STRING_LEN];
-  int tmp_error;
-
-  if (gethostbyname_r(server->hostname,
-                      &h_static, buffer, SMALL_STRING_LEN, 
-                      &h, &tmp_error))
-  {
-    WATCHPOINT_STRING(server->hostname);
-    WATCHPOINT_STRING(hstrerror(tmp_error));
-    return MEMCACHED_HOST_LOOKUP_FAILURE;
-  }
-#else
-  if ((h= gethostbyname(server->hostname)) == NULL)
+  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;
+  hints.ai_socktype= SOCK_STREAM;
+  hints.ai_protocol= 0;
+
+  e= getaddrinfo(server->hostname, str_port, &hints, &ai);
+  if (e != 0)
   {
     WATCHPOINT_STRING(server->hostname);
-    WATCHPOINT_STRING(hstrerror(h_errno));
+    WATCHPOINT_STRING(gai_strerror(e));
     return MEMCACHED_HOST_LOOKUP_FAILURE;
   }
-#endif
-
-  server->servAddr.sin_family= h->h_addrtype;
-  memcpy((char *) &server->servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
 
-  server->servAddr.sin_port = htons(server->port);
+  if (server->address_info)
+    freeaddrinfo(server->address_info);
+  server->address_info= ai;
 
   return MEMCACHED_SUCCESS;
 }
@@ -73,6 +70,7 @@ test_connect:
       case EISCONN: /* We were spinning waiting on connect */
         break;
       default:
+        WATCHPOINT_ERRNO(errno);
         ptr->cached_errno= errno;
         return MEMCACHED_ERRNO;
       }
@@ -122,6 +120,7 @@ static memcached_return tcp_connect(memcached_st *ptr, unsigned int server_key)
   {
     /* Old connection junk still is in the structure */
     WATCHPOINT_ASSERT(ptr->hosts[server_key].stack_responses == 0);
+    struct addrinfo *use;
 
     if (ptr->hosts[server_key].sockaddr_inited == MEMCACHED_NOT_ALLOCATED || 
         (!(ptr->flags & MEM_USE_CACHE_LOOKUPS)))
@@ -133,9 +132,12 @@ static memcached_return tcp_connect(memcached_st *ptr, unsigned int server_key)
         return rc;
       ptr->hosts[server_key].sockaddr_inited= MEMCACHED_ALLOCATED;
     }
+    use= ptr->hosts[server_key].address_info;
 
     /* Create the socket */
-    if ((ptr->hosts[server_key].fd= socket(AF_INET, SOCK_STREAM, 0)) < 0)
+    if ((ptr->hosts[server_key].fd= socket(use->ai_family, 
+                                           use->ai_socktype, 
+                                           use->ai_protocol)) < 0)
     {
       ptr->cached_errno= errno;
       return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
@@ -174,8 +176,8 @@ static memcached_return tcp_connect(memcached_st *ptr, unsigned int server_key)
     /* connect to server */
 test_connect:
     if (connect(ptr->hosts[server_key].fd, 
-                (struct sockaddr *)&ptr->hosts[server_key].servAddr, 
-                sizeof(struct sockaddr)) < 0)
+                use->ai_addr, 
+                use->ai_addrlen) < 0)
     {
       switch (errno) {
         /* We are spinning waiting on connect */
@@ -187,6 +189,7 @@ test_connect:
         break;
       default:
         ptr->cached_errno= errno;
+        WATCHPOINT_ERRNO(ptr->cached_errno);
         return MEMCACHED_ERRNO;
       }
       ptr->connected++;
index 95d7f8622d23975e61015d38ff9e49c8450e9a11..3ea5df976a3df5d6f945b5b89b26b5c019411456 100644 (file)
@@ -86,7 +86,7 @@ unsigned int memcached_generate_hash(memcached_st *ptr, char *key, size_t key_le
 
   WATCHPOINT_ASSERT(hash);
 
-  if (ptr->distribution == MEMCACHED_DISTRIBUTION_MODULUS)
+  if (ptr->distribution == MEMCACHED_DISTRIBUTION_MODULO)
   {
     return hash % ptr->number_of_hosts;
   }
index 3517d824698c4f359d9e188ff1734bc5e49614da..402018b4ae90cb58492776a5afed153c9c908b71 100644 (file)
@@ -186,8 +186,14 @@ unsigned int memcached_server_list_count(memcached_server_st *ptr)
 
 void memcached_server_list_free(memcached_server_st *ptr)
 {
+  unsigned int x;
+
   if (ptr == NULL)
     return;
 
+  for (x= 0; x < ptr->count; x++)
+    if (ptr[x].address_info)
+      freeaddrinfo(ptr[x].address_info);
+
   free(ptr);
 }
index 973ccf95f676ccc428657b200ba30b287d3c68c5..8a05ddb8361e3efc03d40f85a40cd947f0665585 100644 (file)
@@ -152,7 +152,7 @@ ssize_t memcached_io_flush(memcached_st *ptr, unsigned int server_key)
     {
       sent_length= sendto(ptr->hosts[server_key].fd, 
                           write_ptr, write_length, 0, 
-                          (struct sockaddr *)&ptr->hosts[server_key].servAddr, 
+                          (struct sockaddr *)&ptr->hosts[server_key].address_info->ai_addr, 
                           sizeof(struct sockaddr));
     }
     else
index c42cc82baa940c44607a12406dbe6503e93615ef..c3d764c4981653c1c529367a4ebcde7da1032b3c 100644 (file)
@@ -112,6 +112,7 @@ uint8_t set_test(memcached_st *memc)
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
                     (time_t)0, (uint16_t)0);
+  WATCHPOINT_ERROR(rc);
   assert(rc == MEMCACHED_SUCCESS);
 
   return 0;