Skip to content

Commit 18637bf

Browse files
committed
Update target index when rehashing.
1 parent 5b0ffe2 commit 18637bf

File tree

4 files changed

+55
-50
lines changed

4 files changed

+55
-50
lines changed

redis_array.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, i
207207
b_write_cmd = ra_is_write_cmd(ra, cmd, cmd_len);
208208

209209
if(ra->index && b_write_cmd) { // add MULTI + SADD
210-
ra_index_multi(ra, redis_inst);
210+
ra_index_multi(redis_inst);
211211
}
212212

213213
/* pass call through */
@@ -230,10 +230,10 @@ ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, i
230230
zval_dtor(&z_tmp);
231231

232232
// add keys to index.
233-
ra_index_key(ra, redis_inst, key, key_len TSRMLS_CC);
233+
ra_index_key(key, key_len, redis_inst, 1 TSRMLS_CC);
234234

235235
// call EXEC
236-
ra_index_exec(ra, redis_inst, return_value);
236+
ra_index_exec(redis_inst, return_value);
237237
} else { // call directly through.
238238
call_user_function(&redis_ce->function_table, &redis_inst, &z_fun, return_value, argc, z_callargs TSRMLS_CC);
239239

redis_array_impl.c

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ ra_find_key(RedisArray *ra, zval *z_args, const char *cmd, int *key_len) {
228228
}
229229

230230
void
231-
ra_index_multi(RedisArray *ra, zval *z_redis) {
231+
ra_index_multi(zval *z_redis) {
232232

233233
zval z_fun_multi, z_ret;
234234

@@ -239,7 +239,7 @@ ra_index_multi(RedisArray *ra, zval *z_redis) {
239239
}
240240

241241
void
242-
ra_index_key(RedisArray *ra, zval *z_redis, const char *key, int key_len TSRMLS_DC) {
242+
ra_index_key(const char *key, int key_len, zval *z_redis TSRMLS_DC) {
243243

244244
int i;
245245
zval z_fun_sadd, z_ret, *z_args[2];
@@ -263,7 +263,7 @@ ra_index_key(RedisArray *ra, zval *z_redis, const char *key, int key_len TSRMLS_
263263
}
264264

265265
void
266-
ra_index_exec(RedisArray *ra, zval *z_redis, zval *return_value) {
266+
ra_index_exec(zval *z_redis, zval *return_value) {
267267

268268
zval z_fun_exec, z_ret, **zp_tmp;
269269

@@ -273,7 +273,7 @@ ra_index_exec(RedisArray *ra, zval *z_redis, zval *return_value) {
273273

274274
/* extract first element of exec array and put into return_value. */
275275
if(Z_TYPE(z_ret) == IS_ARRAY) {
276-
if(zend_hash_quick_find(Z_ARRVAL(z_ret), NULL, 0, 0, (void**)&zp_tmp) != FAILURE) {
276+
if(return_value && zend_hash_quick_find(Z_ARRVAL(z_ret), NULL, 0, 0, (void**)&zp_tmp) != FAILURE) {
277277
*return_value = **zp_tmp;
278278
zval_copy_ctor(return_value);
279279
}
@@ -376,16 +376,49 @@ ra_get_key_type(zval *z_redis, const char *key, int key_len) {
376376
return Z_LVAL(z_ret);
377377
}
378378

379+
/* delete key from source server index during rehashing */
380+
static void
381+
ra_remove_from_index(zval *z_redis, const char *key, int key_len) {
382+
383+
int i;
384+
zval z_fun_get, z_fun_srem, z_ret, *z_args[2];
385+
386+
/* run SREM on source index */
387+
ZVAL_STRINGL(&z_fun_srem, "SREM", 4, 0);
388+
MAKE_STD_ZVAL(z_args[0]);
389+
ZVAL_STRING(z_args[0], PHPREDIS_INDEX_NAME, 0);
390+
MAKE_STD_ZVAL(z_args[1]);
391+
ZVAL_STRINGL(z_args[1], key, key_len, 0);
392+
393+
call_user_function(&redis_ce->function_table, &z_redis, &z_fun_srem, &z_ret, 2, z_args TSRMLS_CC);
394+
395+
/* cleanup */
396+
efree(z_args[0]);
397+
efree(z_args[1]);
398+
}
399+
400+
401+
/* delete key from source server during rehashing */
379402
static zend_bool
380403
ra_del_key(const char *key, int key_len, zval *z_from) {
381404

382-
zval z_fun_del, z_ret, *z_args[2];
405+
zval z_fun_del, z_ret, *z_args;
383406

384-
/* run GET on source */
385-
MAKE_STD_ZVAL(z_args[0]);
407+
/* in a transaction */
408+
ra_index_multi(z_from);
409+
410+
/* run DEL on source */
411+
MAKE_STD_ZVAL(z_args);
386412
ZVAL_STRINGL(&z_fun_del, "DEL", 3, 0);
387-
ZVAL_STRINGL(z_args[0], key, key_len, 0);
388-
call_user_function(&redis_ce->function_table, &z_from, &z_fun_del, &z_ret, 1, z_args TSRMLS_CC);
413+
ZVAL_STRINGL(z_args, key, key_len, 0);
414+
call_user_function(&redis_ce->function_table, &z_from, &z_fun_del, &z_ret, 1, &z_args TSRMLS_CC);
415+
efree(z_args);
416+
417+
/* remove key from index */
418+
ra_remove_from_index(z_from, key, key_len);
419+
420+
/* close transaction */
421+
ra_index_exec(z_from, NULL);
389422
}
390423

391424
static zend_bool
@@ -426,6 +459,9 @@ ra_move_key(const char *key, int key_len, zval *z_from, zval *z_to) {
426459
long type = ra_get_key_type(z_from, key, key_len);
427460
zend_bool success = 0;
428461

462+
/* open transaction on target server */
463+
ra_index_multi(z_to);
464+
429465
switch(type) {
430466
case REDIS_STRING:
431467
success = ra_move_string(key, key_len, z_from, z_to);
@@ -454,34 +490,11 @@ ra_move_key(const char *key, int key_len, zval *z_from, zval *z_to) {
454490

455491
if(success) {
456492
ra_del_key(key, key_len, z_from);
493+
ra_index_key(key, key_len, z_to TSRMLS_CC);
457494
}
458-
}
459-
460-
void
461-
ra_remove_from_index(zval *z_redis, const char **keys, int *key_lens, int count) {
462-
463-
int i;
464-
zval z_fun_get, z_fun_srem, z_ret, **z_args;
465-
466-
z_args = emalloc((count+1) * sizeof(zval*));
467-
468-
/* run SREM on source index */
469-
ZVAL_STRINGL(&z_fun_srem, "SREM", 4, 0);
470-
MAKE_STD_ZVAL(z_args[0]);
471-
ZVAL_STRING(z_args[0], PHPREDIS_INDEX_NAME, 0);
472-
473-
for(i = 0; i < count; ++i) {
474-
MAKE_STD_ZVAL(z_args[i+1]);
475-
ZVAL_STRINGL(z_args[i+1], keys[i], key_lens[i], 0);
476-
}
477-
478-
call_user_function(&redis_ce->function_table, &z_redis, &z_fun_srem, &z_ret, count+1, z_args TSRMLS_CC);
479495

480-
/* cleanup */
481-
for(i = 0; i < count; ++i) {
482-
efree(z_args[i+1]);
483-
}
484-
efree(z_args);
496+
/* close transaction */
497+
ra_index_exec(z_to, NULL);
485498
}
486499

487500
static void
@@ -509,19 +522,11 @@ ra_rehash_server(RedisArray *ra, zval *z_redis, const char *hostname, zend_bool
509522
z_target = ra_find_node(ra, keys[i], key_lens[i], &target_pos);
510523

511524
if(strcmp(hostname, ra->hosts[target_pos])) { /* different host */
512-
513525
/* php_printf("move [%s] from [%s] to [%s]\n", keys[i], hostname, ra->hosts[target_pos]); */
514-
515526
ra_move_key(keys[i], key_lens[i], z_redis, z_target);
516-
} else {
517-
// php_printf("key [%s] stays on [%s]\n", keys[i], hostname);
518527
}
519528
}
520529

521-
if(b_index) {
522-
ra_remove_from_index(z_redis, (const char**)keys, key_lens, count);
523-
}
524-
525530
// cleanup
526531
for(i = 0; i < count; ++i) {
527532
efree(keys[i]);

redis_array_impl.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ zval *ra_find_node(RedisArray *ra, const char *key, int key_len, int *out_pos);
1111
void ra_init_function_table(RedisArray *ra);
1212

1313
char * ra_find_key(RedisArray *ra, zval *z_args, const char *cmd, int *key_len);
14-
void ra_index_multi(RedisArray *ra, zval *z_redis);
14+
void ra_index_multi(zval *z_redis);
1515

16-
void ra_index_key(RedisArray *ra, zval *z_redis, const char *key, int key_len TSRMLS_DC);
17-
void ra_index_exec(RedisArray *ra, zval *z_redis, zval *return_value);
16+
void ra_index_key(const char *key, int key_len, zval *z_redis TSRMLS_DC);
17+
void ra_index_exec(zval *z_redis, zval *return_value);
1818
zend_bool ra_is_write_cmd(RedisArray *ra, const char *cmd, int cmd_len);
1919

2020
void ra_rehash(RedisArray *ra);

tests/array-rehash.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function report_info($ra) {
1919
}
2020
}
2121

22-
$n = 10000;
22+
$n = 10;
2323
$data = array();
2424
for($i = 0; $i < $n; $i++) {
2525
$tmp = $i; //rand();

0 commit comments

Comments
 (0)