X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Ffetch.cc;h=27ea3a8413722f987cbb3eebeee503c9820b0703;hb=cbda284a1c119a467135113b3a85ced915e869aa;hp=783ee771ed10fbdbe552585b024eede26d5703e5;hpb=5ba03c8cc82605f0eb171d547876fb6cbed70a76;p=m6w6%2Flibmemcached diff --git a/libmemcached/fetch.cc b/libmemcached/fetch.cc index 783ee771..27ea3a84 100644 --- a/libmemcached/fetch.cc +++ b/libmemcached/fetch.cc @@ -44,73 +44,197 @@ char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, { memcached_result_st *result_buffer= &ptr->result; 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; } result_buffer= memcached_fetch_result(ptr, result_buffer, error); - - if (result_buffer == NULL or *error != MEMCACHED_SUCCESS) + if (result_buffer == NULL or memcached_failed(*error)) { WATCHPOINT_ASSERT(result_buffer == NULL); - *value_length= 0; + if (value_length) + { + *value_length= 0; + } + + if (key_length) + { + *key_length= 0; + } + + if (flags) + { + *flags= 0; + } + + if (key) + { + *key= 0; + } + return NULL; } - *value_length= memcached_string_length(&result_buffer->value); + if (value_length) + { + *value_length= memcached_string_length(&result_buffer->value); + } if (key) { if (result_buffer->key_length > MEMCACHED_MAX_KEY) { *error= MEMCACHED_KEY_TOO_BIG; - *value_length= 0; + if (value_length) + { + *value_length= 0; + } + + if (key_length) + { + *key_length= 0; + } + + if (flags) + { + *flags= 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 :( - *key_length= result_buffer->key_length; + 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 (error == NULL) + { + error= &unused; + } - unlikely (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 (result == NULL) - if ((result= memcached_result_create(ptr, NULL)) == NULL) - return NULL; + { + // If we have already initialized (ie it is in use) our internal, we + // create one. + if (memcached_is_initialized(&ptr->result)) + { + if ((result= memcached_result_create(ptr, NULL)) == NULL) + { + *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; + return NULL; + } + } + else + { + result= memcached_result_create(ptr, &ptr->result); + } + } - while ((server= memcached_io_get_readable_server(ptr)) != NULL) + *error= MEMCACHED_MAXIMUM_RETURN; // We use this to see if we ever go into the loop + memcached_server_st *server; + while ((server= memcached_io_get_readable_server(ptr))) { 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_SUCCESS) + { + result->count++; return result; + } else if (*error == MEMCACHED_END) + { memcached_server_response_reset(server); + } else if (*error != MEMCACHED_NOTFOUND) + { break; + } + } + + if (*error == MEMCACHED_NOTFOUND and result->count) + { + *error= MEMCACHED_END; + } + else if (*error == MEMCACHED_MAXIMUM_RETURN and result->count) + { + *error= MEMCACHED_END; + } + else if (*error == MEMCACHED_MAXIMUM_RETURN) // while() loop was never entered + { + *error= MEMCACHED_NOTFOUND; + } + else if (*error == MEMCACHED_SUCCESS) + { + *error= MEMCACHED_END; + } + else if (result->count == 0) + { + *error= MEMCACHED_NOTFOUND; } /* We have completed reading data */ @@ -120,6 +244,7 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, } else { + result->count= 0; memcached_string_reset(&result->value); } @@ -132,19 +257,45 @@ memcached_return_t memcached_fetch_execute(memcached_st *ptr, uint32_t number_of_callbacks) { memcached_result_st *result= &ptr->result; - memcached_return_t rc= MEMCACHED_FAILURE; + memcached_return_t rc; + bool some_errors= false; - while ((result= memcached_fetch_result(ptr, result, &rc)) != NULL) + while ((result= memcached_fetch_result(ptr, result, &rc))) { - if (rc == MEMCACHED_SUCCESS) + if (memcached_failed(rc) and rc == MEMCACHED_NOTFOUND) { - for (uint32_t x= 0; x < number_of_callbacks; x++) + continue; + } + else if (memcached_failed(rc)) + { + memcached_set_error(*ptr, rc, MEMCACHED_AT); + some_errors= true; + continue; + } + + for (uint32_t x= 0; x < number_of_callbacks; x++) + { + memcached_return_t ret= (*callback[x])(ptr, result, context); + if (memcached_failed(ret)) { - rc= (*callback[x])(ptr, result, context); - if (rc != MEMCACHED_SUCCESS) - break; + some_errors= true; + memcached_set_error(*ptr, ret, MEMCACHED_AT); + break; } } } + + if (some_errors) + { + return MEMCACHED_SOME_ERRORS; + } + + // If we were able to run all keys without issue we return + // MEMCACHED_SUCCESS + if (memcached_success(rc)) + { + return MEMCACHED_SUCCESS; + } + return rc; }