Started resharding and fixed memory corruption issue.

This commit is contained in:
Nicolas Favre-Felix
2011-08-19 14:12:17 +01:00
parent 3564d8fb2f
commit 95219ac284
4 changed files with 103 additions and 9 deletions
+5 -2
View File
@@ -140,6 +140,10 @@ PHP_METHOD(RedisArray, __construct)
RETURN_FALSE;
}
// consider previous array as non-existent if empty.
if(z_prev && zend_hash_num_elements(Z_ARRVAL_P(z_prev)) == 0)
z_prev = NULL;
if(!z_fun || Z_TYPE_P(z_fun) == IS_NULL) { /* either an array name or a list of hosts */
switch(Z_TYPE_P(z0)) {
case IS_STRING:
@@ -226,7 +230,7 @@ ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, i
zval_dtor(&z_tmp);
// add keys to index.
ra_index_key(ra, redis_inst, key, key_len);
ra_index_key(ra, redis_inst, key, key_len TSRMLS_CC);
// call EXEC
ra_index_exec(ra, redis_inst, return_value);
@@ -341,7 +345,6 @@ PHP_METHOD(RedisArray, _function)
PHP_METHOD(RedisArray, _rehash)
{
zval *object;
int i;
RedisArray *ra;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+93 -6
View File
@@ -212,7 +212,7 @@ ra_find_node(RedisArray *ra, const char *key, int key_len, int *out_pos) {
char *
ra_find_key(RedisArray *ra, zval *z_args, const char *cmd, int *key_len) {
zval **zp_tmp;
int key_pos = 0; /* TODO: change this depending on the command */
@@ -239,23 +239,27 @@ ra_index_multi(RedisArray *ra, zval *z_redis) {
}
void
ra_index_key(RedisArray *ra, zval *z_redis, const char *key, int key_len) {
ra_index_key(RedisArray *ra, zval *z_redis, const char *key, int key_len TSRMLS_DC) {
int i;
zval z_fun_sadd, z_ret, *z_args[2];
for(i = 0; i < 2; ++i) MAKE_STD_ZVAL(z_args[i]);
MAKE_STD_ZVAL(z_args[0]);
MAKE_STD_ZVAL(z_args[1]);
/* prepare args */
ZVAL_STRING(&z_fun_sadd, "SADD", 0);
ZVAL_STRINGL(&z_fun_sadd, "SADD", 4, 0);
ZVAL_STRING(z_args[0], PHPREDIS_INDEX_NAME, 0);
ZVAL_STRINGL(z_args[1], key, key_len, 1);
/* run SADD */
call_user_function(&redis_ce->function_table, &z_redis, &z_fun_sadd, &z_ret, 2, z_args TSRMLS_CC);
zval_dtor(&z_ret);
/* don't dtor z_ret, since we're returning z_redis */
efree(z_args[0]);
efree(z_args[1]);
}
void
@@ -294,3 +298,86 @@ ra_is_write_cmd(RedisArray *ra, const char *cmd, int cmd_len) {
return !ret;
}
/* list keys from array index */
static long
ra_rehash_scan_index(zval *z_redis, char ***keys, int **key_lens) {
long count, i;
zval z_fun_smembers, z_ret, *z_arg, **z_data_pp;
HashTable *h_keys;
HashPosition pointer;
/* arg */
MAKE_STD_ZVAL(z_arg);
ZVAL_STRING(z_arg, PHPREDIS_INDEX_NAME, 0);
/* run SMEMBERS */
ZVAL_STRING(&z_fun_smembers, "SMEMBERS", 0);
call_user_function(&redis_ce->function_table, &z_redis, &z_fun_smembers, &z_ret, 1, &z_arg TSRMLS_CC);
efree(z_arg);
if(Z_TYPE(z_ret) != IS_ARRAY) { /* failure */
return -1; /* TODO: log error. */
}
h_keys = Z_ARRVAL(z_ret);
/* allocate key array */
count = zend_hash_num_elements(h_keys);
*keys = emalloc(count * sizeof(char*));
*key_lens = emalloc(count * sizeof(int));
php_printf("Got %ld keys to redistribute\n", count);
for (i = 0, zend_hash_internal_pointer_reset_ex(h_keys, &pointer);
zend_hash_get_current_data_ex(h_keys, (void**) &z_data_pp, &pointer) == SUCCESS;
zend_hash_move_forward_ex(h_keys, &pointer), ++i) {
(*keys)[i] = emalloc(1 + Z_STRLEN_PP(z_data_pp));
(*key_lens)[i] = Z_STRLEN_PP(z_data_pp);
(*keys)[i][(*key_lens)[i]] = 0; /* null-terminate string */
}
/* cleanup */
zval_dtor(&z_ret);
return count;
}
/* list keys using KEYS command */
static long
ra_rehash_scan_keys(zval *z_redis, char ***keys, int **key_lens) {
/* TODO */
return 0;
}
static void
ra_rehash_server(RedisArray *ra, zval *z_redis, zend_bool b_index) {
char **keys;
int *key_lens;
int count;
/* list all keys */
if(b_index) {
count = ra_rehash_scan_index(z_redis, &keys, &key_lens);
} else {
count = ra_rehash_scan_keys(z_redis, &keys, &key_lens);
}
/* for each key, redistribute */
}
void
ra_rehash(RedisArray *ra) {
int i;
/* redistribute the data, server by server. */
if(!ra->prev)
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->index);
}
}
+3 -1
View File
@@ -13,8 +13,10 @@ void ra_init_function_table(RedisArray *ra);
char * ra_find_key(RedisArray *ra, zval *z_args, const char *cmd, int *key_len);
void ra_index_multi(RedisArray *ra, zval *z_redis);
void ra_index_key(RedisArray *ra, zval *z_redis, const char *key, int key_len);
void ra_index_key(RedisArray *ra, zval *z_redis, const char *key, int key_len TSRMLS_DC);
void ra_index_exec(RedisArray *ra, 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);
#endif
+2
View File
@@ -47,4 +47,6 @@ $ra->del(array('a','c'));
$ra->del('a','c');
var_dump($ra->mget(array('a', 'b', 'c')));
$ra->_rehash();
?>