Skip to content

Commit 80253e8

Browse files
committed
Added Memcached::setBucket
1 parent 6d19890 commit 80253e8

File tree

4 files changed

+148
-87
lines changed

4 files changed

+148
-87
lines changed

memcached-api.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ public function setOption( $option, $value ) {}
253253

254254
public function setOptions( array $options ) {}
255255

256-
public function setBucket( array $host_map, array $forward_map, $buckets, $replicas ) {}
256+
public function setBucket( array $host_map, array $forward_map, $replicas ) {}
257257

258258
public function addServer( $host, $port, $weight = 0 ) {}
259259

@@ -285,7 +285,7 @@ public function isPersistent( ) {}
285285

286286
public function isPristine( ) {}
287287

288-
public function setSaslAuthData( $username, $password ) {}
288+
public function setSaslAuthData( $username, $password ) {}
289289

290290
}
291291

package.xml

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
116116
<file role='test' name='types.phpt'/>
117117
<file role='test' name='types_multi.phpt'/>
118118
<file role='test' name='undefined_set.phpt'/>
119+
<file role='test' name='vbucket.phpt'/>
119120
<file role='test' name='testdata.res'/>
120121
</dir>
121122
</dir>

php_memcached.c

+99-85
Original file line numberDiff line numberDiff line change
@@ -2522,100 +2522,115 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML
25222522
return 1;
25232523
}
25242524

2525-
/* {{{ Memcached::setBucket(array host_map, array forward_map, long buckets, long replicas)
2525+
static
2526+
uint32_t *s_zval_to_uint32_array (zval *input, size_t *num_elements TSRMLS_DC)
2527+
{
2528+
zval **ppzval;
2529+
uint32_t *retval;
2530+
size_t i = 0;
2531+
2532+
*num_elements = zend_hash_num_elements(Z_ARRVAL_P(input));
2533+
2534+
if (!*num_elements) {
2535+
return NULL;
2536+
}
2537+
2538+
retval = ecalloc(*num_elements, sizeof(uint32_t));
2539+
2540+
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(input));
2541+
zend_hash_get_current_data(Z_ARRVAL_P(input), (void **) &ppzval) == SUCCESS;
2542+
zend_hash_move_forward(Z_ARRVAL_P(input)), i++) {
2543+
2544+
long value = 0;
2545+
2546+
if (Z_TYPE_PP(ppzval) == IS_LONG) {
2547+
value = Z_LVAL_PP(ppzval);
2548+
}
2549+
else {
2550+
zval tmp_zval, *tmp_pzval;
2551+
tmp_zval = **ppzval;
2552+
zval_copy_ctor(&tmp_zval);
2553+
tmp_pzval = &tmp_zval;
2554+
convert_to_long(tmp_pzval);
2555+
2556+
value = (Z_LVAL_P(tmp_pzval) > 0) ? Z_LVAL_P(tmp_pzval) : 0;
2557+
zval_dtor(tmp_pzval);
2558+
}
2559+
2560+
if (value < 0) {
2561+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "the map must contain positive integers");
2562+
efree (retval);
2563+
*num_elements = 0;
2564+
return NULL;
2565+
}
2566+
retval [i] = (uint32_t) value;
2567+
}
2568+
return retval;
2569+
}
2570+
2571+
/* {{{ Memcached::setBucket(array host_map, array forward_map, integer replicas)
25262572
Sets the memcached virtual buckets */
25272573

