MEM_HASH_WITH_PREFIX_KEY= (1 << 13),
MEM_NOREPLY= (1 << 14),
MEM_USE_UDP= (1 << 15),
- MEM_AUTO_EJECT_HOSTS= (1 << 16)
+ MEM_AUTO_EJECT_HOSTS= (1 << 16),
+ MEM_RANDOMIZE_REPLICA_READ= (1 << 17)
} memcached_flags;
/* Hashing algo */
case MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS:
set_behavior_flag(ptr, MEM_AUTO_EJECT_HOSTS, data);
break;
+ case MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ:
+ set_behavior_flag(ptr, MEM_RANDOMIZE_REPLICA_READ, data);
+ break;
default:
/* Shouldn't get here */
WATCHPOINT_ASSERT(flag);
case MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS:
temp_flag= MEM_AUTO_EJECT_HOSTS;
break;
+ case MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ:
+ temp_flag= MEM_RANDOMIZE_REPLICA_READ;
+ break;
default:
WATCHPOINT_ASSERT(flag);
break;
MEMCACHED_BEHAVIOR_USE_UDP,
MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS,
MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
- MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE
+ MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
+ MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ
} memcached_behavior;
#define MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED 0
size_t number_of_keys)
{
memcached_return rc= MEMCACHED_NOTFOUND;
- uint32_t x;
+ uint32_t x, start = 0;
+ uint64_t randomize_read = memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ);
+
+ if (randomize_read) {
+ srandom((uint32_t) time(NULL));
+ start = (uint32_t)(random() % (ptr->number_of_replicas + 1));
+ }
+ /* Loop for each replica */
for (uint32_t replica= 0; replica <= ptr->number_of_replicas; ++replica)
{
- bool success= true;
-
+ bool success= true;
+
for (x= 0; x < number_of_keys; ++x)
{
+ uint32_t server;
+
if (hash[x] == ptr->number_of_hosts)
continue; /* Already successfully sent */
- uint32_t server= hash[x] + replica;
+ server= hash[x] + replica;
+
+ /* In case of randomized reads */
+ if (randomize_read) {
+ if ((server + start) <= (hash[x] + ptr->number_of_replicas)) {
+ server += start;
+ }
+ }
+
while (server >= ptr->number_of_hosts)
server -= ptr->number_of_hosts;