Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpredis/phpredis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Favre-Felix <n.favrefelix@gmail.com>2011-08-28 14:32:29 +0400
committerNicolas Favre-Felix <n.favrefelix@gmail.com>2011-08-28 14:32:29 +0400
commit4dcae80fbfa7ccfba5fd6456e2b344ecfdc844a0 (patch)
tree9f9836b70c472d60c258b9be330ba942fa15f29b
parent35f03a2a72e3b39e159b61a8629746c07f4cf437 (diff)
Rehashing callback
-rw-r--r--redis_array.c8
-rw-r--r--redis_array_impl.c30
-rw-r--r--redis_array_impl.h2
-rw-r--r--tests/array-rehash.php6
4 files changed, 36 insertions, 10 deletions
diff --git a/redis_array.c b/redis_array.c
index 1d75beb8..daab7d74 100644
--- a/redis_array.c
+++ b/redis_array.c
@@ -344,11 +344,11 @@ PHP_METHOD(RedisArray, _function)
PHP_METHOD(RedisArray, _rehash)
{
- zval *object;
+ zval *object, *z_cb = NULL;
RedisArray *ra;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
- &object, redis_array_ce) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|z",
+ &object, redis_array_ce, &z_cb) == FAILURE) {
RETURN_FALSE;
}
@@ -356,7 +356,7 @@ PHP_METHOD(RedisArray, _rehash)
RETURN_FALSE;
}
- ra_rehash(ra);
+ ra_rehash(ra, z_cb);
}
PHP_METHOD(RedisArray, info)
diff --git a/redis_array_impl.c b/redis_array_impl.c
index 7a070f23..eb47d431 100644
--- a/redis_array_impl.c
+++ b/redis_array_impl.c
@@ -690,8 +690,25 @@ ra_move_key(const char *key, int key_len, zval *z_from, zval *z_to) {
ra_index_exec(z_to, NULL);
}
+/* callback with the current progress, with hostname and count */
+static void zval_rehash_callback(zval *z_cb, const char *hostname, long count) {
+
+ zval z_ret, *z_args[2];
+
+ /* run cb(hostname, count) */
+ MAKE_STD_ZVAL(z_args[0]);
+ ZVAL_STRING(z_args[0], hostname, 0);
+ MAKE_STD_ZVAL(z_args[1]);
+ ZVAL_LONG(z_args[1], count);
+ call_user_function(EG(function_table), NULL, z_cb, &z_ret, 2, z_args TSRMLS_CC);
+
+ /* cleanup */
+ efree(z_args[0]);
+ efree(z_args[1]);
+}
+
static void
-ra_rehash_server(RedisArray *ra, zval *z_redis, const char *hostname, zend_bool b_index) {
+ra_rehash_server(RedisArray *ra, zval *z_redis, const char *hostname, zend_bool b_index, zval *z_cb) {
char **keys;
int *key_lens;
@@ -706,10 +723,15 @@ ra_rehash_server(RedisArray *ra, zval *z_redis, const char *hostname, zend_bool
count = ra_rehash_scan_keys(z_redis, &keys, &key_lens);
}
+ /* callback */
+ if(z_cb) {
+ zval_rehash_callback(z_cb, hostname, count);
+ }
+
/* for each key, redistribute */
for(i = 0; i < count; ++i) {
- /* TODO: check that we're not moving to the same node. */
+ /* check that we're not moving to the same node. */
z_target = ra_find_node(ra, keys[i], key_lens[i], &target_pos);
if(strcmp(hostname, ra->hosts[target_pos])) { /* different host */
@@ -727,7 +749,7 @@ ra_rehash_server(RedisArray *ra, zval *z_redis, const char *hostname, zend_bool
}
void
-ra_rehash(RedisArray *ra) {
+ra_rehash(RedisArray *ra, zval *z_cb) {
int i;
@@ -736,7 +758,7 @@ ra_rehash(RedisArray *ra) {
return; /* TODO: compare the two rings for equality */
for(i = 0; i < ra->prev->count; ++i) {
- ra_rehash_server(ra, ra->prev->redis[i], ra->prev->hosts[i], ra->index);
+ ra_rehash_server(ra, ra->prev->redis[i], ra->prev->hosts[i], ra->index, z_cb);
}
}
diff --git a/redis_array_impl.h b/redis_array_impl.h
index e346df9d..735b713d 100644
--- a/redis_array_impl.h
+++ b/redis_array_impl.h
@@ -17,6 +17,6 @@ void ra_index_key(const char *key, int key_len, zval *z_redis TSRMLS_DC);
void ra_index_exec(zval *z_redis, zval *return_value);
zend_bool ra_is_write_cmd(RedisArray *ra, const char *cmd, int cmd_len);
-void ra_rehash(RedisArray *ra);
+void ra_rehash(RedisArray *ra, zval *z_cb);
#endif
diff --git a/tests/array-rehash.php b/tests/array-rehash.php
index 1cd62d41..ea1143fb 100644
--- a/tests/array-rehash.php
+++ b/tests/array-rehash.php
@@ -79,7 +79,11 @@ echo "All key/value pairs read successfuly using the new setup with a fallback\n
report_info($ra);
echo "Rehash array.\n";
-$ra->_rehash();
+
+function rehash_callback($host, $count) {
+ echo "Now rehashing $count keys on node $host\n";
+}
+$ra->_rehash('rehash_callback');
echo "Creating a new ring without fallback and reading back all the values.\n";
$ra = new RedisArray($secondRing);