Branch merge.
author <brian@gir-2.local> <>
Fri, 29 Feb 2008 07:19:55 +0000 (23:19 -0800)
committer <brian@gir-2.local> <>
Fri, 29 Feb 2008 07:19:55 +0000 (23:19 -0800)
1  2 
ChangeLog
docs/memcached_behavior.pod
include/memcached.h
lib/memcached_auto.c
lib/memcached_behavior.c
lib/memcached_delete.c
lib/memcached_mget.c
lib/memcached_storage.c
tests/function.c

diff --cc ChangeLog
Simple merge
Simple merge
Simple merge
index 1f61a18ce0fe05c318fee3d0f7ebafa469f65eca,a607ed66e23298881c2ee5bfd6d3ea429aafbb62..3aa63eedc4a8a7af09240250cebf49851bbeea73
@@@ -7,15 -7,14 +7,15 @@@ static memcached_return memcached_auto(
                                         uint64_t *value)
  {
    size_t send_length;
 -  memcached_return rc;
    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
    unsigned int server_key;
 +  uint8_t replicas= 0;
 +  memcached_return rc[MEMCACHED_MAX_REPLICAS];
  
-   if (key_length == 0)
+   unlikely (key_length == 0)
      return MEMCACHED_NO_KEY_PROVIDED;
  
-   if (ptr->hosts == NULL || ptr->number_of_hosts == 0)
+   unlikely (ptr->hosts == NULL || ptr->number_of_hosts == 0)
      return MEMCACHED_NO_SERVERS;
  
    if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED))
                          "%s %.*s %u\r\n", verb, 
                          (int)key_length, key,
                          offset);
