@@ -31,6 +31,7 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
31
31
private $ namespace ;
32
32
private $ namespaceLen ;
33
33
private $ createCacheItem ;
34
+ private $ setInnerItem ;
34
35
private $ poolHash ;
35
36
36
37
public function __construct (CacheItemPoolInterface $ pool , string $ namespace = '' , int $ defaultLifetime = 0 )
@@ -43,32 +44,65 @@ public function __construct(CacheItemPoolInterface $pool, string $namespace = ''
43
44
function ($ key , $ innerItem ) use ($ defaultLifetime , $ poolHash ) {
44
45
$ item = new CacheItem ();
45
46
$ item ->key = $ key ;
46
- $ item ->value = $ innerItem ->get ();
47
+ $ item ->value = $ v = $ innerItem ->get ();
47
48
$ item ->isHit = $ innerItem ->isHit ();
48
49
$ item ->defaultLifetime = $ defaultLifetime ;
49
50
$ item ->innerItem = $ innerItem ;
50
51
$ item ->poolHash = $ poolHash ;
52
+ // Detect wrapped values that encode for their expiry and creation duration
53
+ // For compacity, these values are packed in the key of an array using magic numbers
54
+ if (\is_array ($ v ) && 1 === \count ($ v ) && 10 === \strlen ($ k = \key ($ v )) && "\x9D" === $ k [0 ] && "\0" === $ k [5 ] && "\x5F" === $ k [9 ]) {
55
+ $ item ->value = $ v [$ k ];
56
+ $ v = \unpack ('Ve/Nc ' , \substr ($ k , 1 , -1 ));
57
+ $ item ->metadata [CacheItem::METADATA_EXPIRY ] = $ v ['e ' ] + CacheItem::METADATA_EXPIRY_OFFSET ;
58
+ $ item ->metadata [CacheItem::METADATA_CTIME ] = $ v ['c ' ];
59
+ } elseif ($ innerItem instanceof CacheItem) {
60
+ $ item ->metadata = $ innerItem ->metadata ;
61
+ }
51
62
$ innerItem ->set (null );
52
63
53
64
return $ item ;
54
65
},
55
66
null ,
56
67
CacheItem::class
57
68
);
69
+ $ this ->setInnerItem = \Closure::bind (
70
+ /**
71
+ * @param array $item A CacheItem cast to (array); accessing protected properties requires adding the \0*\0" PHP prefix
72
+ */
73
+ function (CacheItemInterface $ innerItem , array $ item ) {
74
+ // Tags are stored separately, no need to account for them when considering this item's newly set metadata
75
+ if (isset (($ metadata = $ item ["\0* \0newMetadata " ])[CacheItem::METADATA_TAGS ])) {
76
+ unset($ metadata [CacheItem::METADATA_TAGS ]);
77
+ }
78
+ if ($ metadata ) {
79
+ // For compacity, expiry and creation duration are packed in the key of a array, using magic numbers as separators
80
+ $ item ["\0* \0value " ] = array ("\x9D" .pack ('VN ' , (int ) $ metadata [CacheItem::METADATA_EXPIRY ] - CacheItem::METADATA_EXPIRY_OFFSET , $ metadata [CacheItem::METADATA_CTIME ])."\x5F" => $ item ["\0* \0value " ]);
81
+ }
82
+ $ innerItem ->set ($ item ["\0* \0value " ]);
83
+ $ innerItem ->expiresAt (null !== $ item ["\0* \0expiry " ] ? \DateTime::createFromFormat ('U ' , $ item ["\0* \0expiry " ]) : null );
84
+ },
85
+ null ,
86
+ CacheItem::class
87
+ );
58
88
}
59
89
60
90
/**
61
91
* {@inheritdoc}
62
92
*/
63
- public function get (string $ key , callable $ callback )
93
+ public function get (string $ key , callable $ callback, float $ beta = null )
64
94
{
65
95
if (!$ this ->pool instanceof CacheInterface) {
66
- return $ this ->doGet ($ this -> pool , $ key , $ callback );
96
+ return $ this ->doGet ($ this , $ key , $ callback, $ beta ?? 1.0 );
67
97
}
68
98
69
99
return $ this ->pool ->get ($ this ->getId ($ key ), function ($ innerItem ) use ($ key , $ callback ) {
70
- return $ callback (($ this ->createCacheItem )($ key , $ innerItem ));
71
- });
100
+ $ item = ($ this ->createCacheItem )($ key , $ innerItem );
101
+ $ item ->set ($ value = $ callback ($ item ));
102
+ ($ this ->setInnerItem )($ innerItem , (array ) $ item );
103
+
104
+ return $ value ;
105
+ }, $ beta );
72
106
}
73
107
74
108
/**
@@ -164,13 +198,11 @@ private function doSave(CacheItemInterface $item, $method)
164
198
return false ;
165
199
}
166
200
$ item = (array ) $ item ;
167
- $ expiry = $ item ["\0* \0expiry " ];
168
- if (null === $ expiry && 0 < $ item ["\0* \0defaultLifetime " ]) {
169
- $ expiry = time () + $ item ["\0* \0defaultLifetime " ];
201
+ if (null === $ item ["\0* \0expiry " ] && 0 < $ item ["\0* \0defaultLifetime " ]) {
202
+ $ item ["\0* \0expiry " ] = time () + $ item ["\0* \0defaultLifetime " ];
170
203
}
171
204
$ innerItem = $ item ["\0* \0poolHash " ] === $ this ->poolHash ? $ item ["\0* \0innerItem " ] : $ this ->pool ->getItem ($ this ->namespace .$ item ["\0* \0key " ]);
172
- $ innerItem ->set ($ item ["\0* \0value " ]);
173
- $ innerItem ->expiresAt (null !== $ expiry ? \DateTime::createFromFormat ('U ' , $ expiry ) : null );
205
+ ($ this ->setInnerItem )($ innerItem , $ item );
174
206
175
207
return $ this ->pool ->$ method ($ innerItem );
176
208
}
0 commit comments