@@ -99,8 +99,6 @@ impl ScanKeyCursor {
9999 }
100100
101101 pub fn iter ( & self ) -> ScanKeyCursorIterator < ' _ > {
102- let ctx = Context :: new ( self . key . ctx ) ;
103- ctx. log_notice ( "Starting ScanKeyCursor iteration" ) ;
104102 ScanKeyCursorIterator {
105103 cursor : self ,
106104 buf : Vec :: new ( ) ,
@@ -117,6 +115,7 @@ impl Drop for ScanKeyCursor {
117115
118116pub type ScanKeyIteratorItem = ( RedisString , RedisString ) ;
119117
118+ /// An iterator (state) over the field/value pairs of a hash key.
120119pub struct ScanKeyCursorIterator < ' a > {
121120 /// The cursor that is used for the iteration
122121 cursor : & ' a ScanKeyCursor ,
@@ -233,34 +232,25 @@ unsafe extern "C" fn iterator_callback(
233232 value : * mut raw:: RedisModuleString ,
234233 data : * mut c_void ,
235234) {
236- // SAFETY: this is the responsibility of the caller, see only usage below in `next()`
237- // `data` is a stack slot of type Data
235+ // `data` is a stack slot
238236 let slot = data. cast :: < StackSlot > ( ) ;
239237 let slot = & mut ( * slot) ;
240238
241- // todo: use new-type with refcount handling for better performance
239+ // todo: use new-type with refcount handling for better performance, otherwise we have to copy at this point
240+ // we know that this callback will be called in a loop scope and that we
241+ // need to store the RedisString longer than the ScanKey invocation but not much
242+ // longer and in case of batched results we don't need to store everything in memory
243+ // but only the last batch.
242244 let field = raw:: RedisModule_CreateStringFromString . unwrap ( ) ( slot. ctx . get_raw ( ) , field) ;
243245 let value = raw:: RedisModule_CreateStringFromString . unwrap ( ) ( slot. ctx . get_raw ( ) , value) ;
244246
245247 let field = RedisString :: from_redis_module_string ( slot. ctx . get_raw ( ) , field) ;
246248 let value = RedisString :: from_redis_module_string ( slot. ctx . get_raw ( ) , value) ;
247249
248- if slot. buf . is_empty ( ) {
249- let out = format ! ( "CB - Value tu return - Field: {}, Value: {}" , field, value) ;
250- slot. ctx . log_notice ( & out) ;
251- } else {
252- // This is the case where the callback is called multiple times.
253- // We need to buffer the data in the iterator state.
254- let out = format ! (
255- "CB - Buffer for future use - Field: {}, Value: {}" ,
256- field, value
257- ) ;
258- slot. ctx . log_notice ( & out) ;
259- }
260250 slot. buf . push ( ( field, value) ) ;
261251}
262252
263- // Implements an iterator for `KeysCursor` that yields (RedisKey, *mut RedisModuleString, *mut RedisModuleString ) in a Rust for loop.
253+ // Implements an iterator for `KeysCursor` that yields (RedisString, RedisString ) in a Rust for loop.
264254// This is a wrapper around the RedisModule_ScanKey function from the C API and uses a pattern to get the values from the callback that
265255// is also used in stack unwinding scenarios. There is not common term for that but here we can think of it as a "stack slot" pattern.
266256impl Iterator for ScanKeyCursorIterator < ' _ > {
0 commit comments