25282574
PHP_METHOD(Memcached, setBucket)
25292575
{
2530-
zval *host_map;
2531-
zval *forward_map;
2532-
long buckets;
2533-
long replicas;
2534-
2535-
uint32_t *hm = NULL,*fm = NULL;
2536-
zend_bool ok = 1;
2537-
uint key_len;
2538-
char *key;
2539-
ulong key_index;
2540-
zval **value;
2576+
zval *zserver_map;
2577+
zval *zforward_map = NULL;
2578+
long replicas = 0;
2579+
zend_bool retval = 1;
2580+
2581+
uint32_t *server_map = NULL, *forward_map = NULL;
2582+
size_t server_map_len = 0, forward_map_len = 0;
2583+
memcached_return rc;
25412584
MEMC_METHOD_INIT_VARS;
2542-
2543-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aa!ll", &host_map, &forward_map, &buckets, &replicas) == FAILURE) {
2585+
2586+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aa!l", &zserver_map, &zforward_map, &replicas) == FAILURE) {
25442587
return;
25452588
}
2546-
2547-
2548-
hm = (uint32_t*)malloc(buckets * sizeof(uint32_t));
2549-
2550-
int i = 0;
2551-
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(host_map));
2552-
zend_hash_get_current_data(Z_ARRVAL_P(host_map), (void *) &value) == SUCCESS;
2553-
zend_hash_move_forward(Z_ARRVAL_P(host_map))) {
2554-
2555-
if (i < buckets) {
2556-
if (zend_hash_get_current_key_ex(Z_ARRVAL_P(host_map), &key, &key_len, &key_index, 0, NULL) == HASH_KEY_IS_LONG) {
2557-
zval copy = **value;
2558-
zval_copy_ctor(&copy);
2559-
INIT_PZVAL(&copy);
2560-
convert_to_long(&copy);
2561-
hm[i] = Z_LVAL_P(&copy);
2562-
++i;
2563-
zval_dtor(&copy);
2564-
} else {
2565-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid configuration option");
2566-
ok = 0;
2567-
}
2568-
} else {
2569-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "array size mismatch");
2570-
ok = 0;
2571-
break;
2572-
}
2589+
2590+
MEMC_METHOD_FETCH_OBJECT;
2591+
2592+
if (zend_hash_num_elements (Z_ARRVAL_P(zserver_map)) == 0) {
2593+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "server map cannot be empty");
2594+
RETURN_FALSE;
25732595
}
25742596

2575-
if (i != buckets) {
2576-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "array size mismatch");
2577-
ok = 0;
2578-
}
2579-
2580-
i = 0;
2581-
if (ok != 0 && forward_map != NULL) {
2582-
fm = (uint32_t*)malloc(buckets * sizeof(uint32_t));
2583-
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(forward_map));
2584-
zend_hash_get_current_data(Z_ARRVAL_P(forward_map), (void *) &value) == SUCCESS;
2585-
zend_hash_move_forward(Z_ARRVAL_P(forward_map))) {
2586-
2587-
if (i < buckets) {
2588-
if (zend_hash_get_current_key_ex(Z_ARRVAL_P(forward_map), &key, &key_len, &key_index, 0, NULL) == HASH_KEY_IS_LONG) {
2589-
zval copy = **value;
2590-
zval_copy_ctor(&copy);
2591-
INIT_PZVAL(&copy);
2592-
2593-
convert_to_long(&copy);
2594-
fm[i] = Z_LVAL_P(&copy);
2595-
++i;
2596-
zval_dtor(&copy);
2597-
} else {
2598-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid configuration option");
2599-
ok = 0;
2600-
}
2601-
} else {
2602-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "array size mismatch");
2603-
ok = 0;
2604-
}
2597+
if (zforward_map && zend_hash_num_elements (Z_ARRVAL_P(zserver_map)) != zend_hash_num_elements (Z_ARRVAL_P(zforward_map))) {
2598+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "forward_map length must match the server_map length");
2599+
RETURN_FALSE;
2600+
}
2601+
2602+
if (replicas < 0) {
2603+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "replicas must be larger than zero");
2604+
RETURN_FALSE;
2605+
}
2606+
2607+
server_map = s_zval_to_uint32_array (zserver_map, &server_map_len TSRMLS_CC);
2608+
2609+
if (!server_map) {
2610+
RETURN_FALSE;
2611+
}
2612+
2613+
if (zforward_map) {
2614+
forward_map = s_zval_to_uint32_array (zforward_map, &forward_map_len TSRMLS_CC);
2615+
2616+
if (!forward_map) {
2617+
efree (server_map);
2618+
RETURN_FALSE;
26052619
}
26062620
}
2607-
2608-
MEMC_METHOD_FETCH_OBJECT;
2609-
2610-
if (memcached_bucket_set(m_obj->memc, hm, fm, buckets, replicas) != MEMCACHED_SUCCESS)
2611-
{
2612-
ok = 0;
2613-
php_error_docref(NULL TSRMLS_CC, E_WARNING,"memcached_bucket_set don't returned MEMCACHED_SUCCESS");
2621+
2622+
rc = memcached_bucket_set (m_obj->memc, server_map, forward_map, (uint32_t) server_map_len, replicas);
2623+
2624+
if (php_memc_handle_error(i_obj, rc TSRMLS_CC) < 0) {
2625+
retval = 0;;
26142626
}
2615-
free(hm);
2616-
free(fm);
2617-
RETURN_BOOL(ok);
2618-
2627+
2628+
efree(server_map);
2629+
2630+
if (forward_map) {
2631+
efree(forward_map);
2632+
}
2633+
RETURN_BOOL(retval);
26192634
}
26202635
/* }}} */
26212636