-   if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
+   unlikely (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
      return MEMCACHED_WRITE_FAILURE;
  
 -  rc= memcached_do(&ptr->hosts[server_key], buffer, send_length, 1);
 -  if (rc != MEMCACHED_SUCCESS)
 -    return rc;
 -
 -  rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
 -
 -  /* 
 -    So why recheck responce? Because the protocol is brain dead :)
 -    The number returned might end up equaling one of the string 
 -    values. Less chance of a mistake with strncmp() so we will 
 -    use it. We still called memcached_response() though since it
 -    worked its magic for non-blocking IO.
 -  */
 -  if (!strncmp(buffer, "ERROR\r\n", 7))
 +  do 
    {
 -    *value= 0;
 -    rc= MEMCACHED_PROTOCOL_ERROR;
 -  }
 -  else if (!strncmp(buffer, "NOT_FOUND\r\n", 11))
 +    rc[replicas]= memcached_do(&ptr->hosts[server_key], buffer, send_length, 1);
 +    if (rc[replicas] != MEMCACHED_SUCCESS)
 +      goto error;
 +
 +    rc[replicas]= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
 +
 +    /* 
 +      So why recheck responce? Because the protocol is brain dead :)
 +      The number returned might end up equaling one of the string 
 +      values. Less chance of a mistake with strncmp() so we will 
 +      use it. We still called memcached_response() though since it
 +      worked its magic for non-blocking IO.
 +    */
 +    if (!strncmp(buffer, "ERROR\r\n", 7))
 +    {
 +      *value= 0;
 +      rc[replicas]= MEMCACHED_PROTOCOL_ERROR;
 +    }
 +    else if (!strncmp(buffer, "NOT_FOUND\r\n", 11))
 +    {
 +      *value= 0;
 +      rc[replicas]= MEMCACHED_NOTFOUND;
 +    }
 +    else
 +    {
 +      *value= (uint64_t)strtoll(buffer, (char **)NULL, 10);
 +      rc[replicas]= MEMCACHED_SUCCESS;
 +    }
 +    /* On error we just jump to the next potential server */
 +error:
 +    if (replicas > 1 && ptr->distribution == MEMCACHED_DISTRIBUTION_CONSISTENT)
 +    {
 +      if (server_key == (ptr->number_of_hosts - 1))
 +        server_key= 0;
 +      else
 +        server_key++;
 +    }
 +  } while ((++replicas) < ptr->number_of_replicas);
 +
 +  /* As long as one object gets stored, we count this as a success */
 +  while (replicas--)
    {
 -    *value= 0;
 -    rc= MEMCACHED_NOTFOUND;
 -  }
 -  else
 -  {
 -    *value= (uint64_t)strtoll(buffer, (char **)NULL, 10);
 -    rc= MEMCACHED_SUCCESS;
 +    if (rc[replicas] == MEMCACHED_STORED)
 +      return MEMCACHED_SUCCESS;
    }
  
 -  return rc;
 +  return rc[0];
  }
  
  memcached_return memcached_increment(memcached_st *ptr, 
Simple merge
index 96db7b4efabe2f3bcf5247ab685f7197033bc236,60e3bed4406e3ce89c1b6c64868559af8f77b7b8..24dc16601c178dc30b498658701bdae332948a31
@@@ -14,15 -14,16 +14,15 @@@ memcached_return memcached_delete_by_ke
  {
    char to_write;
    size_t send_length;
 -  memcached_return rc;
    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
    unsigned int server_key;
 -
 -  LIBMEMCACHED_MEMCACHED_DELETE_START();
 +  uint8_t replicas= 0;
 +  memcached_return rc[MEMCACHED_MAX_REPLICAS];
  
-   if (key_length == 0)
+   unlikely (key_length == 0)
      return MEMCACHED_NO_KEY_PROVIDED;
  
-   if (ptr->hosts == NULL || ptr->number_of_hosts == 0)
+   unlikely (ptr->hosts == NULL || ptr->number_of_hosts == 0)
      return MEMCACHED_NO_SERVERS;
  
    server_key= memcached_generate_hash(ptr, master_key, master_key_length);
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a25fa8e09f30a6d5bc0f3d9210a6319d8672e4d0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,125 @@@
++#include "common.h"
++#include "memcached_io.h"
++
++memcached_return memcached_mget(memcached_st *ptr, 
++                                char **keys, size_t *key_length, 
++                                unsigned int number_of_keys)
++{
++  return memcached_mget_by_key(ptr, NULL, 0, keys, key_length, number_of_keys);
++}
++
++memcached_return memcached_mget_by_key(memcached_st *ptr, 
++                                       char *master_key, size_t master_key_length,
++                                       char **keys, size_t *key_length, 
++                                       unsigned int number_of_keys)
++{
++  unsigned int x;
++  memcached_return rc= MEMCACHED_NOTFOUND;
++  char *get_command= "get ";
++  uint8_t get_command_length= 4;
++  unsigned int master_server_key= 0;
++
++  LIBMEMCACHED_MEMCACHED_MGET_START();
++  ptr->cursor_server= 0;
++
++  if (number_of_keys == 0)
++    return MEMCACHED_NOTFOUND;
++
++  if (ptr->number_of_hosts == 0)
++    return MEMCACHED_NO_SERVERS;
++
++  if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(keys, key_length, number_of_keys) == MEMCACHED_BAD_KEY_PROVIDED))
++    return MEMCACHED_BAD_KEY_PROVIDED;
++
++  if (ptr->flags & MEM_SUPPORT_CAS)
++  {
++    get_command= "gets ";
++    get_command_length= 5;
++  }
++
++  if (master_key && master_key_length)
++    master_server_key= memcached_generate_hash(ptr, master_key, master_key_length);
++
++  /* 
++    Here is where we pay for the non-block API. We need to remove any data sitting
++    in the queue before we start our get.
++
++    It might be optimum to bounce the connection if count > some number.
++  */
++  for (x= 0; x < ptr->number_of_hosts; x++)
++  {
++    if (memcached_server_response_count(&ptr->hosts[x]))
++    {
++      char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
++
++      if (ptr->flags & MEM_NO_BLOCK)
++        (void)memcached_io_write(&ptr->hosts[x], NULL, 0, 1);
++
++      while(memcached_server_response_count(&ptr->hosts[x]))
++        (void)memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, &ptr->result);
++    }
++  }
++
++  /* 
++    If a server fails we warn about errors and start all over with sending keys
++    to the server.
++  */
++  for (x= 0; x < number_of_keys; x++)
++  {
++    unsigned int server_key;
++
++    if (master_server_key)
++      server_key= master_server_key;
++    else
++      server_key= memcached_generate_hash(ptr, keys[x], key_length[x]);
++
++    if (memcached_server_response_count(&ptr->hosts[server_key]) == 0)
++    {
++      rc= memcached_connect(&ptr->hosts[server_key]);
++
++      if (rc != MEMCACHED_SUCCESS)
++        continue;
++
++      if ((memcached_io_write(&ptr->hosts[server_key], get_command, get_command_length, 0)) == -1)
++      {
++        rc= MEMCACHED_SOME_ERRORS;
++        continue;
++      }
++      WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 0);
++      memcached_server_response_increment(&ptr->hosts[server_key]);
++      WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 1);
++    }
++
++    if ((memcached_io_write(&ptr->hosts[server_key], keys[x], key_length[x], 0)) == -1)
++    {
++      memcached_server_response_reset(&ptr->hosts[server_key]);
++      rc= MEMCACHED_SOME_ERRORS;
++      continue;
++    }
++
++    if ((memcached_io_write(&ptr->hosts[server_key], " ", 1, 0)) == -1)
++    {
++      memcached_server_response_reset(&ptr->hosts[server_key]);
++      rc= MEMCACHED_SOME_ERRORS;
++      continue;
++    }
++  }
++
++  /*
++    Should we muddle on if some servers are dead?
++  */
++  for (x= 0; x < ptr->number_of_hosts; x++)
++  {
++    if (memcached_server_response_count(&ptr->hosts[x]))
++    {
++      /* We need to do something about non-connnected hosts in the future */
++      if ((memcached_io_write(&ptr->hosts[x], "\r\n", 2, 1)) == -1)
++      {
++        rc= MEMCACHED_SOME_ERRORS;
++      }
++    }
++  }
++
++  LIBMEMCACHED_MEMCACHED_MGET_END();
++  return rc;
++}
Simple merge
index 69ae84b14fcfce8b4af94f7b11e9ed456891ec6f,2258757d646981c1d9dc537b29ef0f37f09ac447..b10ead9b6b225258fbb4f12f84d09787a1b8ec08
@@@ -2310,14 -2308,6 +2308,16 @@@ memcached_return enable_consistent(memc
    return MEMCACHED_SUCCESS;
  }
  
 +memcached_return enable_replication(memcached_st *memc)
 +{
 +  uint64_t value;
 +  value= 2;
 +  enable_consistent(memc);
 +  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_REPLICAS, &value);
++
++  return MEMCACHED_SUCCESS;
 +}
 +
  memcached_return enable_cas(memcached_st *memc)
  {
    unsigned int set= 1;