X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fget.cc;h=1deb39765ea7d2a0162acfb9a6d67e789ab1f3b0;hb=50f05a9503f10bbc6df4eb3ea02c7cf5e36fd6c9;hp=bcc468a012414f86dbf8109be7c93b5f5bb2881b;hpb=8985b4b6e67215904383dac7fca792b4d9be89c4;p=m6w6%2Flibmemcached diff --git a/libmemcached/get.cc b/libmemcached/get.cc index bcc468a0..1deb3976 100644 --- a/libmemcached/get.cc +++ b/libmemcached/get.cc @@ -36,7 +36,6 @@ */ #include -#include /* What happens if no servers exist? @@ -67,63 +66,73 @@ char *memcached_get_by_key(memcached_st *ptr, uint32_t *flags, memcached_return_t *error) { - unlikely (ptr->flags.use_udp) + memcached_return_t unused; + if (error == NULL) { - if (value_length) - *value_length= 0; - - *error= memcached_set_error(*ptr, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT); - return NULL; + error= &unused; } - uint64_t query_id= ptr->query_id; - (void)query_id; + uint64_t query_id= 0; + if (ptr) + { + query_id= ptr->query_id; + } /* Request the key */ *error= memcached_mget_by_key_real(ptr, group_key, group_key_length, - (const char * const *)&key, - &key_length, 1, false); - assert(ptr->query_id == query_id +1); - + (const char * const *)&key, &key_length, + 1, false); + if (ptr) + { + assert_msg(ptr->query_id == query_id +1, "Programmer error, the query_id was not incremented."); + } if (memcached_failed(*error)) { - if (memcached_has_current_error(*ptr)) // Find the most accurate error + if (ptr) { - *error= memcached_last_error(ptr); + if (memcached_has_current_error(*ptr)) // Find the most accurate error + { + *error= memcached_last_error(ptr); + } } if (value_length) + { *value_length= 0; + } return NULL; } char *value= memcached_fetch(ptr, NULL, NULL, value_length, flags, error); - assert(ptr->query_id == query_id +1); + assert_msg(ptr->query_id == query_id +1, "Programmer error, the query_id was not incremented."); /* This is for historical reasons */ if (*error == MEMCACHED_END) + { *error= MEMCACHED_NOTFOUND; + } if (value == NULL) { if (ptr->get_key_failure && *error == MEMCACHED_NOTFOUND) { - memcached_result_reset(&ptr->result); memcached_return_t rc= ptr->get_key_failure(ptr, key, key_length, &ptr->result); /* On all failure drop to returning NULL */ - if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED) + if (rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED) { if (rc == MEMCACHED_BUFFERED) { uint64_t latch; /* We use latch to track the state of the original socket */ latch= memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS); if (latch == 0) + { memcached_behavior_set(ptr, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1); + } rc= memcached_set(ptr, key, key_length, (memcached_result_value(&ptr->result)), @@ -132,7 +141,9 @@ char *memcached_get_by_key(memcached_st *ptr, (memcached_result_flags(&ptr->result))); if (rc == MEMCACHED_BUFFERED && latch == 0) + { memcached_behavior_set(ptr, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0); + } } else { @@ -148,26 +159,15 @@ char *memcached_get_by_key(memcached_st *ptr, *error= rc; *value_length= memcached_result_length(&ptr->result); *flags= memcached_result_flags(&ptr->result); - return memcached_string_c_copy(&ptr->result.value); + return memcached_string_take_value(&ptr->result.value); } } } - assert(ptr->query_id == query_id +1); + assert_msg(ptr->query_id == query_id +1, "Programmer error, the query_id was not incremented."); return NULL; } - size_t dummy_length; - uint32_t dummy_flags; - memcached_return_t dummy_error; - - char *dummy_value= memcached_fetch(ptr, NULL, NULL, - &dummy_length, &dummy_flags, - &dummy_error); - WATCHPOINT_ASSERT(dummy_length == 0); - WATCHPOINT_ASSERT(dummy_value == 0); - assert(ptr->query_id == query_id +1); - return value; } @@ -201,12 +201,12 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, unsigned int master_server_key= (unsigned int)-1; /* 0 is a valid server id! */ memcached_return_t rc; - if (memcached_failed(rc= initialize_query(ptr))) + if (memcached_failed(rc= initialize_query(ptr, true))) { return rc; } - unlikely (ptr->flags.use_udp) + if (memcached_is_udp(ptr)) { return memcached_set_error(*ptr, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT); } @@ -218,19 +218,14 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, return memcached_set_error(*ptr, MEMCACHED_NOTFOUND, MEMCACHED_AT, memcached_literal_param("number_of_keys was zero")); } - if (ptr->flags.verify_key && (memcached_key_test(keys, key_length, number_of_keys) == MEMCACHED_BAD_KEY_PROVIDED)) + if (memcached_failed(memcached_key_test(*ptr, keys, key_length, number_of_keys))) { - return memcached_set_error(*ptr, MEMCACHED_BAD_KEY_PROVIDED, MEMCACHED_AT, memcached_literal_param("A bad key value was provided")); + return memcached_last_error(ptr); } bool is_group_key_set= false; - if (group_key && group_key_length) + if (group_key and group_key_length) { - if (ptr->flags.verify_key and (memcached_key_test((const char * const *)&group_key, &group_key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED)) - { - return memcached_set_error(*ptr, MEMCACHED_BAD_KEY_PROVIDED, MEMCACHED_AT, memcached_literal_param("A bad group key was provided.")); - } - master_server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length); is_group_key_set= true; } @@ -243,22 +238,25 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, */ for (uint32_t x= 0; x < memcached_server_count(ptr); x++) { - memcached_server_write_instance_st instance= - memcached_server_instance_fetch(ptr, x); + memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x); if (memcached_server_response_count(instance)) { char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; if (ptr->flags.no_block) - (void)memcached_io_write(instance, NULL, 0, true); + { + memcached_io_write(instance); + } while(memcached_server_response_count(instance)) + { (void)memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, &ptr->result); + } } } - if (ptr->flags.binary_protocol) + if (memcached_is_binary(ptr)) { return binary_mget_by_key(ptr, master_server_key, is_group_key_set, keys, key_length, number_of_keys, mget_mode); @@ -292,12 +290,12 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, instance= memcached_server_instance_fetch(ptr, server_key); - struct libmemcached_io_vector_st vector[]= + libmemcached_io_vector_st vector[]= { - { get_command_length, get_command }, - { memcached_array_size(ptr->prefix_key), memcached_array_string(ptr->prefix_key) }, - { key_length[x], keys[x] }, - { 1, " " } + { get_command, get_command_length }, + { memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace) }, + { keys[x], key_length[x] }, + { memcached_literal_param(" ") } }; @@ -337,7 +335,9 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, LIBMEMCACHED_MEMCACHED_MGET_END(); if (memcached_failed(rc)) + { return rc; + } return memcached_set_error(*ptr, MEMCACHED_NO_SERVERS, MEMCACHED_AT); } @@ -413,10 +413,23 @@ memcached_return_t memcached_mget_execute_by_key(memcached_st *ptr, void *context, unsigned int number_of_callbacks) { - if ((ptr->flags.binary_protocol) == 0) - return MEMCACHED_NOT_SUPPORTED; - memcached_return_t rc; + if (memcached_failed(rc= initialize_query(ptr, false))) + { + return rc; + } + + if (memcached_is_udp(ptr)) + { + return memcached_set_error(*ptr, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT); + } + + if (memcached_is_binary(ptr) == false) + { + return memcached_set_error(*ptr, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT, + memcached_literal_param("ASCII protocol is not supported for memcached_mget_execute_by_key()")); + } + memcached_callback_st *original_callbacks= ptr->callbacks; memcached_callback_st cb= { callback, @@ -465,20 +478,26 @@ static memcached_return_t simple_binary_mget(memcached_st *ptr, { rc= memcached_connect(instance); if (memcached_failed(rc)) + { continue; + } } protocol_binary_request_getk request= { }; //= {.bytes= {0}}; request.message.header.request.magic= PROTOCOL_BINARY_REQ; if (mget_mode) + { request.message.header.request.opcode= PROTOCOL_BINARY_CMD_GETKQ; + } else + { request.message.header.request.opcode= PROTOCOL_BINARY_CMD_GETK; + } memcached_return_t vk; vk= memcached_validate_key_length(key_length[x], ptr->flags.binary_protocol); - unlikely (vk != MEMCACHED_SUCCESS) + if (vk != MEMCACHED_SUCCESS) { if (x > 0) { @@ -488,15 +507,15 @@ static memcached_return_t simple_binary_mget(memcached_st *ptr, return vk; } - request.message.header.request.keylen= htons((uint16_t)(key_length[x] + memcached_array_size(ptr->prefix_key))); + request.message.header.request.keylen= htons((uint16_t)(key_length[x] + memcached_array_size(ptr->_namespace))); request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES; - request.message.header.request.bodylen= htonl((uint32_t)( key_length[x] + memcached_array_size(ptr->prefix_key))); + request.message.header.request.bodylen= htonl((uint32_t)( key_length[x] + memcached_array_size(ptr->_namespace))); - struct libmemcached_io_vector_st vector[]= + libmemcached_io_vector_st vector[]= { - { sizeof(request.bytes), request.bytes }, - { memcached_array_size(ptr->prefix_key), memcached_array_string(ptr->prefix_key) }, - { key_length[x], keys[x] } + { request.bytes, sizeof(request.bytes) }, + { memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace) }, + { keys[x], key_length[x] } }; if (memcached_io_writev(instance, vector, 3, flush) == -1) @@ -527,12 +546,11 @@ static memcached_return_t simple_binary_mget(memcached_st *ptr, for (uint32_t x= 0; x < memcached_server_count(ptr); ++x) { - memcached_server_write_instance_st instance= - memcached_server_instance_fetch(ptr, x); + memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x); if (memcached_server_response_count(instance)) { - if (memcached_io_write(instance, NULL, 0, true) == -1) + if (memcached_io_write(instance) == false) { memcached_server_response_reset(instance); memcached_io_reset(instance); @@ -585,16 +603,21 @@ static memcached_return_t replication_binary_mget(memcached_st *ptr, server += start; while (server >= memcached_server_count(ptr)) + { server -= memcached_server_count(ptr); + } if (dead_servers[server]) + { continue; + } memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server); if (memcached_server_response_count(instance) == 0) { rc= memcached_connect(instance); + if (memcached_failed(rc)) { memcached_io_reset(instance); @@ -607,9 +630,9 @@ static memcached_return_t replication_binary_mget(memcached_st *ptr, protocol_binary_request_getk request= {}; request.message.header.request.magic= PROTOCOL_BINARY_REQ; request.message.header.request.opcode= PROTOCOL_BINARY_CMD_GETK; - request.message.header.request.keylen= htons((uint16_t)(key_length[x] + memcached_array_size(ptr->prefix_key))); + request.message.header.request.keylen= htons((uint16_t)(key_length[x] + memcached_array_size(ptr->_namespace))); request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES; - request.message.header.request.bodylen= htonl((uint32_t)(key_length[x] + memcached_array_size(ptr->prefix_key))); + request.message.header.request.bodylen= htonl((uint32_t)(key_length[x] + memcached_array_size(ptr->_namespace))); /* * We need to disable buffering to actually know that the request was @@ -621,11 +644,11 @@ static memcached_return_t replication_binary_mget(memcached_st *ptr, * that we might have processed some of the responses etc. For now, * just make sure we work _correctly_ */ - struct libmemcached_io_vector_st vector[]= + libmemcached_io_vector_st vector[]= { - { sizeof(request.bytes), request.bytes }, - { memcached_array_size(ptr->prefix_key), memcached_array_string(ptr->prefix_key) }, - { key_length[x], keys[x] } + { request.bytes, sizeof(request.bytes) }, + { memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace) }, + { keys[x], key_length[x] } }; if (memcached_io_writev(instance, vector, 3, true) == -1) @@ -641,7 +664,9 @@ static memcached_return_t replication_binary_mget(memcached_st *ptr, } if (success) + { break; + } } return rc; @@ -661,8 +686,8 @@ static memcached_return_t binary_mget_by_key(memcached_st *ptr, keys, key_length, number_of_keys, mget_mode); } - uint32_t* hash= static_cast(libmemcached_malloc(ptr, sizeof(uint32_t) * number_of_keys)); - bool* dead_servers= static_cast(libmemcached_calloc(ptr, memcached_server_count(ptr), sizeof(bool))); + uint32_t* hash= libmemcached_xvalloc(ptr, number_of_keys, uint32_t); + bool* dead_servers= libmemcached_xcalloc(ptr, memcached_server_count(ptr), bool); if (hash == NULL || dead_servers == NULL) {