memcached_behavior_set() changes the value of a particular option of the
client. It takes both a flag (listed below) and a value. For simple on or
-off options you just need to pass in a value of 1. Calls to
+off options you just need to pass in a value of 1. Calls to
memcached_behavior_set() will flush and reset all connections.
=over 4
=item MEMCACHED_BEHAVIOR_USE_UDP
Causes libmemcached(3) to use the UDP transport when communicating
-with a memcached server. Not all I/O operations are supported
+with a memcached server. Not all I/O operations are supported
when this behavior is enababled. The following operations will return
C<MEMCACHED_NOT_SUPPORTED> when executed with the MEMCACHED_BEHAVIOR_USE_UDP
enabled: memcached_version(), memcached_stat(), memcached_get(),
All other operations are supported but are executed in a 'fire-and-forget'
mode, in which once the client has executed the operation, no attempt
will be made to ensure the operation has been received and acted on by the
-server.
+server.
libmemcached(3) does not allow TCP and UDP servers to be shared within
the same libmemached(3) client 'instance'. An attempt to add a TCP server
=item MEMCACHED_BEHAVIOR_HASH
Makes the default hashing algorithm for keys use MD5. The value can be set
-to either MEMCACHED_HASH_DEFAULT, MEMCACHED_HASH_MD5, MEMCACHED_HASH_CRC, MEMCACHED_HASH_FNV1_64, MEMCACHED_HASH_FNV1A_64, MEMCACHED_HASH_FNV1_32, MEMCACHED_HASH_FNV1A_32, MEMCACHED_HASH_JENKINS, MEMCACHED_HASH_HSIEH, and MEMCACHED_HASH_MURMUR.
+to either MEMCACHED_HASH_DEFAULT, MEMCACHED_HASH_MD5, MEMCACHED_HASH_CRC, MEMCACHED_HASH_FNV1_64, MEMCACHED_HASH_FNV1A_64, MEMCACHED_HASH_FNV1_32, MEMCACHED_HASH_FNV1A_32, MEMCACHED_HASH_JENKINS, MEMCACHED_HASH_HSIEH, and MEMCACHED_HASH_MURMUR.
Each hash has it's advantages and it's weaknesses. If you dont know or dont care, just go with the default.
-Support for MEMCACHED_HASH_HSIEH is a compile time option that is disabled by default. To enable support for this hashing algorithm, configure and build libmemcached with the --enable-hash_hsieh.
+Support for MEMCACHED_HASH_HSIEH is a compile time option that is disabled by default. To enable support for this hashing algorithm, configure and build libmemcached with the --enable-hash_hsieh.
=item MEMCACHED_BEHAVIOR_DISTRIBUTION
Using this you can enable different means of distributing values to servers.
The default method is MEMCACHED_DISTRIBUTION_MODULA. You can enable
-consistent hashing by setting MEMCACHED_DISTRIBUTION_CONSISTENT.
-Consistent hashing delivers better distribution and allows servers to be
+consistent hashing by setting MEMCACHED_DISTRIBUTION_CONSISTENT.
+Consistent hashing delivers better distribution and allows servers to be
added to the cluster with minimal cache losses. Currently
MEMCACHED_DISTRIBUTION_CONSISTENT is an alias for the value
-MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA.
+MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA.
=item MEMCACHED_BEHAVIOR_CACHE_LOOKUPS
=item MEMCACHED_BEHAVIOR_KETAMA_HASH
Sets the hashing algorithm for host mapping on continuum. The value can be set
-to either MEMCACHED_HASH_DEFAULT, MEMCACHED_HASH_MD5, MEMCACHED_HASH_CRC, MEMCACHED_HASH_FNV1_64, MEMCACHED_HASH_FNV1A_64, MEMCACHED_HASH_FNV1_32, and MEMCACHED_HASH_FNV1A_32.
+to either MEMCACHED_HASH_DEFAULT, MEMCACHED_HASH_MD5, MEMCACHED_HASH_CRC, MEMCACHED_HASH_FNV1_64, MEMCACHED_HASH_FNV1A_64, MEMCACHED_HASH_FNV1_32, and MEMCACHED_HASH_FNV1A_32.
+
+=item MEMCACHED_BEHAVIOR_KETAMA_COMPAT
+
+Sets the compatibility mode. The value can be set to either
+MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED (this is the default) or
+MEMCACHED_KETAMA_COMPAT_SPY to be compatible with the SPY Memcached client
+for Java.
=item MEMCACHED_BEHAVIOR_POLL_TIMEOUT
Enabling buffered IO causes commands to "buffer" instead of being sent. Any
action that gets data causes this buffer to be be sent to the remote
connection. Quiting the connection or closing down the connection will also
-cause the buffered data to be pushed to the remote connection.
+cause the buffered data to be pushed to the remote connection.
=item MEMCACHED_BEHAVIOR_VERIFY_KEY
-Enabling this will cause libmemcached(3) to test all keys to verify that they
+Enabling this will cause libmemcached(3) to test all keys to verify that they
are valid keys.
=item MEMCACHED_BEHAVIOR_SORT_HOSTS
-Enabling this will cause hosts that are added to be placed in the host list in
+Enabling this will cause hosts that are added to be placed in the host list in
sorted order. This will defeat consisten hashing.
=item MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT
=item MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK
-Set this value to tune the number of messages that may be sent before
+Set this value to tune the number of messages that may be sent before
libmemcached should start to automatically drain the input queue. Setting
this value to high, may cause libmemcached to deadlock (trying to send data,
but the send will block because the input buffer in the kernel is full).
Set this value to tune the number of bytes that may be sent before
libmemcached should start to automatically drain the input queue (need
at least 10 IO requests sent without reading the input buffer). Setting
-this value to high, may cause libmemcached to deadlock (trying to send
+this value to high, may cause libmemcached to deadlock (trying to send
data, but the send will block because the input buffer in the kernel is full).
=item MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH
=item MEMCACHED_BEHAVIOR_NOREPLY
Set this value to specify that you really don't care about the result
-from your storage commands (set, add, replace, append, prepend).
+from your storage commands (set, add, replace, append, prepend).
=item MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS
=head1 NOTES
memcached_behavior_set() in version .17 was changed from taking a pointer
-to data value, to taking a uin64_t.
+to data value, to taking a uin64_t.
=head1 HOME
-#include "common.h"
+#include "common.h"
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
-/*
+/*
This function is used to modify the behavior of running client.
We quit all connections so we can reset the sockets.
ptr->flags&= ~temp_flag;
}
-memcached_return memcached_behavior_set(memcached_st *ptr,
- memcached_behavior flag,
+memcached_return memcached_behavior_set(memcached_st *ptr,
+ memcached_behavior flag,
uint64_t data)
{
switch (flag)
break;
case MEMCACHED_BEHAVIOR_SND_TIMEOUT:
ptr->snd_timeout= (int32_t)data;
- break;
+ break;
case MEMCACHED_BEHAVIOR_RCV_TIMEOUT:
ptr->rcv_timeout= (int32_t)data;
- break;
+ break;
case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT:
ptr->server_failure_limit= (uint32_t)data;
- break;
+ break;
case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL:
if (data)
set_behavior_flag(ptr, MEM_VERIFY_KEY, 0);
set_behavior_flag(ptr, MEM_BINARY_PROTOCOL, data);
- break;
+ break;
case MEMCACHED_BEHAVIOR_SUPPORT_CAS:
set_behavior_flag(ptr, MEM_SUPPORT_CAS, data);
break;
run_distribution(ptr);
break;
}
+ case MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE:
+ switch (data)
+ {
+ case MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED:
+ ptr->hash= MEMCACHED_HASH_MD5;
+ ptr->distribution= MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA;
+ break;
+ case MEMCACHED_KETAMA_COMPAT_SPY:
+ ptr->hash= MEMCACHED_HASH_MD5;
+ ptr->distribution= MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY;
+ break;
+ default:
+ return MEMCACHED_FAILURE;
+ }
+ run_distribution(ptr);
+ break;
case MEMCACHED_BEHAVIOR_HASH:
#ifndef HAVE_HSIEH_HASH
if ((memcached_hash)(data) == MEMCACHED_HASH_HSIEH)
return MEMCACHED_SUCCESS;
}
-uint64_t memcached_behavior_get(memcached_st *ptr,
+uint64_t memcached_behavior_get(memcached_st *ptr,
memcached_behavior flag)
{
memcached_flags temp_flag= MEM_NO_BLOCK;
return ptr->io_key_prefetch;
case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL:
temp_flag= MEM_BINARY_PROTOCOL;
- break;
+ break;
case MEMCACHED_BEHAVIOR_SUPPORT_CAS:
temp_flag= MEM_SUPPORT_CAS;
break;
return ptr->distribution;
case MEMCACHED_BEHAVIOR_KETAMA:
return (ptr->distribution == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) ? (uint64_t) 1 : 0;
+ case MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE:
+ switch (ptr->distribution)
+ {
+ case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA:
+ return MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED;
+ case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY:
+ return MEMCACHED_KETAMA_COMPAT_SPY;
+ default:
+ return (uint64_t)-1;
+ }
+ /* NOTREACHED */
case MEMCACHED_BEHAVIOR_HASH:
return ptr->hash;
case MEMCACHED_BEHAVIOR_KETAMA_HASH:
if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS)
return 0;
- if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
+ if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
SO_SNDBUF, &sock_size, &sock_length))
return 0; /* Zero means error */
if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS)
return 0;
- if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
+ if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
SO_RCVBUF, &sock_size, &sock_length))
return 0; /* Zero means error */
#define MEMCACHED_MAX_HOST_SORT_LENGTH 86 /* Used for Ketama */
#define MEMCACHED_POINTS_PER_SERVER 100
#define MEMCACHED_POINTS_PER_SERVER_KETAMA 160
-#define MEMCACHED_CONTINUUM_SIZE MEMCACHED_POINTS_PER_SERVER*100 /* This would then set max hosts to 100 */
+#define MEMCACHED_CONTINUUM_SIZE MEMCACHED_POINTS_PER_SERVER*100 /* This would then set max hosts to 100 */
#define MEMCACHED_STRIDE 4
#define MEMCACHED_DEFAULT_TIMEOUT 1000
#define MEMCACHED_CONTINUUM_ADDITION 10 /* How many extra slots we should build for in the continuum */
MEMCACHED_DISTRIBUTION_MODULA,
MEMCACHED_DISTRIBUTION_CONSISTENT,
MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA,
- MEMCACHED_DISTRIBUTION_RANDOM
+ MEMCACHED_DISTRIBUTION_RANDOM,
+ MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY
} memcached_server_distribution;
typedef enum {
MEMCACHED_BEHAVIOR_NOREPLY,
MEMCACHED_BEHAVIOR_USE_UDP,
MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS,
- MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS
+ MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
+ MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE
} memcached_behavior;
+#define MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED 0
+#define MEMCACHED_KETAMA_COMPAT_SPY 1
+
typedef enum {
MEMCACHED_CALLBACK_PREFIX_KEY = 0,
MEMCACHED_CALLBACK_USER_DATA = 1,
hash= 1;
break;
/* FNV hash'es lifted from Dustin Sallings work */
- case MEMCACHED_HASH_FNV1_64:
+ case MEMCACHED_HASH_FNV1_64:
{
/* Thanks to pierre@demartines.com for the pointer */
uint64_t temp_hash;
temp_hash= FNV_64_INIT;
- for (x= 0; x < key_length; x++)
+ for (x= 0; x < key_length; x++)
{
temp_hash *= FNV_64_PRIME;
temp_hash ^= (uint64_t)key[x];
hash= (uint32_t)temp_hash;
}
break;
- case MEMCACHED_HASH_FNV1A_64:
+ case MEMCACHED_HASH_FNV1A_64:
{
hash= (uint32_t) FNV_64_INIT;
- for (x= 0; x < key_length; x++)
+ for (x= 0; x < key_length; x++)
{
uint32_t val= (uint32_t)key[x];
hash ^= val;
}
}
break;
- case MEMCACHED_HASH_FNV1_32:
+ case MEMCACHED_HASH_FNV1_32:
{
hash= FNV_32_INIT;
- for (x= 0; x < key_length; x++)
+ for (x= 0; x < key_length; x++)
{
uint32_t val= (uint32_t)key[x];
hash *= FNV_32_PRIME;
}
}
break;
- case MEMCACHED_HASH_FNV1A_32:
+ case MEMCACHED_HASH_FNV1A_32:
{
hash= FNV_32_INIT;
- for (x= 0; x < key_length; x++)
+ for (x= 0; x < key_length; x++)
{
uint32_t val= (uint32_t)key[x];
hash ^= val;
static uint32_t dispatch_host(memcached_st *ptr, uint32_t hash)
{
- switch (ptr->distribution)
+ switch (ptr->distribution)
{
case MEMCACHED_DISTRIBUTION_CONSISTENT:
case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA:
+ case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY:
{
uint32_t num= ptr->continuum_points_counter;
WATCHPOINT_ASSERT(ptr->continuum);
if (right == end)
right= begin;
return right->index;
- }
+ }
case MEMCACHED_DISTRIBUTION_MODULA:
return hash % ptr->number_of_hosts;
case MEMCACHED_DISTRIBUTION_RANDOM:
/* NOTREACHED */
}
-/*
- One day make this public, and have it return the actual memcached_server_st
+/*
+ One day make this public, and have it return the actual memcached_server_st
to the calling application.
*/
uint32_t memcached_generate_hash(memcached_st *ptr, const char *key, size_t key_length)
const char *ptr= key;
uint32_t value= 0;
- while (key_length--)
+ while (key_length--)
{
uint32_t val= (uint32_t) *ptr++;
value += val;
}
value += (value << 3);
value ^= (value >> 11);
- value += (value << 15);
+ value += (value << 15);
return value == 0 ? 1 : (uint32_t) value;
}
{
case MEMCACHED_DISTRIBUTION_CONSISTENT:
case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA:
+ case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY:
return update_continuum(ptr);
case MEMCACHED_DISTRIBUTION_MODULA:
if (ptr->flags & MEM_USE_SORT_HOSTS)
pointer_per_server);
#endif
}
- for (pointer_index= 0;
- pointer_index < pointer_per_server / pointer_per_hash;
- pointer_index++)
+
+
+ if (ptr->distribution == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY)
{
- char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= "";
- size_t sort_host_length;
-
- // Spymemcached ketema key format is: hostname/ip:port-index
- // If hostname is not available then: /ip:port-index
- sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
- "/%s:%d-%d",
- list[host_index].hostname,
- list[host_index].port,
- pointer_index);
+ for (pointer_index= 0;
+ pointer_index < pointer_per_server / pointer_per_hash;
+ pointer_index++)
+ {
+ char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= "";
+ size_t sort_host_length;
+
+ // Spymemcached ketema key format is: hostname/ip:port-index
+ // If hostname is not available then: /ip:port-index
+ sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
+ "/%s:%d-%d",
+ list[host_index].hostname,
+ list[host_index].port,
+ pointer_index);
#ifdef DEBUG
- printf("update_continuum: key is %s\n", sort_host);
+ printf("update_continuum: key is %s\n", sort_host);
#endif
- WATCHPOINT_ASSERT(sort_host_length);
+ WATCHPOINT_ASSERT(sort_host_length);
- if (is_ketama_weighted)
- {
- unsigned int i;
- for (i = 0; i < pointer_per_hash; i++)
+ if (is_ketama_weighted)
+ {
+ unsigned int i;
+ for (i = 0; i < pointer_per_hash; i++)
+ {
+ value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i);
+ ptr->continuum[continuum_index].index= host_index;
+ ptr->continuum[continuum_index++].value= value;
+ }
+ }
+ else
{
- value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i);
+ value= memcached_generate_hash_value(sort_host, sort_host_length, ptr->hash_continuum);
ptr->continuum[continuum_index].index= host_index;
ptr->continuum[continuum_index++].value= value;
}
}
- else
+ }
+ else
+ {
+ for (pointer_index= 1;
+ pointer_index <= pointer_per_server / pointer_per_hash;
+ pointer_index++)
{
- value= memcached_generate_hash_value(sort_host, sort_host_length, ptr->hash_continuum);
- ptr->continuum[continuum_index].index= host_index;
- ptr->continuum[continuum_index++].value= value;
+ char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= "";
+ size_t sort_host_length;
+
+ if (list[host_index].port == MEMCACHED_DEFAULT_PORT)
+ {
+ sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
+ "%s-%d",
+ list[host_index].hostname,
+ pointer_index - 1);
+ }
+ else
+ {
+ sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
+ "%s:%d-%d",
+ list[host_index].hostname,
+ list[host_index].port, pointer_index - 1);
+ }
+
+ WATCHPOINT_ASSERT(sort_host_length);
+
+ if (is_ketama_weighted)
+ {
+ unsigned int i;
+ for (i = 0; i < pointer_per_hash; i++)
+ {
+ value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i);
+ ptr->continuum[continuum_index].index= host_index;
+ ptr->continuum[continuum_index++].value= value;
+ }
+ }
+ else
+ {
+ value= memcached_generate_hash_value(sort_host, sort_host_length, ptr->hash_continuum);
+ ptr->continuum[continuum_index].index= host_index;
+ ptr->continuum[continuum_index++].value= value;
+ }
}
}
+
pointer_counter+= pointer_per_server;
}
memc->number_of_hosts= 1;
int max_keys= binary ? 20480 : 1;
-
+
char **keys= calloc((size_t)max_keys, sizeof(char*));
size_t *key_length=calloc((size_t)max_keys, sizeof(size_t));
/* verify the standard ketama set. */
for (x= 0; x < 99; x++)
{
- uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
char *hostname = memc->hosts[server_idx].hostname;
- assert(strcmp(hostname, test_cases[x].server) == 0);
+ assert(strcmp(hostname, ketama_test_cases[x].server) == 0);
}
memcached_server_list_free(server_pool);
for (int x= 0; x < 99; x++)
{
- uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
assert(server_idx != 2);
}
run_distribution(memc);
for (int x= 0; x < 99; x++)
{
- uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
char *hostname = memc->hosts[server_idx].hostname;
- assert(strcmp(hostname, test_cases[x].server) == 0);
+ assert(strcmp(hostname, ketama_test_cases[x].server) == 0);
}
memcached_server_list_free(server_pool);
memcached_st *memc= memcached_create(NULL);
assert(memc);
+
rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
assert(rc == MEMCACHED_SUCCESS);
value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
assert(value == MEMCACHED_HASH_MD5);
+
+ assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
+ MEMCACHED_KETAMA_COMPAT_SPY) == MEMCACHED_SUCCESS);
+
memcached_server_st *server_pool;
server_pool = memcached_servers_parse("10.0.1.1:11211,10.0.1.2:11211,10.0.1.3:11211,10.0.1.4:11211,10.0.1.5:11211,10.0.1.6:11211,10.0.1.7:11211,10.0.1.8:11211,192.168.1.1:11211,192.168.100.1:11211");
memcached_server_push(memc, server_pool);
{
char key[10];
sprintf(key, "%d", x);
-
+
uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
char *hostname = memc->hosts[server_idx].hostname;
unsigned int port = memc->hosts[server_idx].port;
return TEST_SUCCESS;
}
+
+static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
+{
+ memcached_return rc;
+ uint64_t value;
+ int x;
+ memcached_server_st *server_pool;
+ memcached_st *memc;
+
+ (void)trash;
+
+ memc= memcached_create(NULL);
+ assert(memc);
+
+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
+ assert(value == 1);
+
+ assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
+ MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED) == MEMCACHED_SUCCESS);
+
+ assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE) ==
+ MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED);
+
+ server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
+ memcached_server_push(memc, server_pool);
+
+ /* verify that the server list was parsed okay. */
+ assert(memc->number_of_hosts == 8);
+ assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
+ assert(server_pool[0].port == 11211);
+ assert(server_pool[0].weight == 600);
+ assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
+ assert(server_pool[2].port == 11211);
+ assert(server_pool[2].weight == 200);
+ assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
+ assert(server_pool[7].port == 11211);
+ assert(server_pool[7].weight == 100);
+
+ /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
+ * us test the boundary wraparound.
+ */
+ assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
+
+ /* verify the standard ketama set. */
+ for (x= 0; x < 99; x++)
+ {
+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
+ char *hostname = memc->hosts[server_idx].hostname;
+ assert(strcmp(hostname, ketama_test_cases[x].server) == 0);
+ }
+
+ memcached_server_list_free(server_pool);
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
+{
+ memcached_return rc;
+ uint64_t value;
+ int x;
+ memcached_server_st *server_pool;
+ memcached_st *memc;
+
+ (void)trash;
+
+ memc= memcached_create(NULL);
+ assert(memc);
+
+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
+ assert(value == 1);
+
+ assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
+ MEMCACHED_KETAMA_COMPAT_SPY) == MEMCACHED_SUCCESS);
+
+ assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE) ==
+ MEMCACHED_KETAMA_COMPAT_SPY);
+
+ server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
+ memcached_server_push(memc, server_pool);
+
+ /* verify that the server list was parsed okay. */
+ assert(memc->number_of_hosts == 8);
+ assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
+ assert(server_pool[0].port == 11211);
+ assert(server_pool[0].weight == 600);
+ assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
+ assert(server_pool[2].port == 11211);
+ assert(server_pool[2].weight == 200);
+ assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
+ assert(server_pool[7].port == 11211);
+ assert(server_pool[7].weight == 100);
+
+ /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
+ * us test the boundary wraparound.
+ */
+ assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
+
+ /* verify the standard ketama set. */
+ for (x= 0; x < 99; x++)
+ {
+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
+ char *hostname = memc->hosts[server_idx].hostname;
+ assert(strcmp(hostname, ketama_test_cases_spy[x].server) == 0);
+ }
+
+ memcached_server_list_free(server_pool);
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
+
static test_return_t regression_bug_434484(memcached_st *memc)
{
if (pre_binary(memc) != MEMCACHED_SUCCESS)
** to do this ;-)
*/
memcached_quit(memc);
-
- /* Verify that all messages are stored, and we didn't stuff too much
+
+ /* Verify that all messages are stored, and we didn't stuff too much
* into the servers
*/
rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
{0, 0, 0}
};
+test_st ketama_compatibility[]= {
+ {"libmemcached", 1, ketama_compatibility_libmemcached },
+ {"spymemcached", 1, ketama_compatibility_spymemcached },
+ {0, 0, 0}
+};
+
test_st generate_tests[] ={
{"generate_pairs", 1, generate_pairs },
{"generate_data", 1, generate_data },
{"consistent_not", 0, 0, consistent_tests},
{"consistent_ketama", pre_behavior_ketama, 0, consistent_tests},
{"consistent_ketama_weighted", pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
+ {"ketama_compat", 0, 0, ketama_compatibility},
{"test_hashes", 0, 0, hash_tests},
{"replication", pre_replication, 0, replication_tests},
{"replication_noblock", pre_replication_noblock, 0, replication_tests},
-typedef struct {
+#ifndef TESTS_KETAMA_TEST_CASES_H
+#define TESTS_KETAMA_TEST_CASES_H
+
+static struct {
const char *key;
unsigned long hash1;
unsigned long hash2;
const char *server;
-} TestCase;
-
-static TestCase test_cases[99] = {
- { "SVa_]_V41)", 443691461UL, 445379617UL, "10.0.1.2" },
- { "*/Z;?V(.\\8", 1422915503UL, 1428303028UL, "10.0.1.4" },
+} ketama_test_cases[99]= {
+ { "SVa_]_V41)", 443691461UL, 445379617UL, "10.0.1.7" },
+ { "*/Z;?V(.\\8", 1422915503UL, 1428303028UL, "10.0.1.1" },
{ "30C1*Z*S/_", 1473165754UL, 1480075959UL, "10.0.1.2" },
{ "ERR:EC58G>", 2148406511UL, 2168579133UL, "10.0.1.7" },
- { "1I=cTMNTKF", 2882686667UL, 2885206587UL, "10.0.1.4" },
+ { "1I=cTMNTKF", 2882686667UL, 2885206587UL, "10.0.1.5" },
{ "]VG<`I*Z8)", 1103544263UL, 1104827657UL, "10.0.1.5" },
- { "UUTC`-V159", 3716288206UL, 3727224240UL, "10.0.1.7" },
- { "@7RU6C6T+Z", 3862737685UL, 3871917949UL, "10.0.1.6" },
- { "/XLN0@+36;", 1623269830UL, 1627683651UL, "10.0.1.7" },
- { "4(`X;\\V.^c", 373546328UL, 383925769UL, "10.0.1.6" },
- { "726bW=9*a4", 4213440020UL, 4213950705UL, "10.0.1.3" },
- { "\\`)<B)UE,c", 951096736UL, 955226069UL, "10.0.1.8" },
- { "P1[Ma3=K1/", 1989324036UL, 1994028240UL, "10.0.1.1" },
- { "C89I.-V?cT", 1604239957UL, 1606398093UL, "10.0.1.5" },
- { "D[HE+cFXDK", 2117036136UL, 2117124014UL, "10.0.1.5" },
- { "P1L?NAB[)K", 2129972569UL, 2132542634UL, "10.0.1.7" },
- { "cDT0)Z5P6,", 176485284UL, 178675413UL, "10.0.1.1" },
- { "@JW`+[WAO8", 2720940826UL, 2743975456UL, "10.0.1.2" },
- { "\\39DKW^)N_", 3548879868UL, 3550704865UL, "10.0.1.6" },
- { "EM75N0+[X1", 1558531507UL, 1559308507UL, "10.0.1.5" },
+ { "UUTC`-V159", 3716288206UL, 3727224240UL, "10.0.1.5" },
+ { "@7RU6C6T+Z", 3862737685UL, 3871917949UL, "10.0.1.5" },
+ { "/XLN0@+36;", 1623269830UL, 1627683651UL, "10.0.1.1" },
+ { "4(`X;\\V.^c", 373546328UL, 383925769UL, "10.0.1.1" },
+ { "726bW=9*a4", 4213440020UL, 4213950705UL, "10.0.1.7" },
+ { "\\`)<B)UE,c", 951096736UL, 955226069UL, "10.0.1.1" },
+ { "P1[Ma3=K1/", 1989324036UL, 1994028240UL, "10.0.1.8" },
+ { "C89I.-V?cT", 1604239957UL, 1606398093UL, "10.0.1.8" },
+ { "D[HE+cFXDK", 2117036136UL, 2117124014UL, "10.0.1.3" },
+ { "P1L?NAB[)K", 2129972569UL, 2132542634UL, "10.0.1.1" },
+ { "cDT0)Z5P6,", 176485284UL, 178675413UL, "10.0.1.5" },
+ { "@JW`+[WAO8", 2720940826UL, 2743975456UL, "10.0.1.5" },
+ { "\\39DKW^)N_", 3548879868UL, 3550704865UL, "10.0.1.3" },
+ { "EM75N0+[X1", 1558531507UL, 1559308507UL, "10.0.1.4" },
{ "`,SS]NBP,b", 1883545960UL, 1884847278UL, "10.0.1.1" },
- { "XX1a9LT+F?", 653487707UL, 656410408UL, "10.0.1.6" },
- { "Zc\\-,F-c6V", 1160802451UL, 1171575728UL, "10.0.1.6" },
- { "1*RTMC7,03", 1602398012UL, 1606398093UL, "10.0.1.5" },
+ { "XX1a9LT+F?", 653487707UL, 656410408UL, "10.0.1.5" },
+ { "Zc\\-,F-c6V", 1160802451UL, 1171575728UL, "10.0.1.5" },
+ { "1*RTMC7,03", 1602398012UL, 1606398093UL, "10.0.1.8" },
{ "*Xc+V0P>32", 536016577UL, 539988520UL, "10.0.1.7" },
{ "U))Fb-(`,.", 4128682289UL, 4136854163UL, "10.0.1.7" },
{ "R-08RNTaRT", 3718170086UL, 3727224240UL, "10.0.1.5" },
- { "(LHcO203I3", 1007779411UL, 1014643570UL, "10.0.1.1" },
- { "=256P+;Qc8", 3976201210UL, 3976304873UL, "10.0.1.3" },
- { "OI5XZ_BBT(", 2155922164UL, 2168579133UL, "10.0.1.5" },
- { "2TLRL/UL;:", 1086800909UL, 1095659802UL, "10.0.1.2" },
- { "WHD\\O1`ZRW", 3087923411UL, 3095471560UL, "10.0.1.1" },
- { ".=54)_c;=T", 2497691631UL, 2502731301UL, "10.0.1.6" },
- { ";G<W-XWZ@b", 2888169733UL, 2888728739UL, "10.0.1.7" },
- { "(,>E`)FT\\4", 580747448UL, 581063326UL, "10.0.1.5" },
- { "HZAU*;P*N]", 2564670474UL, 2565697267UL, "10.0.1.1" },
+ { "(LHcO203I3", 1007779411UL, 1014643570UL, "10.0.1.5" },
+ { "=256P+;Qc8", 3976201210UL, 3976304873UL, "10.0.1.5" },
+ { "OI5XZ_BBT(", 2155922164UL, 2168579133UL, "10.0.1.7" },
+ { "2TLRL/UL;:", 1086800909UL, 1095659802UL, "10.0.1.7" },
+ { "WHD\\O1`ZRW", 3087923411UL, 3095471560UL, "10.0.1.5" },
+ { ".=54)_c;=T", 2497691631UL, 2502731301UL, "10.0.1.1" },
+ { ";G<W-XWZ@b", 2888169733UL, 2888728739UL, "10.0.1.5" },
+ { "(,>E`)FT\\4", 580747448UL, 581063326UL, "10.0.1.2" },
+ { "HZAU*;P*N]", 2564670474UL, 2565697267UL, "10.0.1.7" },
{ "NZ@ZE=O84_", 533335275UL, 539988520UL, "10.0.1.7" },
- { "6,cEI`F_P>", 3972869246UL, 3974773167UL, "10.0.1.3" },
- { "c,5AQ/T5)6", 2835605783UL, 2847870057UL, "10.0.1.7" },
- { ".O,>>BT)RX", 3857978174UL, 3871917949UL, "10.0.1.7" },
- { "XY\\X::LX50", 1749241099UL, 1752196488UL, "10.0.1.7" },
- { "+550F^/.01", 3781824099UL, 3783248219UL, "10.0.1.2" },
+ { "6,cEI`F_P>", 3972869246UL, 3974773167UL, "10.0.1.6" },
+ { "c,5AQ/T5)6", 2835605783UL, 2847870057UL, "10.0.1.8" },
+ { ".O,>>BT)RX", 3857978174UL, 3871917949UL, "10.0.1.5" },
+ { "XY\\X::LX50", 1749241099UL, 1752196488UL, "10.0.1.6" },
+ { "+550F^/.01", 3781824099UL, 3783248219UL, "10.0.1.6" },
{ "<.X9E2S5+9", 3232479481UL, 3234387706UL, "10.0.1.7" },
- { "]\\.UH8_0a1", 2419699252UL, 2423002920UL, "10.0.1.6" },
- { "8(6=(T0/Z0", 728266737UL, 729026070UL, "10.0.1.6" },
- { "8*6a;Sc*X+", 4223431086UL, 4230156966UL, "10.0.1.5" },
- { "<QW:;3K6;H", 2731158143UL, 2743975456UL, "10.0.1.7" },
+ { "]\\.UH8_0a1", 2419699252UL, 2423002920UL, "10.0.1.4" },
+ { "8(6=(T0/Z0", 728266737UL, 729026070UL, "10.0.1.7" },
+ { "8*6a;Sc*X+", 4223431086UL, 4230156966UL, "10.0.1.2" },
+ { "<QW:;3K6;H", 2731158143UL, 2743975456UL, "10.0.1.5" },
{ "7C@EY@-Y?_", 760770733UL, 761576669UL, "10.0.1.5" },
- { "aPb3E1WD4K", 2500489218UL, 2502731301UL, "10.0.1.2" },
- { "?@12R<=1BH", 1494795329UL, 1502505505UL, "10.0.1.1" },
- { "QR(a+Q=1FU", 3238535074UL, 3238996435UL, "10.0.1.5" },
- { "`C9^FV,960", 2628553463UL, 2628733766UL, "10.0.1.3" },
- { "UNHVP..^8H", 977096483UL, 977319837UL, "10.0.1.6" },
- { ":Y.2W2[(35", 2777083668UL, 2784182515UL, "10.0.1.6" },
- { "M/HV^_HZ4O", 3623390946UL, 3624445007UL, "10.0.1.4" },
- { "ZY16KQ<ICD", 1831153193UL, 1838563516UL, "10.0.1.7" },
- { "bV2,`a.PY9", 1962228869UL, 1962648654UL, "10.0.1.7" },
- { "U;9:-+5N]9", 269504649UL, 277560877UL, "10.0.1.2" },
- { "1S/:aJ[1(;", 578069729UL, 581063326UL, "10.0.1.5" },
- { "Nb-X^]M)I:", 330865696UL, 331009896UL, "10.0.1.3" },
- { "2;M;ES>J5/", 2776949824UL, 2784182515UL, "10.0.1.6" },
- { "[>RZHG97Q9", 71954686UL, 72034069UL, "10.0.1.4" },
- { "J3/G[)9<^Z", 2799896459UL, 2805183696UL, "10.0.1.6" },
- { "N-)88>[O`,", 50404102UL, 51792557UL, "10.0.1.2" },
+ { "aPb3E1WD4K", 2500489218UL, 2502731301UL, "10.0.1.1" },
+ { "?@12R<=1BH", 1494795329UL, 1502505505UL, "10.0.1.8" },
+ { "QR(a+Q=1FU", 3238535074UL, 3238996435UL, "10.0.1.6" },
+ { "`C9^FV,960", 2628553463UL, 2628733766UL, "10.0.1.6" },
+ { "UNHVP..^8H", 977096483UL, 977319837UL, "10.0.1.4" },
+ { ":Y.2W2[(35", 2777083668UL, 2784182515UL, "10.0.1.7" },
+ { "M/HV^_HZ4O", 3623390946UL, 3624445007UL, "10.0.1.7" },
+ { "ZY16KQ<ICD", 1831153193UL, 1838563516UL, "10.0.1.4" },
+ { "bV2,`a.PY9", 1962228869UL, 1962648654UL, "10.0.1.1" },
+ { "U;9:-+5N]9", 269504649UL, 277560877UL, "10.0.1.1" },
+ { "1S/:aJ[1(;", 578069729UL, 581063326UL, "10.0.1.2" },
+ { "Nb-X^]M)I:", 330865696UL, 331009896UL, "10.0.1.6" },
+ { "2;M;ES>J5/", 2776949824UL, 2784182515UL, "10.0.1.7" },
+ { "[>RZHG97Q9", 71954686UL, 72034069UL, "10.0.1.6" },
+ { "J3/G[)9<^Z", 2799896459UL, 2805183696UL, "10.0.1.7" },
+ { "N-)88>[O`,", 50404102UL, 51792557UL, "10.0.1.5" },
{ "NP:=FR\\OaA", 3837333776UL, 3837792034UL, "10.0.1.7" },
- { "`@L+W;a,O[", 1512157148UL, 1522285852UL, "10.0.1.5" },
- { "W2`P:-+1T[", 2945171975UL, 2946196424UL, "10.0.1.7" },
- { "-6G7K^YDIN", 3168617340UL, 3170513015UL, "10.0.1.5" },
- { "U>*>9ZI6V5", 668514946UL, 674097631UL, "10.0.1.5" },
+ { "`@L+W;a,O[", 1512157148UL, 1522285852UL, "10.0.1.6" },
+ { "W2`P:-+1T[", 2945171975UL, 2946196424UL, "10.0.1.5" },
+ { "-6G7K^YDIN", 3168617340UL, 3170513015UL, "10.0.1.7" },
+ { "U>*>9ZI6V5", 668514946UL, 674097631UL, "10.0.1.6" },
{ ".I?^6Ic9RK", 938419020UL, 942832691UL, "10.0.1.6" },
- { "0OZH^9BKM[", 3682518606UL, 3686781297UL, "10.0.1.2" },
- { "5?50UGZ:ML", 868610882UL, 869425986UL, "10.0.1.6" },
- { "?K2NF@3=IU", 381218851UL, 383925769UL, "10.0.1.6" },
- { "YI@G-2X?UB", 3688706179UL, 3693197681UL, "10.0.1.6" },
- { "7cY</BSaL=", 3976870223UL, 3978903843UL, "10.0.1.7" },
+ { "0OZH^9BKM[", 3682518606UL, 3686781297UL, "10.0.1.8" },
+ { "5?50UGZ:ML", 868610882UL, 869425986UL, "10.0.1.5" },
+ { "?K2NF@3=IU", 381218851UL, 383925769UL, "10.0.1.1" },
+ { "YI@G-2X?UB", 3688706179UL, 3693197681UL, "10.0.1.5" },
+ { "7cY</BSaL=", 3976870223UL, 3978903843UL, "10.0.1.6" },
{ "A(`KF:[RH8", 3292979676UL, 3294849139UL, "10.0.1.6" },
- { ";=ZT\\W^P+H", 1401102653UL, 1416290674UL, "10.0.1.6" },
- { "b2?WFF56;R", 480494704UL, 486971192UL, "10.0.1.7" },
- { "CTR74,J+N.", 137446045UL, 146633907UL, "10.0.1.7" },
+ { ";=ZT\\W^P+H", 1401102653UL, 1416290674UL, "10.0.1.4" },
+ { "b2?WFF56;R", 480494704UL, 486971192UL, "10.0.1.4" },
+ { "CTR74,J+N.", 137446045UL, 146633907UL, "10.0.1.8" },
{ "<b;*R+QDST", 1304985302UL, 1308223778UL, "10.0.1.5" },
- { "\\R^7=9UCG`", 126218373UL, 129199837UL, "10.0.1.6" },
- { "1bQS5]WOXB", 1853470245UL, 1855329369UL, "10.0.1.7" },
- { "M(@X^b[L:K", 3019630308UL, 3022260113UL, "10.0.1.4" },
- { "431cBF8,YO", 1679726993UL, 1685224295UL, "10.0.1.1" },
- { "(bEIQJ:E./", 2922607787UL, 2925521819UL, "10.0.1.7" },
- { "WS/3H*)7F;", 419488232UL, 422140585UL, "10.0.1.3" },
- { "ZJF[Ia6Q)+", 3960568056UL, 3962489998UL, "10.0.1.5" },
- { "<]*QCK8U,>", 2590140172UL, 2598117636UL, "10.0.1.5" },
- { "\\[a\\^=V_M0", 689410119UL, 698690782UL, "10.0.1.7" },
+ { "\\R^7=9UCG`", 126218373UL, 129199837UL, "10.0.1.5" },
+ { "1bQS5]WOXB", 1853470245UL, 1855329369UL, "10.0.1.4" },
+ { "M(@X^b[L:K", 3019630308UL, 3022260113UL, "10.0.1.1" },
+ { "431cBF8,YO", 1679726993UL, 1685224295UL, "10.0.1.7" },
+ { "(bEIQJ:E./", 2922607787UL, 2925521819UL, "10.0.1.6" },
+ { "WS/3H*)7F;", 419488232UL, 422140585UL, "10.0.1.5" },
+ { "ZJF[Ia6Q)+", 3960568056UL, 3962489998UL, "10.0.1.7" },
+ { "<]*QCK8U,>", 2590140172UL, 2598117636UL, "10.0.1.7" },
+ { "\\[a\\^=V_M0", 689410119UL, 698690782UL, "10.0.1.6" },
{ "7;RM+8J9YC", 1530175299UL, 1531107082UL, "10.0.1.7" },
- { "4*=.SPR[AV", 3928582722UL, 3928853792UL, "10.0.1.3" },
+ { "4*=.SPR[AV", 3928582722UL, 3928853792UL, "10.0.1.1" },
{ "-2F+^88P4U", 3023552752UL, 3025823613UL, "10.0.1.7" },
- { "X;-F`(N?9D", 570465234UL, 572485994UL, "10.0.1.5" },
- { "R=F_D-K2a]", 1287750228UL, 1290935562UL, "10.0.1.1" },
- { "X*+2aaC.EG", 3200948713UL, 3201088518UL, "10.0.1.3" },
- { "[1ZXONX2]a", 4108881567UL, 4109865744UL, "10.0.1.7" },
- { "FL;\\GWacaV", 458449508UL, 467374054UL, "10.0.1.7" },
- { "\\MQ_XNT7L-", 1259349383UL, 1259509450UL, "10.0.1.5" },
- { "VD6D0]ba_\\", 3842502950UL, 3842588691UL, "10.0.1.7" },
+ { "X;-F`(N?9D", 570465234UL, 572485994UL, "10.0.1.7" },
+ { "R=F_D-K2a]", 1287750228UL, 1290935562UL, "10.0.1.7" },
+ { "X*+2aaC.EG", 3200948713UL, 3201088518UL, "10.0.1.5" },
+ { "[1ZXONX2]a", 4108881567UL, 4109865744UL, "10.0.1.4" },
+ { "FL;\\GWacaV", 458449508UL, 467374054UL, "10.0.1.4" },
+ { "\\MQ_XNT7L-", 1259349383UL, 1259509450UL, "10.0.1.7" },
+ { "VD6D0]ba_\\", 3842502950UL, 3842588691UL, "10.0.1.1" },
};
+
+#include "ketama_test_cases_spy.h"
+
+#endif
--- /dev/null
+#ifndef TESTS_KETAMA_TEST_CASES_SPY_H
+#define TESTS_KETAMA_TEST_CASES_SPY_H
+
+static struct {
+ const char *key;
+ unsigned long hash1;
+ unsigned long hash2;
+ const char *server;
+} ketama_test_cases_spy[99]= {
+ { "SVa_]_V41)", 443691461UL, 445379617UL, "10.0.1.2" },
+ { "*/Z;?V(.\\8", 1422915503UL, 1428303028UL, "10.0.1.4" },
+ { "30C1*Z*S/_", 1473165754UL, 1480075959UL, "10.0.1.2" },
+ { "ERR:EC58G>", 2148406511UL, 2168579133UL, "10.0.1.7" },
+ { "1I=cTMNTKF", 2882686667UL, 2885206587UL, "10.0.1.4" },
+ { "]VG<`I*Z8)", 1103544263UL, 1104827657UL, "10.0.1.5" },
+ { "UUTC`-V159", 3716288206UL, 3727224240UL, "10.0.1.7" },
+ { "@7RU6C6T+Z", 3862737685UL, 3871917949UL, "10.0.1.6" },
+ { "/XLN0@+36;", 1623269830UL, 1627683651UL, "10.0.1.7" },
+ { "4(`X;\\V.^c", 373546328UL, 383925769UL, "10.0.1.6" },
+ { "726bW=9*a4", 4213440020UL, 4213950705UL, "10.0.1.3" },
+ { "\\`)<B)UE,c", 951096736UL, 955226069UL, "10.0.1.8" },
+ { "P1[Ma3=K1/", 1989324036UL, 1994028240UL, "10.0.1.1" },
+ { "C89I.-V?cT", 1604239957UL, 1606398093UL, "10.0.1.5" },
+ { "D[HE+cFXDK", 2117036136UL, 2117124014UL, "10.0.1.5" },
+ { "P1L?NAB[)K", 2129972569UL, 2132542634UL, "10.0.1.7" },
+ { "cDT0)Z5P6,", 176485284UL, 178675413UL, "10.0.1.1" },
+ { "@JW`+[WAO8", 2720940826UL, 2743975456UL, "10.0.1.2" },
+ { "\\39DKW^)N_", 3548879868UL, 3550704865UL, "10.0.1.6" },
+ { "EM75N0+[X1", 1558531507UL, 1559308507UL, "10.0.1.5" },
+ { "`,SS]NBP,b", 1883545960UL, 1884847278UL, "10.0.1.1" },
+ { "XX1a9LT+F?", 653487707UL, 656410408UL, "10.0.1.6" },
+ { "Zc\\-,F-c6V", 1160802451UL, 1171575728UL, "10.0.1.6" },
+ { "1*RTMC7,03", 1602398012UL, 1606398093UL, "10.0.1.5" },
+ { "*Xc+V0P>32", 536016577UL, 539988520UL, "10.0.1.7" },
+ { "U))Fb-(`,.", 4128682289UL, 4136854163UL, "10.0.1.7" },
+ { "R-08RNTaRT", 3718170086UL, 3727224240UL, "10.0.1.5" },
+ { "(LHcO203I3", 1007779411UL, 1014643570UL, "10.0.1.1" },
+ { "=256P+;Qc8", 3976201210UL, 3976304873UL, "10.0.1.3" },
+ { "OI5XZ_BBT(", 2155922164UL, 2168579133UL, "10.0.1.5" },
+ { "2TLRL/UL;:", 1086800909UL, 1095659802UL, "10.0.1.2" },
+ { "WHD\\O1`ZRW", 3087923411UL, 3095471560UL, "10.0.1.1" },
+ { ".=54)_c;=T", 2497691631UL, 2502731301UL, "10.0.1.6" },
+ { ";G<W-XWZ@b", 2888169733UL, 2888728739UL, "10.0.1.7" },
+ { "(,>E`)FT\\4", 580747448UL, 581063326UL, "10.0.1.5" },
+ { "HZAU*;P*N]", 2564670474UL, 2565697267UL, "10.0.1.1" },
+ { "NZ@ZE=O84_", 533335275UL, 539988520UL, "10.0.1.7" },
+ { "6,cEI`F_P>", 3972869246UL, 3974773167UL, "10.0.1.3" },
+ { "c,5AQ/T5)6", 2835605783UL, 2847870057UL, "10.0.1.7" },
+ { ".O,>>BT)RX", 3857978174UL, 3871917949UL, "10.0.1.7" },
+ { "XY\\X::LX50", 1749241099UL, 1752196488UL, "10.0.1.7" },
+ { "+550F^/.01", 3781824099UL, 3783248219UL, "10.0.1.2" },
+ { "<.X9E2S5+9", 3232479481UL, 3234387706UL, "10.0.1.7" },
+ { "]\\.UH8_0a1", 2419699252UL, 2423002920UL, "10.0.1.6" },
+ { "8(6=(T0/Z0", 728266737UL, 729026070UL, "10.0.1.6" },
+ { "8*6a;Sc*X+", 4223431086UL, 4230156966UL, "10.0.1.5" },
+ { "<QW:;3K6;H", 2731158143UL, 2743975456UL, "10.0.1.7" },
+ { "7C@EY@-Y?_", 760770733UL, 761576669UL, "10.0.1.5" },
+ { "aPb3E1WD4K", 2500489218UL, 2502731301UL, "10.0.1.2" },
+ { "?@12R<=1BH", 1494795329UL, 1502505505UL, "10.0.1.1" },
+ { "QR(a+Q=1FU", 3238535074UL, 3238996435UL, "10.0.1.5" },
+ { "`C9^FV,960", 2628553463UL, 2628733766UL, "10.0.1.3" },
+ { "UNHVP..^8H", 977096483UL, 977319837UL, "10.0.1.6" },
+ { ":Y.2W2[(35", 2777083668UL, 2784182515UL, "10.0.1.6" },
+ { "M/HV^_HZ4O", 3623390946UL, 3624445007UL, "10.0.1.4" },
+ { "ZY16KQ<ICD", 1831153193UL, 1838563516UL, "10.0.1.7" },
+ { "bV2,`a.PY9", 1962228869UL, 1962648654UL, "10.0.1.7" },
+ { "U;9:-+5N]9", 269504649UL, 277560877UL, "10.0.1.2" },
+ { "1S/:aJ[1(;", 578069729UL, 581063326UL, "10.0.1.5" },
+ { "Nb-X^]M)I:", 330865696UL, 331009896UL, "10.0.1.3" },
+ { "2;M;ES>J5/", 2776949824UL, 2784182515UL, "10.0.1.6" },
+ { "[>RZHG97Q9", 71954686UL, 72034069UL, "10.0.1.4" },
+ { "J3/G[)9<^Z", 2799896459UL, 2805183696UL, "10.0.1.6" },
+ { "N-)88>[O`,", 50404102UL, 51792557UL, "10.0.1.2" },
+ { "NP:=FR\\OaA", 3837333776UL, 3837792034UL, "10.0.1.7" },
+ { "`@L+W;a,O[", 1512157148UL, 1522285852UL, "10.0.1.5" },
+ { "W2`P:-+1T[", 2945171975UL, 2946196424UL, "10.0.1.7" },
+ { "-6G7K^YDIN", 3168617340UL, 3170513015UL, "10.0.1.5" },
+ { "U>*>9ZI6V5", 668514946UL, 674097631UL, "10.0.1.5" },
+ { ".I?^6Ic9RK", 938419020UL, 942832691UL, "10.0.1.6" },
+ { "0OZH^9BKM[", 3682518606UL, 3686781297UL, "10.0.1.2" },
+ { "5?50UGZ:ML", 868610882UL, 869425986UL, "10.0.1.6" },
+ { "?K2NF@3=IU", 381218851UL, 383925769UL, "10.0.1.6" },
+ { "YI@G-2X?UB", 3688706179UL, 3693197681UL, "10.0.1.6" },
+ { "7cY</BSaL=", 3976870223UL, 3978903843UL, "10.0.1.7" },
+ { "A(`KF:[RH8", 3292979676UL, 3294849139UL, "10.0.1.6" },
+ { ";=ZT\\W^P+H", 1401102653UL, 1416290674UL, "10.0.1.6" },
+ { "b2?WFF56;R", 480494704UL, 486971192UL, "10.0.1.7" },
+ { "CTR74,J+N.", 137446045UL, 146633907UL, "10.0.1.7" },
+ { "<b;*R+QDST", 1304985302UL, 1308223778UL, "10.0.1.5" },
+ { "\\R^7=9UCG`", 126218373UL, 129199837UL, "10.0.1.6" },
+ { "1bQS5]WOXB", 1853470245UL, 1855329369UL, "10.0.1.7" },
+ { "M(@X^b[L:K", 3019630308UL, 3022260113UL, "10.0.1.4" },
+ { "431cBF8,YO", 1679726993UL, 1685224295UL, "10.0.1.1" },
+ { "(bEIQJ:E./", 2922607787UL, 2925521819UL, "10.0.1.7" },
+ { "WS/3H*)7F;", 419488232UL, 422140585UL, "10.0.1.3" },
+ { "ZJF[Ia6Q)+", 3960568056UL, 3962489998UL, "10.0.1.5" },
+ { "<]*QCK8U,>", 2590140172UL, 2598117636UL, "10.0.1.5" },
+ { "\\[a\\^=V_M0", 689410119UL, 698690782UL, "10.0.1.7" },
+ { "7;RM+8J9YC", 1530175299UL, 1531107082UL, "10.0.1.7" },
+ { "4*=.SPR[AV", 3928582722UL, 3928853792UL, "10.0.1.3" },
+ { "-2F+^88P4U", 3023552752UL, 3025823613UL, "10.0.1.7" },
+ { "X;-F`(N?9D", 570465234UL, 572485994UL, "10.0.1.5" },
+ { "R=F_D-K2a]", 1287750228UL, 1290935562UL, "10.0.1.1" },
+ { "X*+2aaC.EG", 3200948713UL, 3201088518UL, "10.0.1.3" },
+ { "[1ZXONX2]a", 4108881567UL, 4109865744UL, "10.0.1.7" },
+ { "FL;\\GWacaV", 458449508UL, 467374054UL, "10.0.1.7" },
+ { "\\MQ_XNT7L-", 1259349383UL, 1259509450UL, "10.0.1.5" },
+ { "VD6D0]ba_\\", 3842502950UL, 3842588691UL, "10.0.1.7" },
+};
+#endif