mirror of
https://github.com/php-win-ext/php-memcached.git
synced 2026-03-24 00:52:18 +01:00
Added Memcached::setBucket
This commit is contained in:
@@ -253,7 +253,7 @@ class Memcached {
|
||||
|
||||
public function setOptions( array $options ) {}
|
||||
|
||||
public function setBucket( array $host_map, array $forward_map, $buckets, $replicas ) {}
|
||||
public function setBucket( array $host_map, array $forward_map, $replicas ) {}
|
||||
|
||||
public function addServer( $host, $port, $weight = 0 ) {}
|
||||
|
||||
@@ -285,7 +285,7 @@ class Memcached {
|
||||
|
||||
public function isPristine( ) {}
|
||||
|
||||
public function setSaslAuthData( $username, $password ) {}
|
||||
public function setSaslAuthData( $username, $password ) {}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file role='test' name='types.phpt'/>
|
||||
<file role='test' name='types_multi.phpt'/>
|
||||
<file role='test' name='undefined_set.phpt'/>
|
||||
<file role='test' name='vbucket.phpt'/>
|
||||
<file role='test' name='testdata.res'/>
|
||||
</dir>
|
||||
</dir>
|
||||
|
||||
188
php_memcached.c
188
php_memcached.c
@@ -2522,100 +2522,115 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* {{{ Memcached::setBucket(array host_map, array forward_map, long buckets, long replicas)
|
||||
static
|
||||
uint32_t *s_zval_to_uint32_array (zval *input, size_t *num_elements TSRMLS_DC)
|
||||
{
|
||||
zval **ppzval;
|
||||
uint32_t *retval;
|
||||
size_t i = 0;
|
||||
|
||||
*num_elements = zend_hash_num_elements(Z_ARRVAL_P(input));
|
||||
|
||||
if (!*num_elements) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retval = ecalloc(*num_elements, sizeof(uint32_t));
|
||||
|
||||
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(input));
|
||||
zend_hash_get_current_data(Z_ARRVAL_P(input), (void **) &ppzval) == SUCCESS;
|
||||
zend_hash_move_forward(Z_ARRVAL_P(input)), i++) {
|
||||
|
||||
long value = 0;
|
||||
|
||||
if (Z_TYPE_PP(ppzval) == IS_LONG) {
|
||||
value = Z_LVAL_PP(ppzval);
|
||||
}
|
||||
else {
|
||||
zval tmp_zval, *tmp_pzval;
|
||||
tmp_zval = **ppzval;
|
||||
zval_copy_ctor(&tmp_zval);
|
||||
tmp_pzval = &tmp_zval;
|
||||
convert_to_long(tmp_pzval);
|
||||
|
||||
value = (Z_LVAL_P(tmp_pzval) > 0) ? Z_LVAL_P(tmp_pzval) : 0;
|
||||
zval_dtor(tmp_pzval);
|
||||
}
|
||||
|
||||
if (value < 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "the map must contain positive integers");
|
||||
efree (retval);
|
||||
*num_elements = 0;
|
||||
return NULL;
|
||||
}
|
||||
retval [i] = (uint32_t) value;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* {{{ Memcached::setBucket(array host_map, array forward_map, integer replicas)
|
||||
Sets the memcached virtual buckets */
|
||||
|
||||
PHP_METHOD(Memcached, setBucket)
|
||||
{
|
||||
zval *host_map;
|
||||
zval *forward_map;
|
||||
long buckets;
|
||||
long replicas;
|
||||
|
||||
uint32_t *hm = NULL,*fm = NULL;
|
||||
zend_bool ok = 1;
|
||||
uint key_len;
|
||||
char *key;
|
||||
ulong key_index;
|
||||
zval **value;
|
||||
zval *zserver_map;
|
||||
zval *zforward_map = NULL;
|
||||
long replicas = 0;
|
||||
zend_bool retval = 1;
|
||||
|
||||
uint32_t *server_map = NULL, *forward_map = NULL;
|
||||
size_t server_map_len = 0, forward_map_len = 0;
|
||||
memcached_return rc;
|
||||
MEMC_METHOD_INIT_VARS;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aa!ll", &host_map, &forward_map, &buckets, &replicas) == FAILURE) {
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aa!l", &zserver_map, &zforward_map, &replicas) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
hm = (uint32_t*)malloc(buckets * sizeof(uint32_t));
|
||||
|
||||
int i = 0;
|
||||
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(host_map));
|
||||
zend_hash_get_current_data(Z_ARRVAL_P(host_map), (void *) &value) == SUCCESS;
|
||||
zend_hash_move_forward(Z_ARRVAL_P(host_map))) {
|
||||
|
||||
if (i < buckets) {
|
||||
if (zend_hash_get_current_key_ex(Z_ARRVAL_P(host_map), &key, &key_len, &key_index, 0, NULL) == HASH_KEY_IS_LONG) {
|
||||
zval copy = **value;
|
||||
zval_copy_ctor(©);
|
||||
INIT_PZVAL(©);
|
||||
convert_to_long(©);
|
||||
hm[i] = Z_LVAL_P(©);
|
||||
++i;
|
||||
zval_dtor(©);
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid configuration option");
|
||||
ok = 0;
|
||||
}
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "array size mismatch");
|
||||
ok = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i != buckets) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "array size mismatch");
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if (ok != 0 && forward_map != NULL) {
|
||||
fm = (uint32_t*)malloc(buckets * sizeof(uint32_t));
|
||||
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(forward_map));
|
||||
zend_hash_get_current_data(Z_ARRVAL_P(forward_map), (void *) &value) == SUCCESS;
|
||||
zend_hash_move_forward(Z_ARRVAL_P(forward_map))) {
|
||||
|
||||
if (i < buckets) {
|
||||
if (zend_hash_get_current_key_ex(Z_ARRVAL_P(forward_map), &key, &key_len, &key_index, 0, NULL) == HASH_KEY_IS_LONG) {
|
||||
zval copy = **value;
|
||||
zval_copy_ctor(©);
|
||||
INIT_PZVAL(©);
|
||||
|
||||
convert_to_long(©);
|
||||
fm[i] = Z_LVAL_P(©);
|
||||
++i;
|
||||
zval_dtor(©);
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid configuration option");
|
||||
ok = 0;
|
||||
}
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "array size mismatch");
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MEMC_METHOD_FETCH_OBJECT;
|
||||
|
||||
if (memcached_bucket_set(m_obj->memc, hm, fm, buckets, replicas) != MEMCACHED_SUCCESS)
|
||||
{
|
||||
ok = 0;
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,"memcached_bucket_set don't returned MEMCACHED_SUCCESS");
|
||||
|
||||
if (zend_hash_num_elements (Z_ARRVAL_P(zserver_map)) == 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "server map cannot be empty");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
free(hm);
|
||||
free(fm);
|
||||
RETURN_BOOL(ok);
|
||||
|
||||
|
||||
if (zforward_map && zend_hash_num_elements (Z_ARRVAL_P(zserver_map)) != zend_hash_num_elements (Z_ARRVAL_P(zforward_map))) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "forward_map length must match the server_map length");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (replicas < 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "replicas must be larger than zero");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
server_map = s_zval_to_uint32_array (zserver_map, &server_map_len TSRMLS_CC);
|
||||
|
||||
if (!server_map) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (zforward_map) {
|
||||
forward_map = s_zval_to_uint32_array (zforward_map, &forward_map_len TSRMLS_CC);
|
||||
|
||||
if (!forward_map) {
|
||||
efree (server_map);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
rc = memcached_bucket_set (m_obj->memc, server_map, forward_map, (uint32_t) server_map_len, replicas);
|
||||
|
||||
if (php_memc_handle_error(i_obj, rc TSRMLS_CC) < 0) {
|
||||
retval = 0;;
|
||||
}
|
||||
|
||||
efree(server_map);
|
||||
|
||||
if (forward_map) {
|
||||
efree(forward_map);
|
||||
}
|
||||
RETURN_BOOL(retval);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -3869,10 +3884,9 @@ ZEND_BEGIN_ARG_INFO(arginfo_setOptions, 0)
|
||||
ZEND_ARG_INFO(0, options)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_setBucket, 0)
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_setBucket, 3)
|
||||
ZEND_ARG_INFO(0, host_map)
|
||||
ZEND_ARG_INFO(0, forward_map)
|
||||
ZEND_ARG_INFO(0, buckets)
|
||||
ZEND_ARG_INFO(0, replicas)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
@@ -3963,7 +3977,7 @@ static zend_function_entry memcached_class_methods[] = {
|
||||
MEMC_ME(getOption, arginfo_getOption)
|
||||
MEMC_ME(setOption, arginfo_setOption)
|
||||
MEMC_ME(setOptions, arginfo_setOptions)
|
||||
MEMC_ME(setBucket, arginfo_setBucket)
|
||||
MEMC_ME(setBucket, arginfo_setBucket)
|
||||
#ifdef HAVE_MEMCACHED_SASL
|
||||
MEMC_ME(setSaslAuthData, arginfo_setSaslAuthData)
|
||||
#endif
|
||||
|
||||
46
tests/vbucket.phpt
Normal file
46
tests/vbucket.phpt
Normal file
@@ -0,0 +1,46 @@
|
||||
--TEST--
|
||||
Memcached virtual buckets
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("memcached")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$m = new Memcached();
|
||||
var_dump ($m->setOption (Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_VIRTUAL_BUCKET));
|
||||
|
||||
$m->addServer('127.0.0.1', 11211, 1);
|
||||
|
||||
var_dump ($m->setBucket (array (1, 2, 3), null, 2));
|
||||
|
||||
var_dump ($m->setBucket (array (1,2,2), array (1,2,2), 2));
|
||||
|
||||
var_dump ($m->setBucket (array ('a', 'b', 'c'), null, 2));
|
||||
|
||||
var_dump ($m->setBucket (array (), null, 2));
|
||||
|
||||
var_dump ($m->setBucket (array (), array (), -1));
|
||||
|
||||
var_dump ($m->setBucket (null, array (), -1));
|
||||
|
||||
var_dump ($m->setBucket (array (-1), array (-1), 1));
|
||||
|
||||
echo "OK\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: Memcached::setBucket() expects parameter 1 to be array, null given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: Memcached::setBucket(): the map must contain positive integers in %s on line %d
|
||||
bool(false)
|
||||
OK
|
||||
Reference in New Issue
Block a user