@@ -2500,83 +2500,49 @@ int redis_hincrbyfloat_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
25002500int redis_hmget_cmd (INTERNAL_FUNCTION_PARAMETERS , RedisSock * redis_sock ,
25012501 char * * cmd , int * cmd_len , short * slot , void * * ctx )
25022502{
2503- char * key ;
2504- zval * z_arr , * z_mems , * z_mem ;
2505- int i , count , valid = 0 , key_free ;
2506- size_t key_len ;
2507- HashTable * ht_arr ;
2503+ zval * field = NULL , * zctx = NULL ;
25082504 smart_string cmdstr = {0 };
2505+ HashTable * fields = NULL ;
2506+ zend_string * key = NULL ;
2507+ zend_ulong valid = 0 ;
25092508
2510- // Parse arguments
2511- if (zend_parse_parameters (ZEND_NUM_ARGS (), "sa" , & key , & key_len ,
2512- & z_arr ) == FAILURE )
2513- {
2514- return FAILURE ;
2515- }
2516-
2517- // Our HashTable
2518- ht_arr = Z_ARRVAL_P (z_arr );
2509+ ZEND_PARSE_PARAMETERS_START (2 , 2 )
2510+ Z_PARAM_STR (key )
2511+ Z_PARAM_ARRAY_HT (fields )
2512+ ZEND_PARSE_PARAMETERS_END_EX (return FAILURE ) ;
25192513
2520- // We can abort if we have no elements
2521- if ((count = zend_hash_num_elements (ht_arr )) == 0 ) {
2514+ if (zend_hash_num_elements (fields ) == 0 )
25222515 return FAILURE ;
2523- }
25242516
2525- // Allocate memory for mems+1 so we can have a sentinel
2526- z_mems = ecalloc (count + 1 , sizeof (zval ));
2517+ zctx = ecalloc (1 + zend_hash_num_elements (fields ), sizeof (* zctx ));
25272518
2528- // Iterate over our member array
2529- ZEND_HASH_FOREACH_VAL (ht_arr , z_mem ) {
2530- ZVAL_DEREF (z_mem );
2531- // We can only handle string or long values here
2532- if ((Z_TYPE_P (z_mem ) == IS_STRING && Z_STRLEN_P (z_mem ) > 0 )
2533- || Z_TYPE_P (z_mem ) == IS_LONG
2534- ) {
2535- // Copy into our member array
2536- ZVAL_ZVAL (& z_mems [valid ], z_mem , 1 , 0 );
2519+ ZEND_HASH_FOREACH_VAL (fields , field ) {
2520+ ZVAL_DEREF (field );
2521+ if (!((Z_TYPE_P (field ) == IS_STRING && Z_STRLEN_P (field ) > 0 ) || Z_TYPE_P (field ) == IS_LONG ))
2522+ continue ;
25372523
2538- // Increment the member count to actually send
2539- valid ++ ;
2540- }
2524+ ZVAL_COPY (& zctx [valid ++ ], field );
25412525 } ZEND_HASH_FOREACH_END ();
25422526
2543- // If nothing was valid, fail
25442527 if (valid == 0 ) {
2545- efree (z_mems );
2528+ efree (zctx );
25462529 return FAILURE ;
25472530 }
25482531
2549- // Sentinel so we can free this even if it's used and then we discard
2550- // the transaction manually or there is a transaction failure
2551- ZVAL_NULL (& z_mems [valid ]);
2552-
2553- // Start command construction
2554- redis_cmd_init_sstr (& cmdstr , valid + 1 , ZEND_STRL ("HMGET" ));
2555-
2556- // Prefix our key
2557- key_free = redis_key_prefix (redis_sock , & key , & key_len );
2532+ ZVAL_NULL (& zctx [valid ]);
25582533
2559- redis_cmd_append_sstr (& cmdstr , key , key_len );
2534+ REDIS_CMD_INIT_SSTR_STATIC (& cmdstr , 1 + valid , "HMGET" );
2535+ redis_cmd_append_sstr_key_zstr (& cmdstr , key , redis_sock , slot );
25602536
2561- // Iterate over members, appending as arguments
2562- for (i = 0 ; i < valid ; i ++ ) {
2563- zend_string * zstr = zval_get_string (& z_mems [i ]);
2564- redis_cmd_append_sstr (& cmdstr , ZSTR_VAL (zstr ), ZSTR_LEN (zstr ));
2565- zend_string_release (zstr );
2537+ for (zend_ulong i = 0 ; i < valid ; i ++ ) {
2538+ redis_cmd_append_sstr_zval (& cmdstr , & zctx [i ], NULL );
25662539 }
25672540
2568- // Set our slot
2569- CMD_SET_SLOT (slot ,key ,key_len );
2570-
2571- // Free our key if we prefixed it
2572- if (key_free ) efree (key );
2573-
25742541 // Push out command, length, and key context
25752542 * cmd = cmdstr .c ;
25762543 * cmd_len = cmdstr .len ;
2577- * ctx = ( void * ) z_mems ;
2544+ * ctx = zctx ;
25782545
2579- // Success!
25802546 return SUCCESS ;
25812547}
25822548
0 commit comments