instance= memcached_server_instance_fetch(ptr, server_key);
send_length= (size_t)snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
- "%s %s%.*s %" PRIu64 "%s\r\n", verb,
+ "%s %.*s%.*s %" PRIu64 "%s\r\n", verb,
+ (int)ptr->prefix_key_length,
ptr->prefix_key,
(int)key_length, key,
offset, no_reply ? " noreply" : "");
}
if ((key_length > MEMCACHED_PREFIX_KEY_MAX_SIZE -1)
- || (strcpy(ptr->prefix_key, key) == NULL))
+ || (strncpy(ptr->prefix_key, key, MEMCACHED_PREFIX_KEY_MAX_SIZE) == NULL))
{
ptr->prefix_key_length= 0;
return MEMCACHED_BAD_KEY_PROVIDED;
}
else
{
- memset(ptr->prefix_key, 0, MEMCACHED_PREFIX_KEY_MAX_SIZE);
+ ptr->prefix_key[0]= 0;
ptr->prefix_key_length= 0;
}
{
case MEMCACHED_CALLBACK_PREFIX_KEY:
{
- if (ptr->prefix_key[0] == 0)
+ if (ptr->prefix_key_length)
{
- *error= MEMCACHED_FAILURE;
- return NULL;
+ *error= MEMCACHED_SUCCESS;
+ return (void *)ptr->prefix_key;
}
else
{
- *error= MEMCACHED_SUCCESS;
- return (void *)ptr->prefix_key;
+ *error= MEMCACHED_FAILURE;
+ return NULL;
}
}
case MEMCACHED_CALLBACK_USER_DATA:
// These are private
#define memcached_is_allocated(__object) ((__object)->options.is_allocated)
#define memcached_is_initialized(__object) ((__object)->options.is_initialized)
-#define memcached_is_purging(__object) ((__object)->flags.is_purging)
-#define memcached_is_processing_input(__object) ((__object)->flags.is_processing_input)
-#define memcached_set_purging(__object, __value) ((__object)->flags.is_purging= (__value))
-#define memcached_set_processing_input(__object, __value) ((__object)->flags.is_processing_input= (__value))
+#define memcached_is_purging(__object) ((__object)->state.is_purging)
+#define memcached_is_processing_input(__object) ((__object)->state.is_processing_input)
+#define memcached_set_purging(__object, __value) ((__object)->state.is_purging= (__value))
+#define memcached_set_processing_input(__object, __value) ((__object)->state.is_processing_input= (__value))
#define memcached_set_initialized(__object, __value) ((__object)->options.is_initialized(= (__value))
#define memcached_set_allocated(__object, __value) ((__object)->options.is_allocated(= (__value))
}
}
send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
- "delete %s%.*s %u%s\r\n",
+ "delete %.*s%.*s %u%s\r\n",
+ (int)ptr->prefix_key_length,
ptr->prefix_key,
(int) key_length, key,
(uint32_t)expiration,
}
else
send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
- "delete %s%.*s%s\r\n",
+ "delete %.*s%.*s%s\r\n",
+ (int)ptr->prefix_key_length,
ptr->prefix_key,
(int)key_length, key, no_reply ? " noreply" :"");
}
/* Only called when we have a prefix key */
- if (ptr->prefix_key[0] != 0)
+ if (ptr->prefix_key_length)
{
if ((memcached_io_write(instance, ptr->prefix_key, ptr->prefix_key_length, 0)) == -1)
{
memcached_return_t memcached_server_push(memcached_st *ptr, memcached_server_st *list)
{
- uint32_t x;
uint32_t count;
memcached_server_st *new_host_list;
memcached_server_list_set(ptr, new_host_list);
- for (x= 0; x < count; x++)
+ for (uint32_t x= 0; x < count; x++)
{
memcached_server_instance_st *instance;
*/
#include "common.h"
+static const memcached_st global_copy= {
+ .state= {
+ .is_purging= false,
+ .is_processing_input= false,
+ },
+ .flags= {
+ .auto_eject_hosts= false,
+ .binary_protocol= false,
+ .buffer_requests= false,
+ .cork= false,
+ .hash_with_prefix_key= false,
+ .ketama_weighted= false,
+ .no_block= false,
+ .no_reply= false,
+ .randomize_replica_read= false,
+ .reuse_memory= false,
+ .support_cas= false,
+ .tcp_nodelay= false,
+ .use_cache_lookups= false,
+ .use_sort_hosts= false,
+ .use_udp= false,
+ .verify_key= false
+ }
+};
+
+static inline void _memcached_init(memcached_st *self)
+{
+ self->state= global_copy.state;
+ self->flags= global_copy.flags;
+
+ self->distribution= MEMCACHED_DISTRIBUTION_MODULA;
+ self->hash= MEMCACHED_HASH_DEFAULT;
+ self->continuum_points_counter= 0;
+
+ self->number_of_hosts= 0;
+ self->servers= NULL;
+ self->last_disconnected_server= NULL;
+
+ self->snd_timeout= 0;
+ self->rcv_timeout= 0;
+ self->server_failure_limit= 0;
+
+ /* TODO, Document why we picked these defaults */
+ self->io_msg_watermark= 500;
+ self->io_bytes_watermark= 65 * 1024;
+
+ self->io_key_prefetch= 0;
+ self->cached_errno= 0;
+ self->poll_timeout= MEMCACHED_DEFAULT_TIMEOUT;
+ self->connect_timeout= MEMCACHED_DEFAULT_TIMEOUT;
+ self->retry_timeout= 0;
+ self->continuum_count= 0;
+
+ self->send_size= -1;
+ self->recv_size= -1;
+
+ self->user_data= NULL;
+ self->next_distribution_rebuild= 0;
+ self->prefix_key_length= 0;
+ self->number_of_replicas= 0;
+ self->distribution_hash= MEMCACHED_HASH_DEFAULT;
+ self->continuum= NULL;
+
+
+ memcached_set_memory_allocators(self, NULL, NULL, NULL, NULL);
+
+ self->on_clone= NULL;
+ self->on_cleanup= NULL;
+ self->get_key_failure= NULL;
+ self->delete_trigger= NULL;
+ self->callbacks= NULL;
+}
+
memcached_st *memcached_create(memcached_st *ptr)
{
if (ptr == NULL)
{
- ptr= (memcached_st *)calloc(1, sizeof(memcached_st));
+ ptr= (memcached_st *)malloc(sizeof(memcached_st));
if (! ptr)
{
}
else
{
- memset(ptr, 0, sizeof(memcached_st));
+ ptr->options.is_allocated= false;
}
#if 0
memcached_set_processing_input(ptr, false);
#endif
- memcached_set_memory_allocators(ptr, NULL, NULL, NULL, NULL);
+ _memcached_init(ptr);
if (! memcached_result_create(ptr, &ptr->result))
{
memcached_free(ptr);
return NULL;
}
- ptr->poll_timeout= MEMCACHED_DEFAULT_TIMEOUT;
- ptr->connect_timeout= MEMCACHED_DEFAULT_TIMEOUT;
- ptr->retry_timeout= 0;
- ptr->distribution= MEMCACHED_DISTRIBUTION_MODULA;
-
-
- ptr->send_size= -1;
- ptr->recv_size= -1;
-
- /* TODO, Document why we picked these defaults */
- ptr->io_msg_watermark= 500;
- ptr->io_bytes_watermark= 65 * 1024;
WATCHPOINT_ASSERT_INITIALIZED(&ptr->result);
}
- if (source->prefix_key[0] != 0)
+ if (source->prefix_key_length)
{
strcpy(new_clone->prefix_key, source->prefix_key);
new_clone->prefix_key_length= source->prefix_key_length;
struct {
bool is_purging:1;
bool is_processing_input:1;
+ } state;
+ struct {
// Everything below here is pretty static.
bool auto_eject_hosts:1;
bool binary_protocol:1;
bool buffer_requests:1;
+ bool cork:1;
bool hash_with_prefix_key:1;
bool ketama_weighted:1;
bool no_block:1;
bool use_sort_hosts:1;
bool use_udp:1;
bool verify_key:1;
- bool cork:1;
} flags;
memcached_server_distribution_t distribution;
memcached_hash_t hash;
uint32_t continuum_points_counter; // Ketama
+ uint32_t number_of_hosts;
memcached_server_st *servers;
memcached_server_st *last_disconnected_server;
int32_t snd_timeout;
uint32_t io_msg_watermark;
uint32_t io_bytes_watermark;
uint32_t io_key_prefetch;
- uint32_t number_of_hosts;
int cached_errno;
int32_t poll_timeout;
int32_t connect_timeout;
memcached_hash_t distribution_hash;
memcached_result_st result;
memcached_continuum_item_st *continuum; // Ketama
- memcached_clone_fn on_clone;
- memcached_cleanup_fn on_cleanup;
+
memcached_free_fn call_free;
memcached_malloc_fn call_malloc;
memcached_realloc_fn call_realloc;
memcached_calloc_fn call_calloc;
+
+ memcached_clone_fn on_clone;
+ memcached_cleanup_fn on_cleanup;
memcached_trigger_key_fn get_key_failure;
memcached_trigger_delete_key_fn delete_trigger;
memcached_callback_st *callbacks;
self->root= root;
self->limit_maxbytes= 0;
- strncpy(self->hostname, hostname, MEMCACHED_MAX_HOST_LENGTH - 1);
+ if (hostname == NULL)
+ self->hostname[0]= 0;
+ else
+ strncpy(self->hostname, hostname, MEMCACHED_MAX_HOST_LENGTH - 1);
}
static memcached_server_st *_server_create(memcached_server_st *self, const memcached_st *memc)
if (cas)
{
write_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
- "%s %s%.*s %u %llu %zu %llu%s\r\n",
+ "%s %.*s%.*s %u %llu %zu %llu%s\r\n",
storage_op_string(verb),
+ (int)ptr->prefix_key_length,
ptr->prefix_key,
(int)key_length, key, flags,
(unsigned long long)expiration, value_length,
memcpy(buffer_ptr, command, strlen(command));
/* Copy in the key prefix, switch to the buffer_ptr */
- buffer_ptr= memcpy((buffer_ptr + strlen(command)), ptr->prefix_key, strlen(ptr->prefix_key));
+ buffer_ptr= memcpy((buffer_ptr + strlen(command)), ptr->prefix_key, ptr->prefix_key_length);
/* Copy in the key, adjust point if a key prefix was used. */
- buffer_ptr= memcpy(buffer_ptr + (ptr->prefix_key ? strlen(ptr->prefix_key) : 0),
+ buffer_ptr= memcpy(buffer_ptr + (ptr->prefix_key_length ? ptr->prefix_key_length : 0),
key, key_length);
buffer_ptr+= key_length;
buffer_ptr[0]= ' ';