uint64_t item_cas;
struct memcached_st *root;
memcached_string_st value;
+ uint64_t numeric_value;
uint64_t count;
char item_key[MEMCACHED_MAX_KEY];
struct {
#include <libmemcached/common.h>
+static void auto_response(memcached_server_write_instance_st instance, const bool reply, memcached_return_t& rc, uint64_t* value)
+{
+ // If the message was successfully sent, then get the response, otherwise
+ // fail.
+ if (memcached_success(rc))
+ {
+ if (reply == false)
+ {
+ *value= UINT64_MAX;
+ return;
+ }
+
+ rc= memcached_response(instance, &instance->root->result);
+ }
+
+ if (memcached_success(rc))
+ {
+ *value= instance->root->result.numeric_value;
+ }
+ else
+ {
+ *value= UINT64_MAX;
+ }
+}
+
static memcached_return_t text_incr_decr(memcached_server_write_instance_st instance,
const bool is_incr,
const char *key, size_t key_length,
const uint64_t offset,
- const bool reply,
- uint64_t& numeric_value)
+ const bool reply)
{
char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
vector[1].buffer= "decr ";
}
- memcached_return_t rc= memcached_vdo(instance, vector, 7, true);
-
- if (reply == false)
- {
- return MEMCACHED_SUCCESS;
- }
-
- if (memcached_failed(rc))
- {
- numeric_value= UINT64_MAX;
- return rc;
- }
-
- rc= memcached_response(instance, buffer, sizeof(buffer), NULL, numeric_value);
-
- return memcached_set_error(*instance, rc, MEMCACHED_AT);
+ return memcached_vdo(instance, vector, 7, true);
}
static memcached_return_t binary_incr_decr(memcached_server_write_instance_st instance,
const uint64_t offset,
const uint64_t initial,
const uint32_t expiration,
- const bool reply,
- uint64_t *value)
+ const bool reply)
{
if (reply == false)
{
{ key, key_length }
};
- memcached_return_t rc;
- if (memcached_failed(rc= memcached_vdo(instance, vector, 4, true)))
- {
- memcached_io_reset(instance);
- return MEMCACHED_WRITE_FAILURE;
- }
-
- if (reply == false)
- {
- return MEMCACHED_SUCCESS;
- }
-
- return memcached_response(instance, (char*)value, sizeof(*value), NULL);
+ return memcached_vdo(instance, vector, 4, true);
}
-memcached_return_t memcached_increment(memcached_st *ptr,
+memcached_return_t memcached_increment(memcached_st *memc,
const char *key, size_t key_length,
uint32_t offset,
uint64_t *value)
{
- return memcached_increment_by_key(ptr, key, key_length, key, key_length, offset, value);
+ return memcached_increment_by_key(memc, key, key_length, key, key_length, offset, value);
}
-memcached_return_t memcached_decrement(memcached_st *ptr,
- const char *key, size_t key_length,
- uint32_t offset,
- uint64_t *value)
+static memcached_return_t increment_decrement_by_key(const protocol_binary_command command,
+ memcached_st *memc,
+ const char *group_key, size_t group_key_length,
+ const char *key, size_t key_length,
+ uint64_t offset,
+ uint64_t *value)
{
- return memcached_decrement_by_key(ptr, key, key_length, key, key_length, offset, value);
-}
-
-memcached_return_t memcached_increment_by_key(memcached_st *ptr,
- const char *group_key, size_t group_key_length,
- const char *key, size_t key_length,
- uint64_t offset,
- uint64_t *value)
-{
- memcached_return_t rc;
uint64_t local_value;
if (value == NULL)
{
value= &local_value;
}
- if (memcached_failed(rc= initialize_query(ptr, true)))
+ memcached_return_t rc;
+ if (memcached_failed(rc= initialize_query(memc, true)))
{
return rc;
}
- if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
+ if (memcached_failed(rc= memcached_key_test(*memc, (const char **)&key, &key_length, 1)))
{
- return rc;
+ return memcached_last_error(memc);
}
- uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
- memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
+ uint32_t server_key= memcached_generate_hash_with_redistribution(memc, group_key, group_key_length);
+ memcached_server_write_instance_st instance= memcached_server_instance_fetch(memc, server_key);
bool reply= memcached_is_replying(instance->root);
- LIBMEMCACHED_MEMCACHED_INCREMENT_START();
- if (memcached_is_binary(ptr))
+ if (memcached_is_binary(memc))
{
- rc= binary_incr_decr(instance, PROTOCOL_BINARY_CMD_INCREMENT,
+ rc= binary_incr_decr(instance, command,
key, key_length,
uint64_t(offset), 0, MEMCACHED_EXPIRATION_NOT_ADD,
- reply,
- value);
+ reply);
}
else
{
- rc= text_incr_decr(instance, true, key, key_length, offset, reply, *value);
+ rc= text_incr_decr(instance,
+ command == PROTOCOL_BINARY_CMD_INCREMENT ? true : false,
+ key, key_length,
+ offset, reply);
}
- LIBMEMCACHED_MEMCACHED_INCREMENT_END();
+ auto_response(instance, reply, rc, value);
return rc;
}
-memcached_return_t memcached_decrement_by_key(memcached_st *ptr,
- const char *group_key, size_t group_key_length,
- const char *key, size_t key_length,
- uint64_t offset,
- uint64_t *value)
+static memcached_return_t increment_decrement_with_initial_by_key(const protocol_binary_command command,
+ memcached_st *memc,
+ const char *group_key,
+ size_t group_key_length,
+ const char *key,
+ size_t key_length,
+ uint64_t offset,
+ uint64_t initial,
+ time_t expiration,
+ uint64_t *value)
{
uint64_t local_value;
if (value == NULL)
}
memcached_return_t rc;
- if (memcached_failed(rc= initialize_query(ptr, true)))
+ if (memcached_failed(rc= initialize_query(memc, true)))
{
return rc;
}
- if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
+ if (memcached_failed(rc= memcached_key_test(*memc, (const char **)&key, &key_length, 1)))
{
- return rc;
+ return memcached_last_error(memc);
}
-
- uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
- memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
+ uint32_t server_key= memcached_generate_hash_with_redistribution(memc, group_key, group_key_length);
+ memcached_server_write_instance_st instance= memcached_server_instance_fetch(memc, server_key);
bool reply= memcached_is_replying(instance->root);
- LIBMEMCACHED_MEMCACHED_DECREMENT_START();
- if (memcached_is_binary(ptr))
+ if (memcached_is_binary(memc))
{
- rc= binary_incr_decr(instance, PROTOCOL_BINARY_CMD_DECREMENT,
+ rc= binary_incr_decr(instance, command,
key, key_length,
- offset, 0, MEMCACHED_EXPIRATION_NOT_ADD,
- reply,
- value);
+ offset, initial, uint32_t(expiration),
+ reply);
+
}
else
{
- rc= text_incr_decr(instance, false, key, key_length, offset, reply, *value);
+ rc= memcached_set_error(*memc, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
+ memcached_literal_param("memcached_increment_with_initial_by_key() is not supported via the ASCII protocol"));
}
+ auto_response(instance, reply, rc, value);
+
+ return rc;
+}
+
+memcached_return_t memcached_decrement(memcached_st *memc,
+ const char *key, size_t key_length,
+ uint32_t offset,
+ uint64_t *value)
+{
+ return memcached_decrement_by_key(memc, key, key_length, key, key_length, offset, value);
+}
+
+
+memcached_return_t memcached_increment_by_key(memcached_st *memc,
+ const char *group_key, size_t group_key_length,
+ const char *key, size_t key_length,
+ uint64_t offset,
+ uint64_t *value)
+{
+ LIBMEMCACHED_MEMCACHED_INCREMENT_START();
+ memcached_return_t rc= increment_decrement_by_key(PROTOCOL_BINARY_CMD_INCREMENT,
+ memc,
+ group_key, group_key_length,
+ key, key_length,
+ offset, value);
+
+ LIBMEMCACHED_MEMCACHED_INCREMENT_END();
+
+ return rc;
+}
+
+memcached_return_t memcached_decrement_by_key(memcached_st *memc,
+ const char *group_key, size_t group_key_length,
+ const char *key, size_t key_length,
+ uint64_t offset,
+ uint64_t *value)
+{
+ LIBMEMCACHED_MEMCACHED_DECREMENT_START();
+ memcached_return_t rc= increment_decrement_by_key(PROTOCOL_BINARY_CMD_DECREMENT,
+ memc,
+ group_key, group_key_length,
+ key, key_length,
+ offset, value);
LIBMEMCACHED_MEMCACHED_DECREMENT_END();
return rc;
}
-memcached_return_t memcached_increment_with_initial(memcached_st *ptr,
+memcached_return_t memcached_increment_with_initial(memcached_st *memc,
const char *key,
size_t key_length,
uint64_t offset,
time_t expiration,
uint64_t *value)
{
- return memcached_increment_with_initial_by_key(ptr, key, key_length,
+ return memcached_increment_with_initial_by_key(memc, key, key_length,
key, key_length,
offset, initial, expiration, value);
}
-memcached_return_t memcached_increment_with_initial_by_key(memcached_st *ptr,
- const char *group_key,
- size_t group_key_length,
- const char *key,
- size_t key_length,
- uint64_t offset,
- uint64_t initial,
- time_t expiration,
- uint64_t *value)
+memcached_return_t memcached_increment_with_initial_by_key(memcached_st *memc,
+ const char *group_key,
+ size_t group_key_length,
+ const char *key,
+ size_t key_length,
+ uint64_t offset,
+ uint64_t initial,
+ time_t expiration,
+ uint64_t *value)
{
- uint64_t local_value;
- if (value == NULL)
- {
- value= &local_value;
- }
-
- memcached_return_t rc;
- if (memcached_failed(rc= initialize_query(ptr, true)))
- {
- return rc;
- }
-
- if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
- {
- return rc;
- }
-
- uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
- memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
-
- bool reply= memcached_is_replying(instance->root);
-
LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_START();
- if (memcached_is_binary(ptr))
- {
- rc= binary_incr_decr(instance, PROTOCOL_BINARY_CMD_INCREMENT,
- key, key_length,
- offset, initial, uint32_t(expiration),
- reply,
- value);
- }
- else
- {
- rc= memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
- memcached_literal_param("memcached_increment_with_initial_by_key() is not supported via the ASCII protocol"));
- }
-
+ memcached_return_t rc= increment_decrement_with_initial_by_key(PROTOCOL_BINARY_CMD_INCREMENT,
+ memc,
+ group_key, group_key_length,
+ key, key_length,
+ offset, initial, expiration, value);
LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_END();
return rc;
}
-memcached_return_t memcached_decrement_with_initial(memcached_st *ptr,
+memcached_return_t memcached_decrement_with_initial(memcached_st *memc,
const char *key,
size_t key_length,
uint64_t offset,
time_t expiration,
uint64_t *value)
{
- return memcached_decrement_with_initial_by_key(ptr, key, key_length,
+ return memcached_decrement_with_initial_by_key(memc, key, key_length,
key, key_length,
offset, initial, expiration, value);
}
-memcached_return_t memcached_decrement_with_initial_by_key(memcached_st *ptr,
+memcached_return_t memcached_decrement_with_initial_by_key(memcached_st *memc,
const char *group_key,
size_t group_key_length,
const char *key,
time_t expiration,
uint64_t *value)
{
- uint64_t local_value;
- if (value == NULL)
- {
- value= &local_value;
- }
-
- memcached_return_t rc;
- if (memcached_failed(rc= initialize_query(ptr, true)))
- {
- return rc;
- }
-
- if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
- {
- return rc;
- }
-
- uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
- memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
-
- bool reply= memcached_is_replying(instance->root);
-
-
LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_START();
- if (memcached_is_binary(ptr))
- {
- rc= binary_incr_decr(instance, PROTOCOL_BINARY_CMD_DECREMENT,
- key, key_length,
- offset, initial, uint32_t(expiration),
- reply,
- value);
- }
- else
- {
- rc= memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
- memcached_literal_param("memcached_decrement_with_initial_by_key() is not supported via the ASCII protocol"));
- }
+ memcached_return_t rc= increment_decrement_with_initial_by_key(PROTOCOL_BINARY_CMD_DECREMENT,
+ memc,
+ group_key, group_key_length,
+ key, key_length,
+ offset, initial, expiration, value);
LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_END();
if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
{
- return rc;
+ return memcached_last_error(ptr);
}
if (expiration)
bool is_group_key_set= false;
if (group_key and group_key_length)
{
- if (memcached_failed(memcached_key_test(*ptr, (const char * const *)&group_key, &group_key_length, 1)))
- {
- 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;
}
*/
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 (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);
static memcached_return_t textual_read_one_response(memcached_server_write_instance_st ptr,
char *buffer, const size_t buffer_length,
- memcached_result_st *result,
- uint64_t& numeric_value)
+ memcached_result_st *result)
{
- numeric_value= UINT64_MAX;
size_t total_read;
memcached_return_t rc= memcached_io_readline(ptr, buffer, buffer_length, total_read);
if (auto_return_value == ULLONG_MAX and errno == ERANGE)
{
+ result->numeric_value= UINT64_MAX;
return memcached_set_error(*ptr, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT,
memcached_literal_param("Numeric response was out of range"));
}
else if (errno == EINVAL)
{
+ result->numeric_value= UINT64_MAX;
return memcached_set_error(*ptr, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT,
memcached_literal_param("Numeric response was out of range"));
}
- numeric_value= uint64_t(auto_return_value);
+ result->numeric_value= uint64_t(auto_return_value);
WATCHPOINT_STRING(buffer);
return MEMCACHED_SUCCESS;
case PROTOCOL_BINARY_CMD_INCREMENT:
case PROTOCOL_BINARY_CMD_DECREMENT:
{
- if (bodylen != sizeof(uint64_t) or buffer_length != sizeof(uint64_t))
+ if (bodylen != sizeof(uint64_t))
{
+ result->numeric_value= UINT64_MAX;
return memcached_set_error(*ptr, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT);
}
- WATCHPOINT_ASSERT(bodylen == buffer_length);
uint64_t val;
if ((rc= memcached_safe_read(ptr, &val, sizeof(val))) != MEMCACHED_SUCCESS)
{
- WATCHPOINT_ERROR(rc);
+ result->numeric_value= UINT64_MAX;
return MEMCACHED_UNKNOWN_READ_FAILURE;
}
- val= memcached_ntohll(val);
- memcpy(buffer, &val, sizeof(val));
+ result->numeric_value= memcached_ntohll(val);
}
break;
static memcached_return_t _read_one_response(memcached_server_write_instance_st ptr,
char *buffer, const size_t buffer_length,
- memcached_result_st *result,
- uint64_t& numeric_value)
+ memcached_result_st *result)
{
memcached_server_response_decrement(ptr);
}
else
{
- rc= textual_read_one_response(ptr, buffer, buffer_length, result, numeric_value);
+ rc= textual_read_one_response(ptr, buffer, buffer_length, result);
assert(rc != MEMCACHED_PROTOCOL_ERROR);
}
memcached_return_t memcached_read_one_response(memcached_server_write_instance_st ptr,
memcached_result_st *result)
{
- uint64_t numeric_value;
char buffer[SMALL_STRING_LEN];
if (memcached_is_udp(ptr->root))
}
- return _read_one_response(ptr, buffer, sizeof(buffer), result, numeric_value);
+ return _read_one_response(ptr, buffer, sizeof(buffer), result);
}
memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
- char *buffer, size_t buffer_length,
memcached_result_st *result)
{
- uint64_t numeric_value;
+ char buffer[1024];
- return memcached_response(ptr, buffer, buffer_length, result, numeric_value);
+ return memcached_response(ptr, buffer, sizeof(buffer), result);
}
memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
char *buffer, size_t buffer_length,
- memcached_result_st *result,
- uint64_t& numeric_value)
+ memcached_result_st *result)
{
if (memcached_is_udp(ptr->root))
{
while (memcached_server_response_count(ptr) > 1)
{
- memcached_return_t rc= _read_one_response(ptr, buffer, buffer_length, junked_result_ptr, numeric_value);
+ memcached_return_t rc= _read_one_response(ptr, buffer, buffer_length, junked_result_ptr);
// @TODO should we return an error on another but a bad read case?
if (
memcached_result_free(junked_result_ptr);
}
- return _read_one_response(ptr, buffer, buffer_length, result, numeric_value);
+ return _read_one_response(ptr, buffer, buffer_length, result);
}
memcached_result_st *result);
memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
- char *buffer, size_t buffer_length,
memcached_result_st *result);
memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
char *buffer, size_t buffer_length,
- memcached_result_st *result,
- uint64_t& numeric_value);
+ memcached_result_st *result);
self->key_length= 0;
self->item_cas= 0;
self->root= memc;
+ self->numeric_value= UINT64_MAX;
self->count= 0;
self->item_key[0]= 0;
}
ptr->item_flags= 0;
ptr->item_cas= 0;
ptr->item_expiration= 0;
+ ptr->numeric_value= UINT64_MAX;
}
void memcached_result_free(memcached_result_st *ptr)
}
memcached_string_free(&ptr->value);
+ ptr->numeric_value= UINT64_MAX;
if (memcached_is_allocated(ptr))
{
return NULL;
}
- if (memcached_failed(rc= (memcached_key_test(*ptr, (const char **)&key, &key_length, 1))))
+ if (memcached_failed((memcached_key_test(*ptr, (const char **)&key, &key_length, 1))))
{
- *error= rc;
+ *error= memcached_last_error(ptr);
return NULL;
}
return rc;
}
- if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
+ if (memcached_failed(memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
{
- return rc;
+ return memcached_last_error(ptr);
}
uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
-# visibility.m4 serial 3 (gettext-0.18)
-dnl Copyright (C) 2005, 2008-2010 Free Software Foundation, Inc.
+# visibility.m4 serial 4 (gettext-0.18.2)
+dnl Copyright (C) 2005, 2008, 2010-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_CACHE_VAL([gl_cv_cc_vis_werror], [
gl_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
- AC_TRY_COMPILE([], [],
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
[gl_cv_cc_vis_werror=yes],
[gl_cv_cc_vis_werror=no])
CFLAGS="$gl_save_CFLAGS"])
if test $gl_cv_cc_vis_werror = yes; then
CFLAGS="$CFLAGS -Werror"
fi
- AC_TRY_COMPILE(
- [extern __attribute__((__visibility__("hidden"))) int hiddenvar;
- extern __attribute__((__visibility__("default"))) int exportedvar;
- extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
- extern __attribute__((__visibility__("default"))) int exportedfunc (void);
- void dummyfunc (void) {}],
- [],
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[extern __attribute__((__visibility__("hidden"))) int hiddenvar;
+ extern __attribute__((__visibility__("default"))) int exportedvar;
+ extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
+ extern __attribute__((__visibility__("default"))) int exportedfunc (void);
+ void dummyfunc (void) {}
+ ]],
+ [[]])],
[gl_cv_cc_visibility=yes],
[gl_cv_cc_visibility=no])
CFLAGS="$gl_save_CFLAGS"])
test_compare(query_id +1, memcached_query_id(memc_clone));
query_id= memcached_query_id(memc_clone);
- test_compare(MEMCACHED_BAD_KEY_PROVIDED,
+ // Grouping keys are not required to follow normal key behaviors
+ test_compare(MEMCACHED_SUCCESS,
memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1));
test_compare(query_id +1, memcached_query_id(memc_clone));
{"mget", false, (test_callback_fn*)replication_mget_test },
{"delete", true, (test_callback_fn*)replication_delete_test },
{"rand_mget", false, (test_callback_fn*)replication_randomize_mget_test },
+ {"miss", false, (test_callback_fn*)replication_miss_test },
{"fail", false, (test_callback_fn*)replication_randomize_mget_fail_test },
{0, 0, (test_callback_fn*)0}
};
memcached_free(memc_clone);
return TEST_SUCCESS;
}
+
+/* Test that single miss does not cause replica reads to fail */
+test_return_t replication_miss_test(memcached_st *memc)
+{
+ test_skip(true, false);
+
+ memcached_st *memc_repl= memcached_clone(NULL, memc);
+ test_true(memc_repl);
+ memcached_st *memc_single= memcached_clone(NULL, memc);
+ test_true(memc_single);
+
+ const char *value = "my_value";
+ size_t vlen;
+ uint32_t flags;
+
+ /* this test makes sense only with 2 or more servers */
+ test_true(memcached_server_count(memc_repl) > 1);
+
+ /* Consistent hash */
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set_distribution(memc_repl, MEMCACHED_DISTRIBUTION_CONSISTENT));
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set_distribution(memc_single, MEMCACHED_DISTRIBUTION_CONSISTENT));
+
+ /* The first clone writes to all servers */
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc_repl, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc_repl, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
+ memcached_server_count(memc_repl)));
+
+ /* Write to servers */
+ {
+ memcached_return_t rc= memcached_set(memc_repl,
+ test_literal_param(__func__),
+ value, strlen(value),
+ time_t(1200), uint32_t(0));
+ test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
+ }
+
+ /* Use the second clone to remove the key from primary server.
+ This should remove the key from only one server */
+ {
+ memcached_return_t rc= memcached_delete(memc_single,
+ test_literal_param(__func__),
+ 0);
+ test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
+ }
+
+ /* Remove the server where the key was deleted */
+ {
+#if 0
+ memcached_return_t rc;
+ const memcached_server_st *instance= memcached_server_by_key(memc_single,
+ test_literal_param(__func__),
+ &rc);
+ test_compare(MEMCACHED_SUCCESS, rc);
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_server_remove(instance));
+#endif
+ }
+
+ /* Test that others still have it */
+ {
+ memcached_return_t rc;
+ char *get_value= memcached_get(memc_single,
+ test_literal_param(__func__),
+ &vlen, &flags, &rc);
+ test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
+ test_true(get_value and strcmp(get_value, value) == 0);
+ free(get_value);
+ }
+
+ /* This read should still return the value as we have it on other servers */
+ {
+ memcached_return_t rc;
+ char *get_value= memcached_get(memc_repl,
+ test_literal_param(__func__),
+ &vlen, &flags, &rc);
+ test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+ test_true(get_value and strcmp(get_value, value) == 0);
+ free(get_value);
+ }
+
+ memcached_free(memc_repl);
+ memcached_free(memc_single);
+
+ return TEST_SUCCESS;
+}
#pragma once
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBTEST_LOCAL
test_return_t replication_set_test(memcached_st *memc);
-LIBTEST_LOCAL
test_return_t replication_get_test(memcached_st *memc);
-LIBTEST_LOCAL
test_return_t replication_mget_test(memcached_st *memc);
-LIBTEST_LOCAL
test_return_t replication_delete_test(memcached_st *memc);
-LIBTEST_LOCAL
test_return_t replication_randomize_mget_test(memcached_st *memc);
-LIBTEST_LOCAL
test_return_t replication_randomize_mget_fail_test(memcached_st *memc);
-#ifdef __cplusplus
-}
-#endif
+test_return_t replication_miss_test(memcached_st *memc);