From 5ba025a6fda8479e8f38ab690b0f89d4d1c4ffc3 Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Wed, 21 Dec 2011 16:28:45 -0800 Subject: [PATCH] Update to use vector for delete. --- libmemcached/delete.cc | 23 ++++---- libmemcached/do.cc | 8 +-- libmemcached/do.hpp | 11 ++-- libmemcached/io.cc | 31 +++++++++-- libmemcached/io.h | 6 +++ tests/libmemcached-1.0/mem_functions.cc | 33 ++++++++---- tests/mem_udp.cc | 72 ++++++++++++++++++++++--- 7 files changed, 139 insertions(+), 45 deletions(-) diff --git a/libmemcached/delete.cc b/libmemcached/delete.cc index ed7510a6..f5a60e33 100644 --- a/libmemcached/delete.cc +++ b/libmemcached/delete.cc @@ -52,18 +52,16 @@ static inline memcached_return_t ascii_delete(memcached_st *ptr, bool& reply, bool& flush) { - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - int send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "delete %.*s%.*s%s\r\n", - memcached_print_array(ptr->_namespace), - (int)key_length, key, - reply ? "" : " noreply"); - - if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0) + struct libmemcached_io_vector_st vector[]= { - return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, - memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)")); - } + { memcached_literal_param("delete ") }, + { memcached_array_string(ptr->_namespace), memcached_array_size(ptr->_namespace) }, + { key, key_length }, + { " noreply", reply ? 0 : memcached_literal_param_size(" noreply") }, + { memcached_literal_param("\r\n") } + }; + + size_t send_length= io_vector_total_size(vector, 5); if (ptr->flags.use_udp and flush == false) { @@ -78,7 +76,8 @@ static inline memcached_return_t ascii_delete(memcached_st *ptr, } } - return memcached_do(instance, buffer, (size_t)send_length, flush); + /* Send command header */ + return memcached_vdo(instance, vector, 5, flush); } static inline memcached_return_t binary_delete(memcached_st *ptr, diff --git a/libmemcached/do.cc b/libmemcached/do.cc index 99dba559..88d8d843 100644 --- a/libmemcached/do.cc +++ b/libmemcached/do.cc @@ -13,8 +13,8 @@ memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const void *command, - size_t command_length, - bool with_flush) + const size_t command_length, + const bool with_flush) { assert_msg(command_length, "Programming error, somehow a command had a length of zero"); assert_msg(command, "Programming error, somehow a command was NULL"); @@ -26,8 +26,8 @@ memcached_return_t memcached_do(memcached_server_write_instance_st ptr, memcached_return_t memcached_vdo(memcached_server_write_instance_st ptr, const struct libmemcached_io_vector_st *vector, - size_t count, - bool with_flush) + const size_t count, + const bool with_flush) { memcached_return_t rc; diff --git a/libmemcached/do.hpp b/libmemcached/do.hpp index f1232662..0bd0e9b3 100644 --- a/libmemcached/do.hpp +++ b/libmemcached/do.hpp @@ -37,13 +37,12 @@ #pragma once -LIBMEMCACHED_LOCAL memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const void *commmand, - size_t command_length, - bool with_flush); + const size_t command_length, + const bool with_flush); -LIBMEMCACHED_LOCAL memcached_return_t memcached_vdo(memcached_server_write_instance_st ptr, - const struct libmemcached_io_vector_st *vector, size_t count, - bool with_flush); + const struct libmemcached_io_vector_st *vector, + const size_t count, + const bool with_flush); diff --git a/libmemcached/io.cc b/libmemcached/io.cc index 22cd474c..10a59b68 100644 --- a/libmemcached/io.cc +++ b/libmemcached/io.cc @@ -692,6 +692,18 @@ ssize_t memcached_io_write(memcached_server_write_instance_st ptr, return _io_write(ptr, buffer, length, with_flush); } +size_t io_vector_total_size(libmemcached_io_vector_st* vector, const size_t number_of) +{ + ssize_t total= 0; + + for (size_t x= 0; x < number_of; x++) + { + total+= vector->length; + } + + return total; +} + ssize_t memcached_io_writev(memcached_server_write_instance_st ptr, const struct libmemcached_io_vector_st *vector, size_t number_of, bool with_flush) @@ -702,11 +714,14 @@ ssize_t memcached_io_writev(memcached_server_write_instance_st ptr, { ssize_t returnable; - if ((returnable= _io_write(ptr, vector->buffer, vector->length, false)) == -1) + if (vector->length) { - return -1; + if ((returnable= _io_write(ptr, vector->buffer, vector->length, false)) == -1) + { + return -1; + } + total+= returnable; } - total+= returnable; } if (with_flush) @@ -858,7 +873,7 @@ memcached_return_t memcached_io_readline(memcached_server_write_instance_st ptr, total_nr= 0; bool line_complete= false; - while (not line_complete) + while (line_complete == false) { if (ptr->read_buffer_length == 0) { @@ -880,7 +895,9 @@ memcached_return_t memcached_io_readline(memcached_server_write_instance_st ptr, } if (*buffer_ptr == '\n') + { line_complete= true; + } ++buffer_ptr; ++total_nr; @@ -891,7 +908,9 @@ memcached_return_t memcached_io_readline(memcached_server_write_instance_st ptr, { *buffer_ptr = *ptr->read_ptr; if (*buffer_ptr == '\n') + { line_complete = true; + } --ptr->read_buffer_length; ++ptr->read_ptr; ++total_nr; @@ -899,7 +918,9 @@ memcached_return_t memcached_io_readline(memcached_server_write_instance_st ptr, } if (total_nr == size) + { return MEMCACHED_PROTOCOL_ERROR; + } } return MEMCACHED_SUCCESS; @@ -908,7 +929,9 @@ memcached_return_t memcached_io_readline(memcached_server_write_instance_st ptr, memcached_return_t memcached_io_init_udp_header(memcached_server_write_instance_st ptr, uint16_t thread_id) { if (thread_id > UDP_REQUEST_ID_MAX_THREAD_ID) + { return MEMCACHED_FAILURE; + } struct udp_datagram_header_st *header= (struct udp_datagram_header_st *)ptr->write_buffer; header->request_id= htons((uint16_t) (generate_udp_request_thread_id(thread_id))); diff --git a/libmemcached/io.h b/libmemcached/io.h index 6d3e2fa2..f1d2a450 100644 --- a/libmemcached/io.h +++ b/libmemcached/io.h @@ -80,3 +80,9 @@ ssize_t memcached_io_writev(memcached_server_write_instance_st ptr, #ifdef __cplusplus } #endif + +#ifdef __cplusplus + +size_t io_vector_total_size(libmemcached_io_vector_st* vector, const size_t number_of); + +#endif diff --git a/tests/libmemcached-1.0/mem_functions.cc b/tests/libmemcached-1.0/mem_functions.cc index 29009ce3..40e0ee8d 100644 --- a/tests/libmemcached-1.0/mem_functions.cc +++ b/tests/libmemcached-1.0/mem_functions.cc @@ -112,6 +112,16 @@ static test_return_t pre_binary(memcached_st *memc) return TEST_SUCCESS; } +static bool return_value_based_on_buffering(memcached_st *memc) +{ + if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS)) + { + return MEMCACHED_BUFFERED; + } + + return MEMCACHED_SUCCESS; +} + static memcached_st * create_single_instance_memcached(const memcached_st *original_memc, const char *options) { /* @@ -820,17 +830,18 @@ static test_return_t replace_test(memcached_st *memc) static test_return_t delete_test(memcached_st *memc) { - memcached_return_t rc; - const char *key= "foo"; - const char *value= "when we sanitize"; - - rc= memcached_set(memc, key, strlen(key), - value, strlen(value), - (time_t)0, (uint32_t)0); - test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED); + test_compare(return_value_based_on_buffering(memc), + memcached_set(memc, + test_literal_param(__func__), + test_literal_param("when we sanitize"), + time_t(0), uint32_t(0))); - rc= memcached_delete(memc, key, strlen(key), (time_t)0); - test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED); + memcached_return_t rc= memcached_delete(memc, + test_literal_param(__func__), + time_t(0)); + test_compare_hint(MEMCACHED_SUCCESS, + rc, + memcached_last_error_message(memc)); return TEST_SUCCESS; } @@ -1042,7 +1053,7 @@ static test_return_t get_test(memcached_st *memc) uint64_t query_id= memcached_query_id(memc); rc= memcached_delete(memc, key, strlen(key), (time_t)0); - test_true(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND); + test_true_got(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND, memcached_last_error_message(memc)); test_compare(query_id +1, memcached_query_id(memc)); string= memcached_get(memc, key, strlen(key), diff --git a/tests/mem_udp.cc b/tests/mem_udp.cc index 16fc1c73..227cea63 100644 --- a/tests/mem_udp.cc +++ b/tests/mem_udp.cc @@ -1,11 +1,41 @@ -/* libMemcached Functions Test - * Copyright (C) 2006-2009 Brian Aker - * All rights reserved. +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * Libmemcached library + * + * Copyright (C) 2011 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 + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * The names of its contributors may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Use and distribution licensed under the BSD license. See - * the COPYING file in the parent directory for full text. */ + /* Sample test application. */ @@ -111,8 +141,25 @@ static test_return_t init_udp(memcached_st *memc) return TEST_SUCCESS; } +static test_return_t init_udp_valgrind(memcached_st *memc) +{ + if (getenv("TESTS_ENVIRONMENT")) + { + return TEST_SKIPPED; + } + + test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, true)); + + return TEST_SUCCESS; +} + static test_return_t binary_init_udp(memcached_st *memc) { + if (getenv("TESTS_ENVIRONMENT")) + { + return TEST_SKIPPED; + } + test_skip(TEST_SUCCESS, pre_binary(memc)); return init_udp(memc); @@ -171,7 +218,13 @@ static test_return_t set_udp_behavior_test(memcached_st *memc) static test_return_t udp_set_test(memcached_st *memc) { - unsigned int num_iters= 1025; //request id rolls over at 1024 + // Assume we are running under valgrind, and bail + if (getenv("TESTS_ENVIRONMENT")) + { + return TEST_SUCCESS; + } + + const unsigned int num_iters= 1025; //request id rolls over at 1024 test_true(memc); @@ -229,7 +282,10 @@ static test_return_t udp_set_too_big_test(memcached_st *memc) memset(value, int('f'), sizeof(value)); - test_compare_hint(MEMCACHED_WRITE_FAILURE, memcached_set(memc, test_literal_param("bar"), value, sizeof(value), time_t(0), uint32_t(0)), + test_compare_hint(MEMCACHED_WRITE_FAILURE, + memcached_set(memc, test_literal_param("bar"), + test_literal_param(value), + time_t(0), uint32_t(0)), memcached_last_error_message(memc)); return post_udp_op_check(memc, expected_ids); @@ -448,7 +504,7 @@ test_st upd_io_tests[] ={ collection_st collection[] ={ {"udp_setup", (test_callback_fn*)init_udp, 0, udp_setup_server_tests}, - {"udp_io", (test_callback_fn*)init_udp, 0, upd_io_tests}, + {"udp_io", (test_callback_fn*)init_udp_valgrind, 0, upd_io_tests}, {"udp_binary_io", (test_callback_fn*)binary_init_udp, 0, upd_io_tests}, {0, 0, 0, 0} }; -- 2.30.2