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
8000
;
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
/**
@@ -280,6 +293,7 @@ PHP_METHOD(RedisArray, __construct)
280
293
281
294
if (ra ) {
282
295
ra -> auto_rehash = b_autorehash ;
296
+ if (ra -> prev ) ra -> prev -> auto_rehash = b_autorehash ;
283
297
#if PHP_VERSION_ID >= 50400
284
298
id = zend_list_insert (ra , le_redis_array TSRMLS_CC );
285
299
#else
@@ -302,7 +316,6 @@ ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, i
302
316
HashTable * h_args ;
303
317
304
318
int argc ;
305
- int failed ;
306
319
zend_bool b_write_cmd = 0 ;
307
320
308
321
h_args = Z_ARRVAL_P (z_args );
@@ -366,23 +379,15 @@ ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, i
366
379
} else { /* call directly through. */
367
380
call_user_function (& redis_ce -> function_table , & redis_inst , & z_fun , return_value , argc , z_callargs TSRMLS_CC );
368
381
369
- failed = 0 ;
370
- if ((Z_TYPE_P (return_value ) == IS_BOOL && Z_BVAL_P (return_value ) == 0 ) ||
371
- (Z_TYPE_P (return_value ) == IS_ARRAY && zend_hash_num_elements (Z_ARRVAL_P (return_value )) == 0 ) ||
372
- (Z_TYPE_P (return_value ) == IS_LONG && Z_LVAL_P (return_value ) == 0 && !strcasecmp (cmd , "TYPE" )))
373
-
374
- {
375
- failed = 1 ;
376
- }
377
-
378
382
/* check if we have an error. */
379
- if (failed && ra -> prev && !b_write_cmd ) { /* there was an error reading, try with prev ring. */
380
- /* ERROR, FALLBACK TO PREVIOUS RING and forward a reference to the first redis instance we were looking at. */
383
+ if (RA_CALL_FAILED ( return_value , cmd ) && ra -> prev && !b_write_cmd ) { /* there was an error reading, try with prev ring. */
384
+ /* ERROR, FALLBACK TO PREVIOUS RING and forward a reference to the first redis instance we were looking at. */
381
385
ra_forward_call (INTERNAL_FUNCTION_PARAM_PASSTHRU , ra -> prev , cmd , cmd_len , z_args , z_new_target ?z_new_target :redis_inst );
382
386
}
383
387
384
- if (!failed && !b_write_cmd && z_new_target && ra -> auto_rehash ) { /* move key from old ring to new ring */
385
- ra_move_key (key , key_len , redis_inst , z_new_target TSRMLS_CC );
388
+ /* Autorehash if the key was found on the previous node if this is a read command and auto rehashing is on */
389
+ if (!RA_CALL_FAILED (return_value ,cmd ) && !b_write_cmd && z_new_target && ra -> auto_rehash ) { /* move key from old ring to new ring */
390
+ ra_move_key (key , key_len , redis_inst , z_new_target TSRMLS_CC );
386
391
}
387
392
}
388
393
0 commit comments