@@ -2266,8 +2266,10 @@ static void cluster_kscan_cmd(INTERNAL_FUNCTION_PARAMETERS,
22662266 short slot ;
22672267 zval * z_it ;
22682268 HashTable * hash ;
2269- long it , num_ele ;
2269+ long num_ele ;
22702270 zend_long count = 0 ;
2271+ zend_bool complted ;
2272+ uint64_t cursor ;
22712273
22722274 // Can't be in MULTI mode
22732275 if (!CLUSTER_IS_ATOMIC (c )) {
@@ -2285,16 +2287,10 @@ static void cluster_kscan_cmd(INTERNAL_FUNCTION_PARAMETERS,
22852287 /* Treat as readonly */
22862288 c -> readonly = 1 ;
22872289
2288- // Convert iterator to long if it isn't, update our long iterator if it's
2289- // set and >0, and finish if it's back to zero
2290- if (Z_TYPE_P (z_it ) != IS_LONG || Z_LVAL_P (z_it ) < 0 ) {
2291- convert_to_long (z_it );
2292- it = 0 ;
2293- } else if (Z_LVAL_P (z_it ) != 0 ) {
2294- it = Z_LVAL_P (z_it );
2295- } else {
2290+ /* Get our scan cursor and return early if we're done */
2291+ cursor = redisGetScanCursor (z_it , & complted );
2292+ if (complted )
22962293 RETURN_FALSE ;
2297- }
22982294
22992295 // Apply any key prefix we have, get the slot
23002296 key_free = redis_key_prefix (c -> flags , & key , & key_len );
@@ -2314,7 +2310,7 @@ static void cluster_kscan_cmd(INTERNAL_FUNCTION_PARAMETERS,
23142310 }
23152311
23162312 // Create command
2317- cmd_len = redis_fmt_scan_cmd (& cmd , type , key , key_len , it , pat , pat_len ,
2313+ cmd_len = redis_fmt_scan_cmd (& cmd , type , key , key_len , cursor , pat , pat_len ,
23182314 count );
23192315
23202316 // Send it off
@@ -2328,7 +2324,7 @@ static void cluster_kscan_cmd(INTERNAL_FUNCTION_PARAMETERS,
23282324
23292325 // Read response
23302326 if (cluster_scan_resp (INTERNAL_FUNCTION_PARAM_PASSTHRU , c , type ,
2331- & it ) == FAILURE )
2327+ & cursor ) == FAILURE )
23322328 {
23332329 CLUSTER_THROW_EXCEPTION ("Couldn't read SCAN response" , 0 );
23342330 if (key_free ) efree (key );
@@ -2342,7 +2338,7 @@ static void cluster_kscan_cmd(INTERNAL_FUNCTION_PARAMETERS,
23422338
23432339 // Free our command
23442340 efree (cmd );
2345- } while (c -> flags -> scan & REDIS_SCAN_RETRY && it != 0 && num_ele == 0 );
2341+ } while (c -> flags -> scan & REDIS_SCAN_RETRY && cursor != 0 && num_ele == 0 );
23462342
23472343 // Free our pattern
23482344 if (pat_free ) efree (pat );
@@ -2351,7 +2347,7 @@ static void cluster_kscan_cmd(INTERNAL_FUNCTION_PARAMETERS,
23512347 if (key_free ) efree (key );
23522348
23532349 // Update iterator reference
2354- Z_LVAL_P (z_it ) = it ;
2350+ redisSetScanCursor (z_it , cursor ) ;
23552351}
23562352
23572353static int redis_acl_op_readonly (zend_string * op ) {
@@ -2445,9 +2441,11 @@ PHP_METHOD(RedisCluster, scan) {
24452441 size_t pat_len = 0 ;
24462442 int cmd_len ;
24472443 short slot ;
2448- zval * z_it , * z_node ;
2449- long it , num_ele , pat_free = 0 ;
2444+ zval * zcursor , * z_node ;
2445+ long num_ele , pat_free = 0 ;
24502446 zend_long count = 0 ;
2447+ zend_bool completed ;
2448+ uint64_t cursor ;
24512449
24522450 /* Treat as read-only */
24532451 c -> readonly = CLUSTER_IS_ATOMIC (c );
@@ -2459,21 +2457,16 @@ PHP_METHOD(RedisCluster, scan) {
24592457 }
24602458
24612459 /* Parse arguments */
2462- if (zend_parse_parameters (ZEND_NUM_ARGS (), "z/z|s!l" , & z_it ,
2460+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "z/z|s!l" , & zcursor ,
24632461 & z_node , & pat , & pat_len , & count ) == FAILURE )
24642462 {
24652463 RETURN_FALSE ;
24662464 }
24672465
2468- /* Convert or update iterator */
2469- if (Z_TYPE_P (z_it ) != IS_LONG || Z_LVAL_P (z_it ) < 0 ) {
2470- convert_to_long (z_it );
2471- it = 0 ;
2472- } else if (Z_LVAL_P (z_it ) != 0 ) {
2473- it = Z_LVAL_P (z_it );
2474- } else {
2466+ /* Get the scan cursor and return early if we're done */
2467+ cursor = redisGetScanCursor (zcursor , & completed );
2468+ if (completed )
24752469 RETURN_FALSE ;
2476- }
24772470
24782471 if (c -> flags -> scan & REDIS_SCAN_PREFIX ) {
24792472 pat_free = redis_key_prefix (c -> flags , & pat , & pat_len );
@@ -2489,7 +2482,7 @@ PHP_METHOD(RedisCluster, scan) {
24892482 }
24902483
24912484 /* Construct our command */
2492- cmd_len = redis_fmt_scan_cmd (& cmd , TYPE_SCAN , NULL , 0 , it , pat , pat_len ,
2485+ cmd_len = redis_fmt_scan_cmd (& cmd , TYPE_SCAN , NULL , 0 , cursor , pat , pat_len ,
24932486 count );
24942487
24952488 if ((slot = cluster_cmd_get_slot (c , z_node )) < 0 ) {
@@ -2505,7 +2498,7 @@ PHP_METHOD(RedisCluster, scan) {
25052498 }
25062499
25072500 if (cluster_scan_resp (INTERNAL_FUNCTION_PARAM_PASSTHRU , c , TYPE_SCAN ,
2508- & it ) == FAILURE || Z_TYPE_P (return_value )!= IS_ARRAY )
2501+ & cursor ) == FAILURE || Z_TYPE_P (return_value ) != IS_ARRAY )
25092502 {
25102503 CLUSTER_THROW_EXCEPTION ("Couldn't process SCAN response from node" , 0 );
25112504 efree (cmd );
@@ -2515,11 +2508,11 @@ PHP_METHOD(RedisCluster, scan) {
25152508 efree (cmd );
25162509
25172510 num_ele = zend_hash_num_elements (Z_ARRVAL_P (return_value ));
2518- } while (c -> flags -> scan & REDIS_SCAN_RETRY && it != 0 && num_ele == 0 );
2511+ } while (c -> flags -> scan & REDIS_SCAN_RETRY && cursor != 0 && num_ele == 0 );
25192512
25202513 if (pat_free ) efree (pat );
25212514
2522- Z_LVAL_P ( z_it ) = it ;
2515+ redisSetScanCursor ( zcursor , cursor ) ;
25232516}
25242517/* }}} */
25252518
0 commit comments