X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Ffetch.cc;h=d795109259108b5bde95c5682cf5ca04f523790b;hb=6d8ae66c64dded43f17dc85b906dd334e1173bf7;hp=5a353d29e2fa19e72f2ff67c2ea6844fea799670;hpb=276e5c1e7fefa8f7061270f79443a704231c819e;p=awesomized%2Flibmemcached diff --git a/libmemcached/fetch.cc b/libmemcached/fetch.cc index 5a353d29..d7951092 100644 --- a/libmemcached/fetch.cc +++ b/libmemcached/fetch.cc @@ -2,7 +2,7 @@ * * Libmemcached library * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * Copyright (C) 2011-2012 Data Differential, http://datadifferential.com/ * Copyright (C) 2006-2009 Brian Aker All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,56 +37,76 @@ #include -char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, +char *memcached_fetch(memcached_st *shell, char *key, size_t *key_length, size_t *value_length, uint32_t *flags, memcached_return_t *error) { - memcached_result_st *result_buffer= &ptr->result; + Memcached* ptr= memcached2Memcached(shell); memcached_return_t unused; - if (not error) + if (error == NULL) + { error= &unused; + } - - unlikely (ptr->flags.use_udp) + if (memcached_is_udp(ptr)) { if (value_length) + { *value_length= 0; + } if (key_length) + { *key_length= 0; + } if (flags) + { *flags= 0; + } if (key) + { *key= 0; + } *error= MEMCACHED_NOT_SUPPORTED; return NULL; } + memcached_result_st *result_buffer= &ptr->result; result_buffer= memcached_fetch_result(ptr, result_buffer, error); if (result_buffer == NULL or memcached_failed(*error)) { WATCHPOINT_ASSERT(result_buffer == NULL); if (value_length) + { *value_length= 0; + } if (key_length) + { *key_length= 0; + } if (flags) + { *flags= 0; + } if (key) + { *key= 0; + } return NULL; } if (value_length) + { *value_length= memcached_string_length(&result_buffer->value); + } if (key) { @@ -94,62 +114,102 @@ char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, { *error= MEMCACHED_KEY_TOO_BIG; if (value_length) + { *value_length= 0; + } - if (key_length) - *key_length= 0; + if (key_length) + { + *key_length= 0; + } - if (flags) - *flags= 0; + if (flags) + { + *flags= 0; + } - if (key) - *key= 0; + if (key) + { + *key= 0; + } return NULL; } + strncpy(key, result_buffer->item_key, result_buffer->key_length); // For the binary protocol we will cut off the key :( if (key_length) + { *key_length= result_buffer->key_length; + } } if (flags) + { *flags= result_buffer->item_flags; + } - return memcached_string_c_copy(&result_buffer->value); + return memcached_string_take_value(&result_buffer->value); } memcached_result_st *memcached_fetch_result(memcached_st *ptr, memcached_result_st *result, memcached_return_t *error) { - memcached_server_st *server; - memcached_return_t unused; - if (not error) + if (error == NULL) + { error= &unused; + } - if (ptr->flags.use_udp) + if (ptr == NULL) + { + *error= MEMCACHED_INVALID_ARGUMENTS; + return NULL; + } + + if (memcached_is_udp(ptr)) { *error= MEMCACHED_NOT_SUPPORTED; return NULL; } - if (not result) + if (result == NULL) { - if (not (result= memcached_result_create(ptr, NULL))) + // If we have already initialized (ie it is in use) our internal, we + // create one. + if (memcached_is_initialized(&ptr->result)) { - *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; - return NULL; + if ((result= memcached_result_create(ptr, NULL)) == NULL) + { + *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; + return NULL; + } + } + else + { + result= memcached_result_create(ptr, &ptr->result); } } *error= MEMCACHED_MAXIMUM_RETURN; // We use this to see if we ever go into the loop - while ((server= memcached_io_get_readable_server(ptr))) + memcached_instance_st *server; + memcached_return_t read_ret= MEMCACHED_SUCCESS; + bool connection_failures= false; + while ((server= memcached_io_get_readable_server(ptr, read_ret))) { char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; *error= memcached_response(server, buffer, sizeof(buffer), result); - if (*error == MEMCACHED_SUCCESS) + if (*error == MEMCACHED_IN_PROGRESS) + { + continue; + } + else if (*error == MEMCACHED_CONNECTION_FAILURE) + { + connection_failures= true; + continue; + } + else if (*error == MEMCACHED_SUCCESS) { result->count++; return result; @@ -176,6 +236,16 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, { *error= MEMCACHED_NOTFOUND; } + else if (connection_failures) + { + /* + If we have a connection failure to some servers, the caller may + wish to treat that differently to getting a definitive NOT_FOUND + from all servers, so return MEMCACHED_CONNECTION_FAILURE to allow + that. + */ + *error= MEMCACHED_CONNECTION_FAILURE; + } else if (*error == MEMCACHED_SUCCESS) { *error= MEMCACHED_END; @@ -199,11 +269,12 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, return NULL; } -memcached_return_t memcached_fetch_execute(memcached_st *ptr, +memcached_return_t memcached_fetch_execute(memcached_st *shell, memcached_execute_fn *callback, void *context, uint32_t number_of_callbacks) { + Memcached* ptr= memcached2Memcached(shell); memcached_result_st *result= &ptr->result; memcached_return_t rc; bool some_errors= false;