32
32
#include "redis_array.h"
33
33
#include "redis_array_impl.h"
34
34
35
+ /* Simple macro to detect failure in a RedisArray call */
36
+ #define RA_CALL_FAILED (rv , cmd ) \
37
+ ((Z_TYPE_P(rv) == IS_BOOL && Z_BVAL_P(rv) == 0) || \
38
+ (Z_TYPE_P(rv) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(rv)) == 0) || \
39
+ (Z_TYPE_P(rv) == IS_LONG && Z_LVAL_P(rv) == 0 && !strcasecmp(cmd, "TYPE"))) \
40
+
35
41
extern zend_class_entry * redis_ce ;
36
42
zend_class_entry * redis_array_ce ;
37
43
@@ -76,41 +82,48 @@ zend_function_entry redis_array_functions[] = {
76
82
{NULL , NULL , NULL }
77
83
};
78
84
79
- int le_redis_array ;
80
- void redis_destructor_redis_array (zend_rsrc_list_entry * rsrc TSRMLS_DC )
81
- {
82
- int i ;
83
- RedisArray * ra = (RedisArray * )rsrc -> ptr ;
85
+ static void redis_array_free (RedisArray * ra ) {
86
+ int i ;
84
87
85
- /* delete Redis objects */
86
- for (i = 0 ; i < ra -> count ; ++ i ) {
87
- zval_dtor (ra -> redis [i ]);
88
- efree (ra -> redis [i ]);
88
+ // Redis objects
89
+ for (i = 0 ;i < ra -> count ;i ++ ) {
90
+ zval_dtor (ra -> redis [i ]);
91
+ efree (ra -> redis [i ]);
92
+ efree (ra -> hosts [i ]);
93
+ }
94
+ efree (ra -> redis );
95
+ efree (ra -> hosts );
89
96
90
- /* remove host too */
91
- efree (ra -> hosts [ i ]);
92
- }
93
- efree (ra -> redis );
94
- efree ( ra -> hosts );
97
+ /* delete hash function */
98
+ if (ra -> z_fun ) {
99
+ zval_dtor ( ra -> z_fun );
100
+ efree (ra -> z_fun );
101
+ }
95
102
96
- /* delete function */
97
- if (ra -> z_fun ) {
98
- zval_dtor (ra -> z_fun );
99
- efree (ra -> z_fun );
100
- }
103
+ /* Distributor */
104
+ if (ra -> z_dist ) {
105
+ zval_dtor (ra -> z_dist );
106
+ efree (ra -> z_dist );
107
+ }
101
108
102
- /* delete distributor */
103
- if (ra -> z_dist ) {
104
- zval_dtor (ra -> z_dist );
105
- efree (ra -> z_dist );
106
- }
109
+ /* Delete pur commands */
110
+ zval_dtor (ra -> z_pure_cmds );
111
+ efree (ra -> z_pure_cmds );
112
+
113
+ // Free structure itself
114
+ efree (ra );
115
+ }
107
116
108
- /* delete list of pure commands */
109
- zval_dtor (ra -> z_pure_cmds );
110
- efree (ra -> z_pure_cmds );
117
+ int le_redis_array ;
118
+ void redis_destructor_redis_array (zend_rsrc_list_entry * rsrc TSRMLS_DC )
119
+ {
120
+ RedisArray * ra = (RedisArray * )rsrc -> ptr ;
111
121
112
- /* free container */
113
- efree (ra );
122
+ /* Free previous ring if it's set */
123
+ if (ra -> prev ) redis_array_free (ra -> prev );
124
+
125
+ /* Free parent array */
126
+ redis_array_free (ra );
114
127
}
115
128
116
129
/**
@@ -295,6 +308,7 @@ PHP_METHOD(RedisArray, __construct)
295
308
if (ra ) {
296
309
ra -> auto_rehash = b_autorehash ;
297
310
ra -> connect_timeout = d_connect_timeout ;
311
+ if (ra -> prev ) ra -> prev -> auto_rehash = b_autorehash ;
298
312
#if PHP_VERSION_ID >= 50400
299
313
id = zend_list_insert (ra , le_redis_array TSRMLS_CC );
300
314
#else
@@ -317,7 +331,6 @@ ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, i
317
331
HashTable * h_args ;
318
332
319
333
int argc ;
320
- int failed ;
321
334
zend_bool b_write_cmd = 0 ;
322
335
323
336
h_args = Z_ARRVAL_P (z_args );
@@ -381,23 +394,15 @@ ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, i
381
394
} else { /* call directly through. */
382
395
call_user_function (& redis_ce -> function_table , & redis_inst , & z_fun , return_value , argc , z_callargs TSRMLS_CC );
383
396
384
- failed = 0 ;
385
- if ((Z_TYPE_P (return_value ) == IS_BOOL && Z_BVAL_P (return_value ) == 0 ) ||
386
- (Z_TYPE_P (return_value ) == IS_ARRAY && zend_hash_num_elements (Z_ARRVAL_P (return_value )) == 0 ) ||
387
- (Z_TYPE_P (return_value ) == IS_LONG && Z_LVAL_P (return_value ) == 0 && !strcasecmp (cmd , "TYPE" )))
388
-
389
- {
390
- failed = 1 ;
391
- }
392
-
393
397
/* check if we have an error. */
394
- if (failed && ra -> prev && !b_write_cmd ) { /* there was an error reading, try with prev ring. */
395
- /* ERROR, FALLBACK TO PREVIOUS RING and forward a reference to the first redis instance we were looking at. */
398
+ if (RA_CALL_FAILED ( return_value , cmd ) && ra -> prev && !b_write_cmd ) { /* there was an error reading, try with prev ring. */
399
+ /* ERROR, FALLBACK TO PREVIOUS RING and forward a reference to the first redis instance we were looking at. */
396
400
ra_forward_call (INTERNAL_FUNCTION_PARAM_PASSTHRU , ra -> prev , cmd , cmd_len , z_args , z_new_target ?z_new_target :redis_inst );
397
401
}
398
402
399
- if (!failed && !b_write_cmd && z_new_target && ra -> auto_rehash ) { /* move key from old ring to new ring */
400
- ra_move_key (key , key_len , redis_inst , z_new_target TSRMLS_CC );
403
+ /* Autorehash if the key was found on the previous node if this is a read command and auto rehashing is on */
404
+ if (!RA_CALL_FAILED (return_value ,cmd ) && !b_write_cmd && z_new_target && ra -> auto_rehash ) { /* move key from old ring to new ring */
405
+ ra_move_key (key , key_len , redis_inst , z_new_target TSRMLS_CC );
401
406
}
402
407
}
403
408
0 commit comments