memcached_return_t memcached_bucket_set(memcached_st *self, const uint32_t *host_map, const uint32_t *forward_map, const uint32_t buckets, const uint32_t replicas) { memcached_return_t rc; if (! self) return MEMCACHED_INVALID_ARGUMENTS; if (! host_map) return MEMCACHED_INVALID_ARGUMENTS; memcached_server_distribution_t old; old= memcached_behavior_get_distribution(self); rc =memcached_behavior_set_distribution(self, MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET); if (rc != MEMCACHED_SUCCESS) { return rc; } rc= memcached_virtual_bucket_create(self, host_map, forward_map, buckets, replicas); if (rc != MEMCACHED_SUCCESS) { memcached_behavior_set_distribution(self, old); } return rc; }
static VALUE mc_initialize(VALUE self, VALUE opts) { memcached_st *mc; VALUE servers_aryv, prefixv, hashv, distributionv; Data_Get_Struct(self, memcached_st, mc); hashv = rb_hash_aref(opts, sym_hash); distributionv = rb_hash_aref(opts, sym_distribution); prefixv = rb_hash_aref(opts, sym_prefix); servers_aryv = rb_hash_aref(opts, sym_servers); if (!NIL_P(hashv)) { memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_HASH, hash_behavior(hashv)); memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_KETAMA_HASH, hash_behavior(hashv)); } if (!NIL_P(distributionv)) memcached_behavior_set_distribution(mc, distribution_behavior(distributionv)); if (RTEST( rb_hash_aref(opts, sym_ketama) )) memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_KETAMA, true); if (RTEST( rb_hash_aref(opts, sym_ketama_weighted) )) memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true); if (RTEST( rb_hash_aref(opts, sym_hash_with_prefix) )) memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY, true); if (RTEST( rb_hash_aref(opts, sym_binary) )) memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true); if (!NIL_P(prefixv)) memcached_callback_set(mc, MEMCACHED_CALLBACK_PREFIX_KEY, StringValuePtr(prefixv)); if (!NIL_P(servers_aryv)) { char* server; int i; for (i = 0; i < RARRAY_LEN(servers_aryv); i++) { server = StringValuePtr(RARRAY_PTR(servers_aryv)[i]); memcached_server_push(mc, memcached_servers_parse(server)); } } else { VALUE hostv, portv, weightv; char* host; int port, weight; hostv = rb_hash_aref(opts, sym_host); portv = rb_hash_aref(opts, sym_port); weightv = rb_hash_aref(opts, sym_weight); host = StringValuePtr(hostv); port = NIL_P(portv) ? MEMCACHED_DEFAULT_PORT : NUM2INT(portv); weight = NIL_P(weightv) ? 0 : NUM2INT(weightv); memcached_server_add_with_weight(mc, StringValuePtr(hostv), port, weight); } return self; }
memcached_return_t memcached_behavior_set(memcached_st *ptr, const memcached_behavior_t flag, uint64_t data) { switch (flag) { case MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS: ptr->number_of_replicas= (uint32_t)data; break; case MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK: ptr->io_msg_watermark= (uint32_t) data; break; case MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK: ptr->io_bytes_watermark= (uint32_t)data; break; case MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH: ptr->io_key_prefetch = (uint32_t)data; break; case MEMCACHED_BEHAVIOR_SND_TIMEOUT: ptr->snd_timeout= (int32_t)data; break; case MEMCACHED_BEHAVIOR_RCV_TIMEOUT: ptr->rcv_timeout= (int32_t)data; break; case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT: ptr->server_failure_limit= (uint32_t)data; break; case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL: memcached_quit(ptr); // We need t shutdown all of the connections to make sure we do the correct protocol if (data) { ptr->flags.verify_key= false; } ptr->flags.binary_protocol= set_flag(data); break; case MEMCACHED_BEHAVIOR_SUPPORT_CAS: ptr->flags.support_cas= set_flag(data); break; case MEMCACHED_BEHAVIOR_NO_BLOCK: ptr->flags.no_block= set_flag(data); memcached_quit(ptr); break; case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS: ptr->flags.buffer_requests= set_flag(data); memcached_quit(ptr); break; case MEMCACHED_BEHAVIOR_USE_UDP: if (memcached_server_count(ptr)) { return MEMCACHED_FAILURE; } ptr->flags.use_udp= set_flag(data); if (data) { ptr->flags.no_reply= set_flag(data); } break; case MEMCACHED_BEHAVIOR_TCP_NODELAY: ptr->flags.tcp_nodelay= set_flag(data); memcached_quit(ptr); break; case MEMCACHED_BEHAVIOR_TCP_KEEPALIVE: ptr->flags.tcp_keepalive= set_flag(data); memcached_quit(ptr); break; case MEMCACHED_BEHAVIOR_DISTRIBUTION: return memcached_behavior_set_distribution(ptr, (memcached_server_distribution_t)data); case MEMCACHED_BEHAVIOR_KETAMA: { if (data) { (void)memcached_behavior_set_key_hash(ptr, MEMCACHED_HASH_MD5); (void)memcached_behavior_set_distribution_hash(ptr, MEMCACHED_HASH_MD5); (void)memcached_behavior_set_distribution(ptr, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA); } else { (void)memcached_behavior_set_key_hash(ptr, MEMCACHED_HASH_DEFAULT); (void)memcached_behavior_set_distribution_hash(ptr, MEMCACHED_HASH_DEFAULT); (void)memcached_behavior_set_distribution(ptr, MEMCACHED_DISTRIBUTION_MODULA); } break; } case MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED: { (void)memcached_behavior_set_key_hash(ptr, MEMCACHED_HASH_MD5); (void)memcached_behavior_set_distribution_hash(ptr, MEMCACHED_HASH_MD5); ptr->flags.ketama_weighted= set_flag(data); /** @note We try to keep the same distribution going. This should be deprecated and rewritten. */ return memcached_behavior_set_distribution(ptr, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA); } case MEMCACHED_BEHAVIOR_HASH: return memcached_behavior_set_key_hash(ptr, (memcached_hash_t)(data)); case MEMCACHED_BEHAVIOR_KETAMA_HASH: return memcached_behavior_set_distribution_hash(ptr, (memcached_hash_t)(data)); case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS: ptr->flags.use_cache_lookups= set_flag(data); memcached_quit(ptr); break; case MEMCACHED_BEHAVIOR_VERIFY_KEY: if (ptr->flags.binary_protocol) return MEMCACHED_FAILURE; ptr->flags.verify_key= set_flag(data); break; case MEMCACHED_BEHAVIOR_SORT_HOSTS: { ptr->flags.use_sort_hosts= set_flag(data); run_distribution(ptr); break; } case MEMCACHED_BEHAVIOR_POLL_TIMEOUT: ptr->poll_timeout= (int32_t)data; break; case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT: ptr->connect_timeout= (int32_t)data; break; case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT: ptr->retry_timeout= (int32_t)data; break; case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE: ptr->send_size= (int32_t)data; memcached_quit(ptr); break; case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE: ptr->recv_size= (int32_t)data; memcached_quit(ptr); break; case MEMCACHED_BEHAVIOR_TCP_KEEPIDLE: ptr->tcp_keepidle= (uint32_t)data; memcached_quit(ptr); break; case MEMCACHED_BEHAVIOR_USER_DATA: return MEMCACHED_FAILURE; case MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY: ptr->flags.hash_with_prefix_key= set_flag(data); break; case MEMCACHED_BEHAVIOR_NOREPLY: ptr->flags.no_reply= set_flag(data); break; case MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS: ptr->flags.auto_eject_hosts= set_flag(data); break; case MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ: srandom((uint32_t) time(NULL)); ptr->flags.randomize_replica_read= set_flag(data); break; case MEMCACHED_BEHAVIOR_CORK: { memcached_server_write_instance_st instance; bool action= set_flag(data); if (action == false) { ptr->flags.cork= set_flag(false); return MEMCACHED_SUCCESS; } instance= memcached_server_instance_fetch(ptr, 0); if (! instance) return MEMCACHED_NO_SERVERS; /* We just try the first host, and if it is down we return zero */ memcached_return_t rc; rc= memcached_connect(instance); if (rc != MEMCACHED_SUCCESS) { return rc; } /* Now we test! */ memcached_ternary_t enabled; enabled= test_cork(instance, true); switch (enabled) { case MEM_FALSE: return ptr->cached_errno ? MEMCACHED_ERRNO : MEMCACHED_FAILURE ; case MEM_TRUE: { enabled= test_cork(instance, false); if (enabled == false) // Possible bug in OS? { memcached_quit_server(instance, false); // We should reset everything on this error. return MEMCACHED_ERRNO; // Errno will be true because we will have already set it. } ptr->flags.cork= true; ptr->flags.tcp_nodelay= true; memcached_quit(ptr); // We go on and reset the connections. } break; case MEM_NOT: default: return MEMCACHED_NOT_SUPPORTED; } } break; case MEMCACHED_BEHAVIOR_MAX: default: /* Shouldn't get here */ WATCHPOINT_ASSERT(0); return MEMCACHED_FAILURE; } return MEMCACHED_SUCCESS; }
memcached_return_t memcached_behavior_set(memcached_st *ptr, const memcached_behavior_t flag, uint64_t data) { switch (flag) { case MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS: ptr->number_of_replicas= (uint32_t)data; break; case MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK: ptr->io_msg_watermark= (uint32_t) data; break; case MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK: ptr->io_bytes_watermark= (uint32_t)data; break; case MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH: ptr->io_key_prefetch = (uint32_t)data; break; case MEMCACHED_BEHAVIOR_SND_TIMEOUT: ptr->snd_timeout= (int32_t)data; break; case MEMCACHED_BEHAVIOR_RCV_TIMEOUT: ptr->rcv_timeout= (int32_t)data; break; case MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS: ptr->flags.auto_eject_hosts= set_flag(data); case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT: ptr->server_failure_limit= (uint32_t)data; break; case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL: send_quit(ptr); // We need t shutdown all of the connections to make sure we do the correct protocol if (data) { ptr->flags.verify_key= false; } ptr->flags.binary_protocol= set_flag(data); break; case MEMCACHED_BEHAVIOR_SUPPORT_CAS: ptr->flags.support_cas= set_flag(data); break; case MEMCACHED_BEHAVIOR_NO_BLOCK: ptr->flags.no_block= set_flag(data); send_quit(ptr); break; case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS: ptr->flags.buffer_requests= set_flag(data); send_quit(ptr); break; case MEMCACHED_BEHAVIOR_USE_UDP: if (memcached_server_count(ptr)) { return MEMCACHED_FAILURE; } ptr->flags.use_udp= set_flag(data); if (data) { ptr->flags.no_reply= set_flag(data); } break; case MEMCACHED_BEHAVIOR_TCP_NODELAY: ptr->flags.tcp_nodelay= set_flag(data); send_quit(ptr); break; case MEMCACHED_BEHAVIOR_TCP_KEEPALIVE: ptr->flags.tcp_keepalive= set_flag(data); send_quit(ptr); break; case MEMCACHED_BEHAVIOR_DISTRIBUTION: return memcached_behavior_set_distribution(ptr, (memcached_server_distribution_t)data); case MEMCACHED_BEHAVIOR_KETAMA: { if (data) // Turn on return memcached_behavior_set_distribution(ptr, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA); return memcached_behavior_set_distribution(ptr, MEMCACHED_DISTRIBUTION_MODULA); } case MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED: { (void)memcached_behavior_set_key_hash(ptr, MEMCACHED_HASH_MD5); (void)memcached_behavior_set_distribution_hash(ptr, MEMCACHED_HASH_MD5); ptr->ketama.weighted= set_flag(data); /** @note We try to keep the same distribution going. This should be deprecated and rewritten. */ return memcached_behavior_set_distribution(ptr, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA); } case MEMCACHED_BEHAVIOR_HASH: return memcached_behavior_set_key_hash(ptr, (memcached_hash_t)(data)); case MEMCACHED_BEHAVIOR_KETAMA_HASH: return memcached_behavior_set_distribution_hash(ptr, (memcached_hash_t)(data)); case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS: return memcached_set_error_string(ptr, MEMCACHED_DEPRECATED, memcached_string_with_size("MEMCACHED_BEHAVIOR_CACHE_LOOKUPS has been deprecated.")); case MEMCACHED_BEHAVIOR_VERIFY_KEY: if (ptr->flags.binary_protocol) return memcached_set_error_string(ptr, MEMCACHED_INVALID_ARGUMENTS, memcached_string_with_size("MEMCACHED_BEHAVIOR_VERIFY_KEY if the binary protocol has been enabled.")); ptr->flags.verify_key= set_flag(data); break; case MEMCACHED_BEHAVIOR_SORT_HOSTS: { ptr->flags.use_sort_hosts= set_flag(data); run_distribution(ptr); break; } case MEMCACHED_BEHAVIOR_POLL_TIMEOUT: ptr->poll_timeout= (int32_t)data; break; case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT: ptr->connect_timeout= (int32_t)data; break; case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT: ptr->retry_timeout= (int32_t)data; break; case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE: ptr->send_size= (int32_t)data; send_quit(ptr); break; case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE: ptr->recv_size= (int32_t)data; send_quit(ptr); break; case MEMCACHED_BEHAVIOR_TCP_KEEPIDLE: ptr->tcp_keepidle= (uint32_t)data; send_quit(ptr); break; case MEMCACHED_BEHAVIOR_USER_DATA: return memcached_set_error_string(ptr, MEMCACHED_DEPRECATED, memcached_string_with_size("MEMCACHED_BEHAVIOR_USER_DATA deprecated.")); case MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY: ptr->flags.hash_with_prefix_key= set_flag(data); break; case MEMCACHED_BEHAVIOR_NOREPLY: ptr->flags.no_reply= set_flag(data); break; case MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS: ptr->flags.auto_eject_hosts= set_flag(data); break; case MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ: srandom((uint32_t) time(NULL)); ptr->flags.randomize_replica_read= set_flag(data); break; case MEMCACHED_BEHAVIOR_CORK: { return memcached_set_error_string(ptr, MEMCACHED_DEPRECATED, memcached_string_with_size("MEMCACHED_BEHAVIOR_CORK is now incorporated into the driver by default.")); } break; case MEMCACHED_BEHAVIOR_LOAD_FROM_FILE: return memcached_set_error_string(ptr, MEMCACHED_INVALID_ARGUMENTS, memcached_string_with_size("MEMCACHED_BEHAVIOR_LOAD_FROM_FILE can not be set with memcached_behavior_set()")); case MEMCACHED_BEHAVIOR_MAX: default: /* Shouldn't get here */ WATCHPOINT_ASSERT(0); return memcached_set_error_string(ptr, MEMCACHED_INVALID_ARGUMENTS, memcached_string_with_size("Invalid behavior passed to memcached_behavior_set()")); } return MEMCACHED_SUCCESS; }