@@ -495,7 +495,7 @@ PHP_METHOD(RedisArray, _instance)
495
495
496
496
PHP_METHOD (RedisArray , _function )
497
497
{
498
- zval * object , * z_fun ;
498
+ zval * object ;
499
499
RedisArray * ra ;
500
500
501
501
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "O" ,
@@ -507,13 +507,12 @@ PHP_METHOD(RedisArray, _function)
507
507
RETURN_FALSE ;
508
508
}
509
509
510
- z_fun = & ra -> z_fun ;
511
- RETURN_ZVAL (z_fun , 1 , 0 );
510
+ RETURN_ZVAL (& ra -> z_fun , 1 , 0 );
512
511
}
513
512
514
513
PHP_METHOD (RedisArray , _distributor )
515
514
{
516
- zval * object , * z_dist ;
515
+ zval * object ;
517
516
RedisArray * ra ;
518
517
519
518
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "O" ,
@@ -525,8 +524,7 @@ PHP_METHOD(RedisArray, _distributor)
525
524
RETURN_FALSE ;
526
525
}
527
526
528
- z_dist = & ra -> z_dist ;
529
- RETURN_ZVAL (z_dist , 1 , 0 );
527
+ RETURN_ZVAL (& ra -> z_dist , 1 , 0 );
530
528
}
531
529
532
530
PHP_METHOD (RedisArray , _rehash )
@@ -815,12 +813,10 @@ PHP_METHOD(RedisArray, select)
815
813
/* MGET will distribute the call to several nodes and regroup the values. */
816
814
PHP_METHOD (RedisArray , mget )
817
815
{
818
- zval * object , * z_keys , z_argarray , * data , z_ret , * z_cur , z_tmp_array ;
819
- int i , j , n ;
820
- RedisArray * ra ;
821
- int * pos , argc , * argc_each ;
816
+ zval * object , * z_keys , * data , z_ret , * z_cur , z_tmp_array , z_fun , z_arg , * * argv ;
817
+ int i , j , n , * pos , argc , * argc_each ;
822
818
HashTable * h_keys ;
823
- zval * * argv ;
819
+ RedisArray * ra ;
824
820
825
821
if ((ra = redis_array_get (getThis ())) == NULL ) {
826
822
RETURN_FALSE ;
@@ -840,11 +836,10 @@ PHP_METHOD(RedisArray, mget)
840
836
if ((argc = zend_hash_num_elements (h_keys )) == 0 ) {
841
837
RETURN_FALSE ;
842
838
}
843
- argv = emalloc (argc * sizeof (zval * ));
844
- pos = emalloc (argc * sizeof (int ));
839
+ argv = ecalloc (argc , sizeof (* argv ));
840
+ pos = ecalloc (argc , sizeof (* pos ));
845
841
846
- argc_each = emalloc (ra -> count * sizeof (int ));
847
- memset (argc_each , 0 , ra -> count * sizeof (int ));
842
+ argc_each = ecalloc (ra -> count , sizeof (* argc_each ));
848
843
849
844
/* associate each key to a redis node */
850
845
i = 0 ;
@@ -856,95 +851,86 @@ PHP_METHOD(RedisArray, mget)
856
851
/* Handle the possibility that we're a reference */
857
852
ZVAL_DEREF (data );
858
853
859
- /* phpredis proper can only use string or long keys, so restrict to that here */
860
- if (Z_TYPE_P (data ) != IS_STRING && Z_TYPE_P (data ) != IS_LONG ) {
861
- php_error_docref (NULL , E_ERROR , "MGET: all keys must be strings or longs" );
862
- efree (argv );
863
- efree (pos );
864
- efree (argc_each );
865
- RETURN_FALSE ;
866
- }
867
-
868
854
/* Convert to a string for hash lookup if it isn't one */
869
855
if (Z_TYPE_P (data ) == IS_STRING ) {
870
856
key_len = Z_STRLEN_P (data );
871
857
key_lookup = Z_STRVAL_P (data );
872
- } else {
858
+ } else if ( Z_TYPE_P ( data ) == IS_LONG ) {
873
859
key_len = snprintf (kbuf , sizeof (kbuf ), ZEND_LONG_FMT , Z_LVAL_P (data ));
874
860
key_lookup = (char * )kbuf ;
861
+ } else {
862
+ /* phpredis proper can only use string or long keys, so restrict to that here */
863
+ php_error_docref (NULL , E_ERROR , "MGET: all keys must be strings or longs" );
864
+ RETVAL_FALSE ;
865
+ goto cleanup ;
875
866
}
876
867
877
868
/* Find our node */
878
869
if (ra_find_node (ra , key_lookup , key_len , & pos [i ]) == NULL ) {
879
- /* TODO: handle */
870
+ RETVAL_FALSE ;
871
+ goto cleanup ;
880
872
}
881
873
882
874
argc_each [pos [i ]]++ ; /* count number of keys per node */
883
875
argv [i ++ ] = data ;
884
876
} ZEND_HASH_FOREACH_END ();
885
877
878
+ /* prepare call */
886
879
array_init (& z_tmp_array );
880
+ ZVAL_STRINGL (& z_fun , "MGET" , sizeof ("MGET" ) - 1 );
881
+
887
882
/* calls */
888
883
for (n = 0 ; n < ra -> count ; ++ n ) { /* for each node */
889
884
/* We don't even need to make a call to this node if no keys go there */
890
885
if (!argc_each [n ]) continue ;
891
886
892
887
/* copy args for MGET call on node. */
893
- array_init (& z_argarray );
888
+ array_init (& z_arg );
894
889
895
890
for (i = 0 ; i < argc ; ++ i ) {
896
- if (pos [i ] != n ) continue ;
897
-
898
- zval z_ret ;
899
- ZVAL_ZVAL (& z_ret , argv [i ], 1 , 0 );
900
- add_next_index_zval (& z_argarray , & z_ret );
891
+ if (pos [i ] == n ) {
892
+ add_next_index_zval (& z_arg , argv [i ]);
893
+ }
901
894
}
902
895
903
- zval z_fun ;
904
- /* prepare call */
905
- ZVAL_STRINGL (& z_fun , "MGET" , 4 );
906
896
/* call MGET on the node */
907
- call_user_function (& redis_ce -> function_table , & ra -> redis [n ], & z_fun , & z_ret , 1 , & z_argarray );
908
- zval_dtor (& z_fun );
897
+ call_user_function (& redis_ce -> function_table , & ra -> redis [n ], & z_fun , & z_ret , 1 , & z_arg );
909
898
910
899
/* cleanup args array */
911
- zval_dtor (& z_argarray );
900
+ zval_dtor (& z_arg );
912
901
913
902
/* Error out if we didn't get a proper response */
914
903
if (Z_TYPE (z_ret ) != IS_ARRAY ) {
915
904
/* cleanup */
916
905
zval_dtor (& z_ret );
917
906
zval_dtor (& z_tmp_array );
918
- efree (argv );
919
- efree (pos );
920
- efree (argc_each );
921
-
922
- /* failure */
923
- RETURN_FALSE ;
907
+ RETVAL_FALSE ;
908
+ goto cleanup ;
924
909
}
925
910
926
911
for (i = 0 , j = 0 ; i < argc ; ++ i ) {
927
912
if (pos [i ] != n || (z_cur = zend_hash_index_find (Z_ARRVAL (z_ret ), j ++ )) == NULL ) continue ;
928
913
929
- zval z_ret ;
930
- ZVAL_ZVAL (& z_ret , z_cur , 1 , 0 );
931
- add_index_zval (& z_tmp_array , i , & z_ret );
914
+ ZVAL_ZVAL (& z_arg , z_cur , 1 , 0 );
915
+ add_index_zval (& z_tmp_array , i , & z_arg );
932
916
}
933
917
zval_dtor (& z_ret );
934
918
}
935
919
920
+ zval_dtor (& z_fun );
921
+
936
922
array_init (return_value );
937
923
/* copy temp array in the right order to return_value */
938
924
for (i = 0 ; i < argc ; ++ i ) {
939
925
if ((z_cur = zend_hash_index_find (Z_ARRVAL (z_tmp_array ), i )) == NULL ) continue ;
940
926
941
- zval z_ret ;
942
- ZVAL_ZVAL (& z_ret , z_cur , 1 , 0 );
943
- add_next_index_zval (return_value , & z_ret );
927
+ ZVAL_ZVAL (& z_arg , z_cur , 1 , 0 );
928
+ add_next_index_zval (return_value , & z_arg );
944
929
}
945
930
946
931
/* cleanup */
947
932
zval_dtor (& z_tmp_array );
933
+ cleanup :
948
934
efree (argv );
949
935
efree (pos );
950
936
efree (argc_each );
@@ -954,13 +940,11 @@ PHP_METHOD(RedisArray, mget)
954
940
/* MSET will distribute the call to several nodes and regroup the values. */
955
941
PHP_METHOD (RedisArray , mset )
956
942
{
957
- zval * object , * z_keys , z_argarray , * data , z_ret , * * argv ;
958
- int i = 0 , n ;
943
+ zval * object , * z_keys , z_argarray , * data , z_fun , z_ret , * * argv ;
944
+ int i = 0 , n , * pos , argc , * argc_each , key_len ;
959
945
RedisArray * ra ;
960
- int * pos , argc , * argc_each ;
961
946
HashTable * h_keys ;
962
947
char * key , kbuf [40 ];
963
- int key_len ;
964
948
zend_string * * keys , * zkey ;
965
949
zend_ulong idx ;
966
950
@@ -982,12 +966,11 @@ PHP_METHOD(RedisArray, mset)
982
966
if ((argc = zend_hash_num_elements (h_keys )) == 0 ) {
983
967
RETURN_FALSE ;
984
968
}
985
- argv = emalloc (argc * sizeof (zval * ));
986
- pos = emalloc (argc * sizeof (int ));
987
- keys = ecalloc (argc , sizeof (zend_string * ));
969
+ argv = ecalloc (argc , sizeof (* argv ));
970
+ pos = ecalloc (argc , sizeof (* pos ));
971
+ keys = ecalloc (argc , sizeof (* keys ));
988
972
989
- argc_each = emalloc (ra -> count * sizeof (int ));
990
- memset (argc_each , 0 , ra -> count * sizeof (int ));
973
+ argc_each = ecalloc (ra -> count , sizeof (* argc_each ));
991
974
992
975
/* associate each key to a redis node */
993
976
ZEND_HASH_FOREACH_KEY_VAL (h_keys , idx , zkey , data ) {
@@ -1001,16 +984,26 @@ PHP_METHOD(RedisArray, mset)
1001
984
}
1002
985
1003
986
if (ra_find_node (ra , key , (int )key_len , & pos [i ]) == NULL ) {
1004
- // TODO: handle
987
+ for (n = 0 ; n < i ; ++ n ) {
988
+ zend_string_release (keys [n ]);
989
+ }
990
+ efree (keys );
991
+ efree (argv );
992
+ efree (pos );
993
+ efree (argc_each );
994
+ RETURN_FALSE ;
1005
995
}
1006
996
1007
997
argc_each [pos [i ]]++ ; /* count number of keys per node */
1008
- keys [i ] = zend_string_init (key , key_len , 0 );
998
+ keys [i ] = zkey ? zend_string_copy ( zkey ) : zend_string_init (key , key_len , 0 );
1009
999
argv [i ] = data ;
1010
1000
i ++ ;
1011
1001
} ZEND_HASH_FOREACH_END ();
1012
1002
1013
1003
1004
+ /* prepare call */
1005
+ ZVAL_STRINGL (& z_fun , "MSET" , sizeof ("MSET" ) - 1 );
1006
+
1014
1007
/* calls */
1015
1008
for (n = 0 ; n < ra -> count ; ++ n ) { /* for each node */
1016
1009
/* We don't even need to make a call to this node if no keys go there */
@@ -1023,7 +1016,6 @@ PHP_METHOD(RedisArray, mset)
1023
1016
for (i = 0 ; i < argc ; ++ i ) {
1024
1017
if (pos [i ] != n ) continue ;
1025
1018
1026
- zval z_ret ;
1027
1019
if (argv [i ] == NULL ) {
1028
1020
ZVAL_NULL (& z_ret );
1029
1021
} else {
@@ -1040,26 +1032,19 @@ PHP_METHOD(RedisArray, mset)
1040
1032
1041
1033
if (ra -> index ) { /* add MULTI */
1042
1034
ra_index_multi (& ra -> redis [n ], MULTI );
1043
- }
1044
-
1045
- zval z_fun ;
1046
-
1047
- /* prepare call */
1048
- ZVAL_STRINGL (& z_fun , "MSET" , 4 );
1049
-
1050
- /* call */
1051
- call_user_function (& redis_ce -> function_table , & ra -> redis [n ], & z_fun , & z_ret , 1 , & z_argarray );
1052
- zval_dtor (& z_fun );
1053
- zval_dtor (& z_ret );
1054
-
1055
- if (ra -> index ) {
1035
+ call_user_function (& redis_ce -> function_table , & ra -> redis [n ], & z_fun , & z_ret , 1 , & z_argarray );
1056
1036
ra_index_keys (& z_argarray , & ra -> redis [n ]); /* use SADD to add keys to node index */
1057
1037
ra_index_exec (& ra -> redis [n ], NULL , 0 ); /* run EXEC */
1038
+ } else {
1039
+ call_user_function (& redis_ce -> function_table , & ra -> redis [n ], & z_fun , & z_ret , 1 , & z_argarray );
1058
1040
}
1059
1041
1060
1042
zval_dtor (& z_argarray );
1043
+ zval_dtor (& z_ret );
1061
1044
}
1062
1045
1046
+ zval_dtor (& z_fun );
1047
+
1063
1048
/* Free any keys that we needed to allocate memory for, because they weren't strings */
1064
1049
for (i = 0 ; i < argc ; i ++ ) {
1065
1050
zend_string_release (keys [i ]);
0 commit comments