@@ -3869,10 +3884,9 @@ ZEND_BEGIN_ARG_INFO(arginfo_setOptions, 0)
38693884
ZEND_ARG_INFO(0, options)
38703885
ZEND_END_ARG_INFO()
38713886

3872-
ZEND_BEGIN_ARG_INFO(arginfo_setBucket, 0)
3887+
ZEND_BEGIN_ARG_INFO(arginfo_setBucket, 3)
38733888
ZEND_ARG_INFO(0, host_map)
38743889
ZEND_ARG_INFO(0, forward_map)
3875-
ZEND_ARG_INFO(0, buckets)
38763890
ZEND_ARG_INFO(0, replicas)
38773891
ZEND_END_ARG_INFO()
38783892

@@ -3963,7 +3977,7 @@ static zend_function_entry memcached_class_methods[] = {
39633977
MEMC_ME(getOption, arginfo_getOption)
39643978
MEMC_ME(setOption, arginfo_setOption)
39653979
MEMC_ME(setOptions, arginfo_setOptions)
3966-
MEMC_ME(setBucket, arginfo_setBucket)
3980+
MEMC_ME(setBucket, arginfo_setBucket)
39673981
#ifdef HAVE_MEMCACHED_SASL
39683982
MEMC_ME(setSaslAuthData, arginfo_setSaslAuthData)
39693983
#endif

tests/vbucket.phpt

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
Memcached virtual buckets
3+
--SKIPIF--
4+
<?php if (!extension_loaded("memcached")) print "skip"; ?>
5+
--FILE--
6+
<?php
7+
$m = new Memcached();
8+
var_dump ($m->setOption (Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_VIRTUAL_BUCKET));
9+
10+
$m->addServer('127.0.0.1', 11211, 1);
11+
12+
var_dump ($m->setBucket (array (1, 2, 3), null, 2));
13+
14+
var_dump ($m->setBucket (array (1,2,2), array (1,2,2), 2));
15+
16+
var_dump ($m->setBucket (array ('a', 'b', 'c'), null, 2));
17+
18+
var_dump ($m->setBucket (array (), null, 2));
19+
20+
var_dump ($m->setBucket (array (), array (), -1));
21+
22+
var_dump ($m->setBucket (null, array (), -1));
23+
24+
var_dump ($m->setBucket (array (-1), array (-1), 1));
25+
26+
echo "OK\n";
27+
28+
?>
29+
--EXPECTF--
30+
bool(true)
31+
bool(true)
32+
bool(true)
33+
bool(true)
34+
35+
Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d
36+
bool(false)
37+
38+
Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d
39+
bool(false)
40+
41+
Warning: Memcached::setBucket() expects parameter 1 to be array, null given in %s on line %d
42+
NULL
43+
44+
Warning: Memcached::setBucket(): the map must contain positive integers in %s on line %d
45+
bool(false)
46+
OK

0 commit comments

Comments
 (0)