@@ -31,6 +31,9 @@ class RedisJournal extends Nette\Object implements Nette\Caching\Storages\IJourn
3131 TAGS = 'tags ' ,
3232 KEYS = 'keys ' ;
3333
34+ /** @internal batch delete size */
35+ const BATCH_SIZE = 8000 ;
36+
3437 /**
3538 * @var RedisClient
3639 */
@@ -108,34 +111,86 @@ private function cleanEntry($keys)
108111 * Cleans entries from journal.
109112 *
110113 * @param array $conds
114+ * @param \Nette\Caching\IStorage $storage
111115 *
112116 * @return array of removed items or NULL when performing a full cleanup
113117 */
114- public function clean (array $ conds )
118+ public function clean (array $ conds, Nette \ Caching \ IStorage $ storage = NULL )
115119 {
116120 if (!empty ($ conds [Cache::ALL ])) {
117121 $ all = $ this ->client ->keys (self ::NS_NETTE . ':* ' );
122+ if ($ storage instanceof RedisStorage) {
123+ $ all = array_merge ($ all , $ this ->client ->keys (RedisStorage::NS_NETTE . ':* ' ));
124+ }
118125
119- $ this ->client ->multi ();
120126 call_user_func_array (array ($ this ->client , 'del ' ), $ all );
121- $ this ->client ->exec ();
122127 return NULL ;
123128 }
124129
125130 $ entries = array ();
126131 if (!empty ($ conds [Cache::TAGS ])) {
132+ $ removingTagKeys = array ();
127133 foreach ((array )$ conds [Cache::TAGS ] as $ tag ) {
128- $ this ->cleanEntry ($ found = $ this ->tagEntries ($ tag ));
134+ $ found = $ this ->tagEntries ($ tag );
135+ $ removingTagKeys [] = $ this ->formatKey ($ tag , self ::KEYS );
129136 $ entries = array_merge ($ entries , $ found );
130137 }
138+ if ($ removingTagKeys ) {
139+ call_user_func_array (array ($ this ->client , 'del ' ), $ removingTagKeys );
140+ }
131141 }
132142
133143 if (isset ($ conds [Cache::PRIORITY ])) {
134- $ this ->cleanEntry ($ found = $ this ->priorityEntries ($ conds [Cache::PRIORITY ]));
144+ $ found = $ this ->priorityEntries ($ conds [Cache::PRIORITY ]);
145+ call_user_func_array (array ($ this ->client , 'zRemRangeByScore ' ), array ($ this ->formatKey (self ::PRIORITY ), 0 , (int )$ conds [Cache::PRIORITY ]));
135146 $ entries = array_merge ($ entries , $ found );
136147 }
137148
138- return array_unique ($ entries );
149+ $ entries = array_unique ($ entries );
150+
151+ $ removingKeys = array ();
152+ $ removingKeyTags = array ();
153+ $ removingKeyPriorities = array ();
154+ foreach ($ entries as $ key ) {
155+ if ($ storage instanceof RedisStorage) {
156+ $ removingKeys [] = $ key ;
157+ }
158+ $ removingKeyTags [] = $ this ->formatKey ($ key , self ::TAGS );
159+ $ removingKeyPriorities [] = $ this ->formatKey ($ key , self ::PRIORITY );
160+ if (count ($ removingKeyTags ) >= self ::BATCH_SIZE ) {
161+ $ this ->cleanBatchData ($ removingKeys , $ removingKeyPriorities , $ removingKeyTags , $ entries );
162+ $ removingKeys = array ();
163+ $ removingKeyTags = array ();
164+ $ removingKeyPriorities = array ();
165+ }
166+ }
167+
168+ $ this ->cleanBatchData ($ removingKeys , $ removingKeyPriorities , $ removingKeyTags , $ entries );
169+
170+ return $ storage instanceof RedisStorage ? array () : $ entries ;
171+ }
172+
173+
174+
175+ private function cleanBatchData (array $ removingKeys , array $ removingKeyPriorities , array $ removingKeyTags , array $ keys )
176+ {
177+ if ($ removingKeyTags ) {
178+ if ($ keys ) {
179+ $ affectedTags = call_user_func_array (array ($ this ->client , 'sunion ' ), array ($ removingKeyTags ));
180+ foreach ($ affectedTags as $ tag ) {
181+ if ($ tag ) {
182+ call_user_func_array (array ($ this ->client , 'sRem ' ), array_merge (array ($ this ->formatKey ($ tag , self ::KEYS )), $ keys ));
183+ }
184+ }
185+ }
186+ call_user_func_array (array ($ this ->client , 'del ' ), $ removingKeyTags );
187+ }
188+ if ($ removingKeyPriorities ) {
189+ call_user_func_array (array ($ this ->client , 'del ' ), $ removingKeyPriorities );
190+ }
191+ if ($ removingKeys ) {
192+ call_user_func_array (array ($ this ->client , 'del ' ), $ removingKeys );
193+ }
139194 }
140195
141196
0 commit comments