@@ -228,7 +228,7 @@ ra_find_key(RedisArray *ra, zval *z_args, const char *cmd, int *key_len) {
228228}
229229
230230void
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
241241void
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
265265void
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 */
379402static zend_bool
380403ra_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
391424static 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
487500static 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 ]);
0 commit comments