X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Ffetch.cc;h=70e5bf75ef30989c5845a276357bf84553e799bf;hb=674c7578fa870c3b57e81e765c355ce98434b310;hp=8977753489a33835f73d640289869893ab16442c;hpb=ea7a5dd332779c77eaef6d14eac58372cb3439e1;p=m6w6%2Flibmemcached diff --git a/libmemcached/fetch.cc b/libmemcached/fetch.cc index 89777534..70e5bf75 100644 --- a/libmemcached/fetch.cc +++ b/libmemcached/fetch.cc @@ -44,77 +44,166 @@ 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 (not error) + if (error == NULL) + { error= &unused; + } + + if (ptr == NULL) + { + *error= MEMCACHED_INVALID_ARGUMENTS; + return NULL; + } - if (ptr->flags.use_udp) + 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)) { - 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 + org::libmemcached::Instance *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) @@ -127,6 +216,27 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, } } + 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 */ if (memcached_is_allocated(result)) { @@ -134,6 +244,7 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, } else { + result->count= 0; memcached_string_reset(&result->value); } @@ -146,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) + { + continue; + } + else if (memcached_failed(rc)) { - for (uint32_t x= 0; x < number_of_callbacks; x++) + 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; }