@@ -55,6 +55,7 @@ void activeExpire(RedisModuleCtx *ctx, int dbid, uint64_t keys_per_loop) {
5555
5656 RedisModuleString * key , * field ;
5757 RedisModuleKey * real_key ;
58+ int may_delkey = 0 ;
5859
5960 long long when , now ;
6061 unsigned long zsl_len ;
@@ -79,8 +80,7 @@ void activeExpire(RedisModuleCtx *ctx, int dbid, uint64_t keys_per_loop) {
7980 Module_Assert (RedisModule_CallReplyType (keys_reply ) == REDISMODULE_REPLY_ARRAY );
8081 size_t keynum = RedisModule_CallReplyLength (keys_reply );
8182
82- int j ;
83- for (j = 0 ; j < keynum ; j ++ ) {
83+ for (int j = 0 ; j < keynum ; j ++ ) {
8484 RedisModuleCallReply * key_reply = RedisModule_CallReplyArrayElement (keys_reply , j );
8585 Module_Assert (RedisModule_CallReplyType (key_reply ) == REDISMODULE_REPLY_STRING );
8686 key = RedisModule_CreateStringFromCallReply (key_reply );
@@ -89,8 +89,10 @@ void activeExpire(RedisModuleCtx *ctx, int dbid, uint64_t keys_per_loop) {
8989 return REDISMODULE_KEYTYPE_EMPTY here, so we must deal with it until after this
9090 bugfix: https://github.com/redis/redis/commit/1833d008b3af8628835b5f082c5b4b1359557893 */
9191 if (RedisModule_KeyType (real_key ) == REDISMODULE_KEYTYPE_EMPTY ) {
92+ RedisModule_CloseKey (real_key );
9293 continue ;
9394 }
95+
9496 if (RedisModule_ModuleTypeGetType (real_key ) == TairHashType ) {
9597 tair_hash_obj = RedisModule_ModuleTypeGetValue (real_key );
9698 if (tair_hash_obj -> expire_index -> length > 0 ) {
@@ -117,17 +119,28 @@ void activeExpire(RedisModuleCtx *ctx, int dbid, uint64_t keys_per_loop) {
117119 m_listNode * node ;
118120 while ((node = listFirst (keys )) != NULL ) {
119121 key = listNodeValue (node );
122+ may_delkey = 0 ;
120123 real_key = RedisModule_OpenKey (ctx , key , REDISMODULE_READ | REDISMODULE_WRITE | REDISMODULE_OPEN_KEY_NOTOUCH );
121124 int type = RedisModule_KeyType (real_key );
122125 if (type != REDISMODULE_KEYTYPE_EMPTY ) {
123126 Module_Assert (RedisModule_ModuleTypeGetType (real_key ) == TairHashType );
124127 } else {
125128 /* Note: redis scan may return dup key. */
126129 m_listDelNode (keys , node );
130+ RedisModule_CloseKey (real_key );
127131 continue ;
128132 }
129133
134+ mstime_t key_ttl = RedisModule_GetExpire (real_key );
135+ if (key_ttl != REDISMODULE_NO_EXPIRE && key_ttl < 1000 ) { //
136+ may_delkey = 1 ;
137+ }
138+
130139 tair_hash_obj = RedisModule_ModuleTypeGetValue (real_key );
140+ if (dictSize (tair_hash_obj -> hash ) == 1 ) {
141+ may_delkey = 1 ;
142+ }
143+ RedisModule_CloseKey (real_key );
131144
132145 zsl_len = tair_hash_obj -> expire_index -> length ;
133146 Module_Assert (zsl_len > 0 );
@@ -140,15 +153,30 @@ void activeExpire(RedisModuleCtx *ctx, int dbid, uint64_t keys_per_loop) {
140153 g_expire_algorithm .stat_active_expired_field [dbid ]++ ;
141154 start_index ++ ;
142155 expire_keys_per_loop -- ;
156+ if (may_delkey ) {
157+ break ;
158+ }
143159 } else {
144160 break ;
145161 }
146162 ln2 = ln2 -> level [0 ].forward ;
147163 }
148164
165+ // If the key happens to expire, it will be released in fieldExpireIfNeeded.
166+ if (may_delkey ) {
167+ real_key = RedisModule_OpenKey (ctx , key , REDISMODULE_READ | REDISMODULE_OPEN_KEY_NOTOUCH );
168+ int type = RedisModule_KeyType (real_key );
169+ if (type == REDISMODULE_KEYTYPE_EMPTY ) {
170+ m_listDelNode (keys , node );
171+ RedisModule_CloseKey (real_key );
172+ continue ;
173+ }
174+ RedisModule_CloseKey (real_key );
175+ }
176+
149177 if (start_index ) {
150178 m_zslDeleteRangeByRank (tair_hash_obj -> expire_index , 1 , start_index );
151- delEmptyTairHashIfNeeded (ctx , real_key , key , tair_hash_obj );
179+ delEmptyTairHashIfNeeded (ctx , NULL , key , tair_hash_obj );
152180 }
153181 m_listDelNode (keys , node );
154182 }
@@ -164,6 +192,7 @@ void passiveExpire(RedisModuleCtx *ctx, int dbid, RedisModuleString *key) {
164192 RedisModuleString * field ;
165193 RedisModuleKey * real_key ;
166194 unsigned long zsl_len ;
195+ int may_delkey = 0 ;
167196 /* 1. The current db does not have a key that needs to expire. */
168197 list * keys = m_listCreate ();
169198
@@ -186,6 +215,7 @@ void passiveExpire(RedisModuleCtx *ctx, int dbid, RedisModuleString *key) {
186215 m_listNode * node ;
187216 while ((node = listFirst (keys )) != NULL ) {
188217 key = listNodeValue (node );
218+ may_delkey = 0 ;
189219 real_key = RedisModule_OpenKey (ctx , key , REDISMODULE_READ | REDISMODULE_WRITE );
190220 int type = RedisModule_KeyType (real_key );
191221
@@ -195,6 +225,17 @@ void passiveExpire(RedisModuleCtx *ctx, int dbid, RedisModuleString *key) {
195225 zsl_len = tair_hash_obj -> expire_index -> length ;
196226 Module_Assert (zsl_len > 0 );
197227
228+ mstime_t key_ttl = RedisModule_GetExpire (real_key );
229+ if (key_ttl != REDISMODULE_NO_EXPIRE && key_ttl < 100 ) { // 100ms
230+ may_delkey = 1 ;
231+ }
232+
233+ tair_hash_obj = RedisModule_ModuleTypeGetValue (real_key );
234+ if (dictSize (tair_hash_obj -> hash ) == 1 ) {
235+ may_delkey = 1 ;
236+ }
237+ RedisModule_CloseKey (real_key );
238+
198239 start_index = 0 ;
199240 ln = tair_hash_obj -> expire_index -> header -> level [0 ].forward ;
200241 while (ln && keys_per_loop ) {
@@ -203,17 +244,29 @@ void passiveExpire(RedisModuleCtx *ctx, int dbid, RedisModuleString *key) {
203244 g_expire_algorithm .stat_passive_expired_field [dbid ]++ ;
204245 start_index ++ ;
205246 keys_per_loop -- ;
247+ if (may_delkey ) {
248+ break ;
249+ }
206250 } else {
207251 break ;
208252 }
209253 ln = ln -> level [0 ].forward ;
210254 }
211255
256+ if (may_delkey ) {
257+ real_key = RedisModule_OpenKey (ctx , key , REDISMODULE_READ | REDISMODULE_OPEN_KEY_NOTOUCH );
258+ int type = RedisModule_KeyType (real_key );
259+ if (type == REDISMODULE_KEYTYPE_EMPTY ) {
260+ m_listDelNode (keys , node );
261+ RedisModule_CloseKey (real_key );
262+ continue ;
263+ }
264+ RedisModule_CloseKey (real_key );
265+ }
266+
212267 if (start_index ) {
213268 m_zslDeleteRangeByRank (tair_hash_obj -> expire_index , 1 , start_index );
214- if (!delEmptyTairHashIfNeeded (ctx , real_key , key , tair_hash_obj )) {
215- RedisModule_CloseKey (real_key );
216- }
269+ delEmptyTairHashIfNeeded (ctx , NULL , key , tair_hash_obj );
217270 }
218271 m_listDelNode (keys , node );
219272 }
0 commit comments