@@ -41,7 +41,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
41
41
private static $ createCacheItem ;
42
42
private static $ setCacheItemTags ;
43
43
private static $ getTagsByKey ;
44
- private static $ invalidateTags ;
44
+ private static $ saveTags ;
45
45
46
46
public function __construct (AdapterInterface $ itemsPool , AdapterInterface $ tagsPool = null , float $ knownTagVersionsTtl = 0.15 )
47
47
{
@@ -95,8 +95,10 @@ static function ($deferred) {
95
95
null ,
96
96
CacheItem::class
97
97
);
98
- self ::$ invalidateTags ?? self ::$ invalidateTags = \Closure::bind (
98
+ self ::$ saveTags ?? self ::$ saveTags = \Closure::bind (
99
99
static function (AdapterInterface $ tagsAdapter , array $ tags ) {
100
+ ksort ($ tags );
101
+
100
102
foreach ($ tags as $ v ) {
101
103
$ v ->expiry = 0 ;
102
104
$ tagsAdapter ->saveDeferred ($ v );
@@ -114,40 +116,14 @@ static function (AdapterInterface $tagsAdapter, array $tags) {
114
116
*/
115
117
public function invalidateTags (array $ tags )
116
118
{
117
- $ ok = true ;
118
- $ tagsByKey = [];
119
- $ invalidatedTags = [];
119
+ $ ids = [];
120
120
foreach ($ tags as $ tag ) {
121
121
\assert ('' !== CacheItem::validateKey ($ tag ));
122
- $ invalidatedTags [$ tag ] = 0 ;
123
- }
124
-
125
- if ($ this ->deferred ) {
126
- $ items = $ this ->deferred ;
127
- foreach ($ items as $ key => $ item ) {
128
- if (!$ this ->pool ->saveDeferred ($ item )) {
129
- unset($ this ->deferred [$ key ]);
130
- $ ok = false ;
131
- }
132
- }
133
-
134
- $ tagsByKey = (self ::$ getTagsByKey )($ items );
135
- $ this ->deferred = [];
136
- }
137
-
138
- $ tagVersions = $ this ->getTagVersions ($ tagsByKey , $ invalidatedTags );
139
- $ f = self ::$ createCacheItem ;
140
-
141
- foreach ($ tagsByKey as $ key => $ tags ) {
142
- $ this ->pool ->saveDeferred ($ f (static ::TAGS_PREFIX .$ key , array_intersect_key ($ tagVersions , $ tags ), $ items [$ key ]));
143
- }
144
- $ ok = $ this ->pool ->commit () && $ ok ;
145
-
146
- if ($ invalidatedTags ) {
147
- $ ok = (self ::$ invalidateTags )($ this ->tags , $ invalidatedTags ) && $ ok ;
122
+ unset($ this ->knownTagVersions [$ tag ]);
123
+ $ ids [] = $ tag .static ::TAGS_PREFIX ;
148
124
}
149
125
150
- return $ ok ;
126
+ return ! $ tags || $ this -> tags -> deleteItems ( $ ids ) ;
151
127
}
152
128
153
129
/**
@@ -176,7 +152,7 @@ public function hasItem($key)
176
152
}
177
153
178
154
foreach ($ this ->getTagVersions ([$ itemTags ]) as $ tag => $ version ) {
179
- if ($ itemTags [$ tag ] !== $ version && 1 !== $ itemTags [ $ tag ] - $ version ) {
155
+ if ($ itemTags [$ tag ] !== $ version ) {
180
156
return false ;
181
157
}
182
158
}
@@ -314,7 +290,30 @@ public function saveDeferred(CacheItemInterface $item)
314
290
*/
315
291
public function commit ()
316
292
{
317
- return $ this ->invalidateTags ([]);
293
+ if (!$ this ->deferred ) {
294
+ return true ;
295
+ }
296
+
297
+ $ ok = true ;
298
+ foreach ($ this ->deferred as $ key => $ item ) {
299
+ if (!$ this ->pool ->saveDeferred ($ item )) {
300
+ unset($ this ->deferred [$ key ]);
301
+ $ ok = false ;
302
+ }
303
+ }
304
+
305
+ $ items = $ this ->deferred ;
306
+ $ tagsByKey = (self ::$ getTagsByKey )($ items );
307
+ $ this ->deferred = [];
308
+
309
+ $ tagVersions = $ this ->getTagVersions ($ tagsByKey );
310
+ $ f = self ::$ createCacheItem ;
311
+
312
+ foreach ($ tagsByKey as $ key => $ tags ) {
313
+ $ this ->pool ->saveDeferred ($ f (static ::TAGS_PREFIX .$ key , array_intersect_key ($ tagVersions , $ tags ), $ items [$ key ]));
314
+ }
315
+
316
+ return $ this ->pool ->commit () && $ ok ;
318
317
}
319
318
320
319
/**
@@ -361,7 +360,7 @@ private function generateItems(iterable $items, array $tagKeys): \Generator
361
360
362
361
foreach ($ itemTags as $ key => $ tags ) {
363
362
foreach ($ tags as $ tag => $ version ) {
364
- if ($ tagVersions [$ tag ] !== $ version && 1 !== $ version - $ tagVersions [ $ tag ] ) {
363
+ if ($ tagVersions [$ tag ] !== $ version ) {
365
364
unset($ itemTags [$ key ]);
366
365
continue 2 ;
367
366
}
@@ -377,57 +376,53 @@ private function generateItems(iterable $items, array $tagKeys): \Generator
377
376
}
378
377
}
379
378
380
- private function getTagVersions (array $ tagsByKey, array & $ invalidatedTags = [] )
379
+ private function getTagVersions (array $ tagsByKey )
381
380
{
382
- $ tagVersions = $ invalidatedTags ;
381
+ $ tagVersions = [];
382
+ $ fetchTagVersions = false ;
383
383
384
384
foreach ($ tagsByKey as $ tags ) {
385
385
$ tagVersions += $ tags ;
386
+
387
+ foreach ($ tags as $ tag => $ version ) {
388
+ if ($ tagVersions [$ tag ] !== $ version ) {
389
+ unset($ this ->knownTagVersions [$ tag ]);
390
+ }
391
+ }
386
392
}
387
393
388
394
if (!$ tagVersions ) {
389
395
return [];
390
396
}
391
397
392
- if (!$ fetchTagVersions = 1 !== \func_num_args ()) {
393
- foreach ($ tagsByKey as $ tags ) {
394
- foreach ($ tags as $ tag => $ version ) {
395
- if ($ tagVersions [$ tag ] > $ version ) {
396
- $ tagVersions [$ tag ] = $ version ;
397
- }
398
- }
399
- }
400
- }
401
-
402
398
$ now = microtime (true );
403
399
$ tags = [];
404
400
foreach ($ tagVersions as $ tag => $ version ) {
405
401
$ tags [$ tag .static ::TAGS_PREFIX ] = $ tag ;
406
- if ($ fetchTagVersions || !isset ($ this ->knownTagVersions [$ tag ])) {
402
+ if ($ fetchTagVersions || ($ this ->knownTagVersions [$ tag ][1 ] ?? null ) !== $ version || $ now - $ this ->knownTagVersions [$ tag ][0 ] >= $ this ->knownTagVersionsTtl ) {
403
+ // reuse previously fetched tag versions up to the ttl
407
404
$ fetchTagVersions = true ;
408
- continue ;
409
- }
410
- $ version -= $ this ->knownTagVersions [$ tag ][1 ];
411
- if ((0 !== $ version && 1 !== $ version ) || $ now - $ this ->knownTagVersions [$ tag ][0 ] >= $ this ->knownTagVersionsTtl ) {
412
- // reuse previously fetched tag versions up to the ttl, unless we are storing items or a potential miss arises
413
- $ fetchTagVersions = true ;
414
- } else {
415
- $ this ->knownTagVersions [$ tag ][1 ] += $ version ;
416
405
}
417
406
}
418
407
419
408
if (!$ fetchTagVersions ) {
420
409
return $ tagVersions ;
421
410
}
422
411
412
+ $ newTags = [];
413
+ $ newVersion = null ;
423
414
foreach ($ this ->tags ->getItems (array_keys ($ tags )) as $ tag => $ version ) {
424
- $ tagVersions [$ tag = $ tags [$ tag ]] = $ version ->get () ?: 0 ;
425
- if (isset ($ invalidatedTags [$ tag ])) {
426
- $ invalidatedTags [$ tag ] = $ version ->set (++$ tagVersions [$ tag ]);
415
+ if (!$ version ->isHit ()) {
416
+ $ newTags [$ tag ] = $ version ->set ($ newVersion ?? $ newVersion = random_int (\PHP_INT_MIN , \PHP_INT_MAX ));
427
417
}
418
+ $ tagVersions [$ tag = $ tags [$ tag ]] = $ version ->get ();
428
419
$ this ->knownTagVersions [$ tag ] = [$ now , $ tagVersions [$ tag ]];
429
420
}
430
421
422
+ if ($ newTags ) {
423
+ (self ::$ saveTags )($ this ->tags , $ newTags );
424
+ }
425
+
431
426
return $ tagVersions ;
432
427
}
433
428
}
0 commit comments