Version Notes
1.9.2.0
Download this release
Release Info
| Developer | Magento Core Team |
| Extension | Lib_Cm |
| Version | 1.9.2.0 |
| Comparing to | |
| See all releases | |
Code changes from version 1.8.0.0 to 1.9.2.0
- lib/Cm/Cache/Backend/Redis.php +226 -40
- package.xml +6 -6
lib/Cm/Cache/Backend/Redis.php
CHANGED
|
@@ -55,6 +55,10 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 55 |
const DEFAULT_CONNECT_TIMEOUT = 2.5;
|
| 56 |
const DEFAULT_CONNECT_RETRIES = 1;
|
| 57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
/** @var Credis_Client */
|
| 59 |
protected $_redis;
|
| 60 |
|
|
@@ -76,6 +80,19 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 76 |
/** @var string */
|
| 77 |
protected $_compressionLib;
|
| 78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
/**
|
| 80 |
* Contruct Zend_Cache Redis backend
|
| 81 |
* @param array $options
|
|
@@ -91,9 +108,10 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 91 |
Zend_Cache::throwException('Redis \'port\' not specified.');
|
| 92 |
}
|
| 93 |
|
|
|
|
| 94 |
$timeout = isset($options['timeout']) ? $options['timeout'] : self::DEFAULT_CONNECT_TIMEOUT;
|
| 95 |
$persistent = isset($options['persistent']) ? $options['persistent'] : '';
|
| 96 |
-
$this->_redis = new Credis_Client($options['server'], $
|
| 97 |
|
| 98 |
if ( isset($options['force_standalone']) && $options['force_standalone']) {
|
| 99 |
$this->_redis->forceStandalone();
|
|
@@ -143,11 +161,14 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 143 |
}
|
| 144 |
|
| 145 |
if ( isset($options['compression_lib']) ) {
|
| 146 |
-
$this->_compressionLib = $options['compression_lib'];
|
| 147 |
}
|
| 148 |
else if ( function_exists('snappy_compress') ) {
|
| 149 |
$this->_compressionLib = 'snappy';
|
| 150 |
}
|
|
|
|
|
|
|
|
|
|
| 151 |
else if ( function_exists('lzf_compress') ) {
|
| 152 |
$this->_compressionLib = 'lzf';
|
| 153 |
}
|
|
@@ -155,6 +176,14 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 155 |
$this->_compressionLib = 'gzip';
|
| 156 |
}
|
| 157 |
$this->_compressPrefix = substr($this->_compressionLib,0,2).self::COMPRESS_PREFIX;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
}
|
| 159 |
|
| 160 |
/**
|
|
@@ -200,10 +229,73 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 200 |
*/
|
| 201 |
public function save($data, $id, $tags = array(), $specificLifetime = false)
|
| 202 |
{
|
| 203 |
-
if
|
|
|
|
|
|
|
|
|
|
| 204 |
|
| 205 |
$lifetime = $this->getLifetime($specificLifetime);
|
| 206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
// Get list of tags previously assigned
|
| 208 |
$oldTags = $this->_decodeData($this->_redis->hGet(self::PREFIX_KEY.$id, self::FIELD_TAGS));
|
| 209 |
$oldTags = $oldTags ? explode(',', $oldTags) : array();
|
|
@@ -212,10 +304,10 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 212 |
|
| 213 |
// Set the data
|
| 214 |
$result = $this->_redis->hMSet(self::PREFIX_KEY.$id, array(
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
));
|
| 220 |
if( ! $result) {
|
| 221 |
throw new CredisException("Could not set cache key $id");
|
|
@@ -223,7 +315,7 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 223 |
|
| 224 |
// Set expiration if specified
|
| 225 |
if ($lifetime) {
|
| 226 |
-
|
| 227 |
}
|
| 228 |
|
| 229 |
// Process added tags
|
|
@@ -339,6 +431,28 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 339 |
*/
|
| 340 |
protected function _removeByMatchingAnyTags($tags)
|
| 341 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 342 |
$ids = $this->getIdsMatchingAnyTags($tags);
|
| 343 |
|
| 344 |
$this->_redis->pipeline()->multi();
|
|
@@ -369,6 +483,67 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 369 |
protected function _collectGarbage()
|
| 370 |
{
|
| 371 |
// Clean up expired keys from tag id set and global id set
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 372 |
$exists = array();
|
| 373 |
$tags = (array) $this->_redis->sMembers(self::SET_TAGS);
|
| 374 |
foreach($tags as $tag)
|
|
@@ -445,42 +620,41 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 445 |
$tags = array($tags);
|
| 446 |
}
|
| 447 |
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
|
| 451 |
-
|
| 452 |
-
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
switch ($mode)
|
| 464 |
-
{
|
| 465 |
-
case Zend_Cache::CLEANING_MODE_MATCHING_TAG:
|
| 466 |
|
| 467 |
-
|
| 468 |
-
|
| 469 |
|
| 470 |
-
|
| 471 |
|
| 472 |
-
|
| 473 |
-
|
| 474 |
|
| 475 |
-
|
| 476 |
|
| 477 |
-
|
| 478 |
-
|
| 479 |
|
| 480 |
-
|
| 481 |
-
|
|
|
|
|
|
|
|
|
|
| 482 |
}
|
| 483 |
-
return
|
| 484 |
}
|
| 485 |
|
| 486 |
/**
|
|
@@ -597,7 +771,16 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 597 |
*/
|
| 598 |
public function getFillingPercentage()
|
| 599 |
{
|
| 600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 601 |
}
|
| 602 |
|
| 603 |
/**
|
|
@@ -615,7 +798,7 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 615 |
{
|
| 616 |
list($tags, $mtime, $inf) = $this->_redis->hMGet(self::PREFIX_KEY.$id, array(self::FIELD_TAGS, self::FIELD_MTIME, self::FIELD_INF));
|
| 617 |
if( ! $mtime) {
|
| 618 |
-
|
| 619 |
}
|
| 620 |
$tags = explode(',', $this->_decodeData($tags));
|
| 621 |
$expire = $inf === '1' ? FALSE : time() + $this->_redis->ttl(self::PREFIX_KEY.$id);
|
|
@@ -678,11 +861,13 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 678 |
*/
|
| 679 |
protected function _encodeData($data, $level)
|
| 680 |
{
|
| 681 |
-
if ($level && strlen($data) >= $this->_compressThreshold) {
|
| 682 |
switch($this->_compressionLib) {
|
| 683 |
case 'snappy': $data = snappy_compress($data); break;
|
| 684 |
case 'lzf': $data = lzf_compress($data); break;
|
|
|
|
| 685 |
case 'gzip': $data = gzcompress($data, $level); break;
|
|
|
|
| 686 |
}
|
| 687 |
if( ! $data) {
|
| 688 |
throw new CredisException("Could not compress cache data.");
|
|
@@ -702,6 +887,7 @@ class Cm_Cache_Backend_Redis extends Zend_Cache_Backend implements Zend_Cache_Ba
|
|
| 702 |
switch(substr($data,0,2)) {
|
| 703 |
case 'sn': return snappy_uncompress(substr($data,5));
|
| 704 |
case 'lz': return lzf_decompress(substr($data,5));
|
|
|
|
| 705 |
case 'gz': case 'zc': return gzuncompress(substr($data,5));
|
| 706 |
}
|
| 707 |
}
|
| 55 |
const DEFAULT_CONNECT_TIMEOUT = 2.5;
|
| 56 |
const DEFAULT_CONNECT_RETRIES = 1;
|
| 57 |
|
| 58 |
+
const LUA_SAVE_SH1 = '1617c9fb2bda7d790bb1aaa320c1099d81825e64';
|
| 59 |
+
const LUA_CLEAN_SH1 = '42ab2fe548aee5ff540123687a2c39a38b54e4a2';
|
| 60 |
+
const LUA_GC_SH1 = 'c00416b970f1aa6363b44965d4cf60ee99a6f065';
|
| 61 |
+
|
| 62 |
/** @var Credis_Client */
|
| 63 |
protected $_redis;
|
| 64 |
|
| 80 |
/** @var string */
|
| 81 |
protected $_compressionLib;
|
| 82 |
|
| 83 |
+
/** @var bool */
|
| 84 |
+
protected $_useLua = false;
|
| 85 |
+
|
| 86 |
+
/**
|
| 87 |
+
* Lua's unpack() has a limit on the size of the table imposed by
|
| 88 |
+
* the number of Lua stack slots that a C function can use.
|
| 89 |
+
* This value is defined by LUAI_MAXCSTACK in luaconf.h and for Redis it is set to 8000.
|
| 90 |
+
*
|
| 91 |
+
* @see https://github.com/antirez/redis/blob/b903145/deps/lua/src/luaconf.h#L439
|
| 92 |
+
* @var int
|
| 93 |
+
*/
|
| 94 |
+
protected $_luaMaxCStack = 5000;
|
| 95 |
+
|
| 96 |
/**
|
| 97 |
* Contruct Zend_Cache Redis backend
|
| 98 |
* @param array $options
|
| 108 |
Zend_Cache::throwException('Redis \'port\' not specified.');
|
| 109 |
}
|
| 110 |
|
| 111 |
+
$port = isset($options['port']) ? $options['port'] : NULL;
|
| 112 |
$timeout = isset($options['timeout']) ? $options['timeout'] : self::DEFAULT_CONNECT_TIMEOUT;
|
| 113 |
$persistent = isset($options['persistent']) ? $options['persistent'] : '';
|
| 114 |
+
$this->_redis = new Credis_Client($options['server'], $port, $timeout, $persistent);
|
| 115 |
|
| 116 |
if ( isset($options['force_standalone']) && $options['force_standalone']) {
|
| 117 |
$this->_redis->forceStandalone();
|
| 161 |
}
|
| 162 |
|
| 163 |
if ( isset($options['compression_lib']) ) {
|
| 164 |
+
$this->_compressionLib = (string) $options['compression_lib'];
|
| 165 |
}
|
| 166 |
else if ( function_exists('snappy_compress') ) {
|
| 167 |
$this->_compressionLib = 'snappy';
|
| 168 |
}
|
| 169 |
+
else if ( function_exists('lz4_compress')) {
|
| 170 |
+
$this->_compressionLib = 'l4z';
|
| 171 |
+
}
|
| 172 |
else if ( function_exists('lzf_compress') ) {
|
| 173 |
$this->_compressionLib = 'lzf';
|
| 174 |
}
|
| 176 |
$this->_compressionLib = 'gzip';
|
| 177 |
}
|
| 178 |
$this->_compressPrefix = substr($this->_compressionLib,0,2).self::COMPRESS_PREFIX;
|
| 179 |
+
|
| 180 |
+
if (isset($options['use_lua'])) {
|
| 181 |
+
$this->_useLua = (bool) $options['use_lua'];
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
if (isset($options['lua_max_c_stack'])) {
|
| 185 |
+
$this->_luaMaxCStack = (int) $options['lua_max_c_stack'];
|
| 186 |
+
}
|
| 187 |
}
|
| 188 |
|
| 189 |
/**
|
| 229 |
*/
|
| 230 |
public function save($data, $id, $tags = array(), $specificLifetime = false)
|
| 231 |
{
|
| 232 |
+
if(!is_array($tags))
|
| 233 |
+
$tags = $tags ? array($tags) : array();
|
| 234 |
+
else
|
| 235 |
+
$tags = array_flip(array_flip($tags));
|
| 236 |
|
| 237 |
$lifetime = $this->getLifetime($specificLifetime);
|
| 238 |
|
| 239 |
+
if ($this->_useLua) {
|
| 240 |
+
$sArgs = array(
|
| 241 |
+
self::PREFIX_KEY,
|
| 242 |
+
self::FIELD_DATA,
|
| 243 |
+
self::FIELD_TAGS,
|
| 244 |
+
self::FIELD_MTIME,
|
| 245 |
+
self::FIELD_INF,
|
| 246 |
+
self::SET_TAGS,
|
| 247 |
+
self::PREFIX_TAG_IDS,
|
| 248 |
+
self::SET_IDS,
|
| 249 |
+
$id,
|
| 250 |
+
$this->_encodeData($data, $this->_compressData),
|
| 251 |
+
$this->_encodeData(implode(',',$tags), $this->_compressTags),
|
| 252 |
+
time(),
|
| 253 |
+
$lifetime ? 0 : 1,
|
| 254 |
+
min($lifetime, self::MAX_LIFETIME),
|
| 255 |
+
$this->_notMatchingTags ? 1 : 0
|
| 256 |
+
);
|
| 257 |
+
|
| 258 |
+
$res = $this->_redis->evalSha(self::LUA_SAVE_SH1, $tags, $sArgs);
|
| 259 |
+
if (is_null($res)) {
|
| 260 |
+
$script =
|
| 261 |
+
"local oldTags = redis.call('HGET', ARGV[1]..ARGV[9], ARGV[3]) ".
|
| 262 |
+
"redis.call('HMSET', ARGV[1]..ARGV[9], ARGV[2], ARGV[10], ARGV[3], ARGV[11], ARGV[4], ARGV[12], ARGV[5], ARGV[13]) ".
|
| 263 |
+
"if (ARGV[13] == '0') then ".
|
| 264 |
+
"redis.call('EXPIRE', ARGV[1]..ARGV[9], ARGV[14]) ".
|
| 265 |
+
"end ".
|
| 266 |
+
"if next(KEYS) ~= nil then ".
|
| 267 |
+
"redis.call('SADD', ARGV[6], unpack(KEYS)) ".
|
| 268 |
+
"for _, tagname in ipairs(KEYS) do ".
|
| 269 |
+
"redis.call('SADD', ARGV[7]..tagname, ARGV[9]) ".
|
| 270 |
+
"end ".
|
| 271 |
+
"end ".
|
| 272 |
+
"if (ARGV[15] == '1') then ".
|
| 273 |
+
"redis.call('SADD', ARGV[8], ARGV[9]) ".
|
| 274 |
+
"end ".
|
| 275 |
+
"if (oldTags ~= false) then ".
|
| 276 |
+
"return oldTags ".
|
| 277 |
+
"else ".
|
| 278 |
+
"return '' ".
|
| 279 |
+
"end";
|
| 280 |
+
$res = $this->_redis->eval($script, $tags, $sArgs);
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
// Process removed tags if cache entry already existed
|
| 284 |
+
if ($res) {
|
| 285 |
+
$oldTags = explode(',', $this->_decodeData($res));
|
| 286 |
+
if ($remTags = ($oldTags ? array_diff($oldTags, $tags) : FALSE))
|
| 287 |
+
{
|
| 288 |
+
// Update the id list for each tag
|
| 289 |
+
foreach($remTags as $tag)
|
| 290 |
+
{
|
| 291 |
+
$this->_redis->sRem(self::PREFIX_TAG_IDS . $tag, $id);
|
| 292 |
+
}
|
| 293 |
+
}
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
return TRUE;
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
// Get list of tags previously assigned
|
| 300 |
$oldTags = $this->_decodeData($this->_redis->hGet(self::PREFIX_KEY.$id, self::FIELD_TAGS));
|
| 301 |
$oldTags = $oldTags ? explode(',', $oldTags) : array();
|
| 304 |
|
| 305 |
// Set the data
|
| 306 |
$result = $this->_redis->hMSet(self::PREFIX_KEY.$id, array(
|
| 307 |
+
self::FIELD_DATA => $this->_encodeData($data, $this->_compressData),
|
| 308 |
+
self::FIELD_TAGS => $this->_encodeData(implode(',',$tags), $this->_compressTags),
|
| 309 |
+
self::FIELD_MTIME => time(),
|
| 310 |
+
self::FIELD_INF => $lifetime ? 0 : 1,
|
| 311 |
));
|
| 312 |
if( ! $result) {
|
| 313 |
throw new CredisException("Could not set cache key $id");
|
| 315 |
|
| 316 |
// Set expiration if specified
|
| 317 |
if ($lifetime) {
|
| 318 |
+
$this->_redis->expire(self::PREFIX_KEY.$id, min($lifetime, self::MAX_LIFETIME));
|
| 319 |
}
|
| 320 |
|
| 321 |
// Process added tags
|
| 431 |
*/
|
| 432 |
protected function _removeByMatchingAnyTags($tags)
|
| 433 |
{
|
| 434 |
+
if ($this->_useLua) {
|
| 435 |
+
$pTags = $this->_preprocessTagIds($tags);
|
| 436 |
+
$sArgs = array(self::PREFIX_KEY, self::SET_TAGS, self::SET_IDS, ($this->_notMatchingTags ? 1 : 0), (int) $this->_luaMaxCStack);
|
| 437 |
+
if ( ! $this->_redis->evalSha(self::LUA_CLEAN_SH1, $pTags, $sArgs)) {
|
| 438 |
+
$script =
|
| 439 |
+
"for i = 1, #KEYS, ARGV[5] do ".
|
| 440 |
+
"local keysToDel = redis.call('SUNION', unpack(KEYS, i, math.min(#KEYS, i + ARGV[5] - 1))) ".
|
| 441 |
+
"for _, keyname in ipairs(keysToDel) do ".
|
| 442 |
+
"redis.call('DEL', ARGV[1]..keyname) ".
|
| 443 |
+
"if (ARGV[4] == '1') then ".
|
| 444 |
+
"redis.call('SREM', ARGV[3], keyname) ".
|
| 445 |
+
"end ".
|
| 446 |
+
"end ".
|
| 447 |
+
"redis.call('DEL', unpack(KEYS, i, math.min(#KEYS, i + ARGV[5] - 1))) ".
|
| 448 |
+
"redis.call('SREM', ARGV[2], unpack(KEYS, i, math.min(#KEYS, i + ARGV[5] - 1))) ".
|
| 449 |
+
"end ".
|
| 450 |
+
"return true";
|
| 451 |
+
$this->_redis->eval($script, $pTags, $sArgs);
|
| 452 |
+
}
|
| 453 |
+
return;
|
| 454 |
+
}
|
| 455 |
+
|
| 456 |
$ids = $this->getIdsMatchingAnyTags($tags);
|
| 457 |
|
| 458 |
$this->_redis->pipeline()->multi();
|
| 483 |
protected function _collectGarbage()
|
| 484 |
{
|
| 485 |
// Clean up expired keys from tag id set and global id set
|
| 486 |
+
|
| 487 |
+
if ($this->_useLua) {
|
| 488 |
+
$sArgs = array(self::PREFIX_KEY, self::SET_TAGS, self::SET_IDS, self::PREFIX_TAG_IDS, ($this->_notMatchingTags ? 1 : 0));
|
| 489 |
+
$allTags = (array) $this->_redis->sMembers(self::SET_TAGS);
|
| 490 |
+
$tagsCount = count($allTags);
|
| 491 |
+
$counter = 0;
|
| 492 |
+
$tagsBatch = array();
|
| 493 |
+
foreach ($allTags as $tag) {
|
| 494 |
+
$tagsBatch[] = $tag;
|
| 495 |
+
$counter++;
|
| 496 |
+
if (count($tagsBatch) == 10 || $counter == $tagsCount ) {
|
| 497 |
+
if ( ! $this->_redis->evalSha(self::LUA_GC_SH1, $tagsBatch, $sArgs)) {
|
| 498 |
+
$script =
|
| 499 |
+
"local tagKeys = {} ".
|
| 500 |
+
"local expired = {} ".
|
| 501 |
+
"local expiredCount = 0 ".
|
| 502 |
+
"local notExpiredCount = 0 ".
|
| 503 |
+
"for _, tagName in ipairs(KEYS) do ".
|
| 504 |
+
"tagKeys = redis.call('SMEMBERS', ARGV[4]..tagName) ".
|
| 505 |
+
"for __, keyName in ipairs(tagKeys) do ".
|
| 506 |
+
"if (redis.call('EXISTS', ARGV[1]..keyName) == 0) then ".
|
| 507 |
+
"expiredCount = expiredCount + 1 ".
|
| 508 |
+
"expired[expiredCount] = keyName ".
|
| 509 |
+
/* Redis Lua scripts have a hard limit of 8000 parameters per command */
|
| 510 |
+
"if (expiredCount == 7990) then ".
|
| 511 |
+
"redis.call('SREM', ARGV[4]..tagName, unpack(expired)) ".
|
| 512 |
+
"if (ARGV[5] == '1') then ".
|
| 513 |
+
"redis.call('SREM', ARGV[3], unpack(expired)) ".
|
| 514 |
+
"end ".
|
| 515 |
+
"expiredCount = 0 ".
|
| 516 |
+
"expired = {} ".
|
| 517 |
+
"end ".
|
| 518 |
+
"else ".
|
| 519 |
+
"notExpiredCount = notExpiredCount + 1 ".
|
| 520 |
+
"end ".
|
| 521 |
+
"end ".
|
| 522 |
+
"if (expiredCount > 0) then ".
|
| 523 |
+
"redis.call('SREM', ARGV[4]..tagName, unpack(expired)) ".
|
| 524 |
+
"if (ARGV[5] == '1') then ".
|
| 525 |
+
"redis.call('SREM', ARGV[3], unpack(expired)) ".
|
| 526 |
+
"end ".
|
| 527 |
+
"end ".
|
| 528 |
+
"if (notExpiredCount == 0) then ".
|
| 529 |
+
"redis.call ('DEL', ARGV[4]..tagName) ".
|
| 530 |
+
"redis.call ('SREM', ARGV[2], tagName) ".
|
| 531 |
+
"end ".
|
| 532 |
+
"expired = {} ".
|
| 533 |
+
"expiredCount = 0 ".
|
| 534 |
+
"notExpiredCount = 0 ".
|
| 535 |
+
"end ".
|
| 536 |
+
"return true";
|
| 537 |
+
$this->_redis->eval($script, $tagsBatch, $sArgs);
|
| 538 |
+
}
|
| 539 |
+
$tagsBatch = array();
|
| 540 |
+
/* Give Redis some time to handle other requests */
|
| 541 |
+
usleep(20000);
|
| 542 |
+
}
|
| 543 |
+
}
|
| 544 |
+
return;
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
$exists = array();
|
| 548 |
$tags = (array) $this->_redis->sMembers(self::SET_TAGS);
|
| 549 |
foreach($tags as $tag)
|
| 620 |
$tags = array($tags);
|
| 621 |
}
|
| 622 |
|
| 623 |
+
try {
|
| 624 |
+
if ($mode == Zend_Cache::CLEANING_MODE_ALL) {
|
| 625 |
+
return $this->_redis->flushDb();
|
| 626 |
+
}
|
| 627 |
+
if ($mode == Zend_Cache::CLEANING_MODE_OLD) {
|
| 628 |
+
$this->_collectGarbage();
|
| 629 |
+
return TRUE;
|
| 630 |
+
}
|
| 631 |
+
if ( ! count($tags)) {
|
| 632 |
+
return TRUE;
|
| 633 |
+
}
|
| 634 |
+
switch ($mode)
|
| 635 |
+
{
|
| 636 |
+
case Zend_Cache::CLEANING_MODE_MATCHING_TAG:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 637 |
|
| 638 |
+
$this->_removeByMatchingTags($tags);
|
| 639 |
+
break;
|
| 640 |
|
| 641 |
+
case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG:
|
| 642 |
|
| 643 |
+
$this->_removeByNotMatchingTags($tags);
|
| 644 |
+
break;
|
| 645 |
|
| 646 |
+
case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG:
|
| 647 |
|
| 648 |
+
$this->_removeByMatchingAnyTags($tags);
|
| 649 |
+
break;
|
| 650 |
|
| 651 |
+
default:
|
| 652 |
+
Zend_Cache::throwException('Invalid mode for clean() method: '.$mode);
|
| 653 |
+
}
|
| 654 |
+
} catch (CredisException $e) {
|
| 655 |
+
Zend_Cache::throwException('Error cleaning cache by mode '.$mode.': '.$e->getMessage(), $e);
|
| 656 |
}
|
| 657 |
+
return TRUE;
|
| 658 |
}
|
| 659 |
|
| 660 |
/**
|
| 771 |
*/
|
| 772 |
public function getFillingPercentage()
|
| 773 |
{
|
| 774 |
+
$maxMem = $this->_redis->config('GET','maxmemory');
|
| 775 |
+
if (0 == (int) $maxMem['maxmemory']) {
|
| 776 |
+
return 1;
|
| 777 |
+
}
|
| 778 |
+
$info = $this->_redis->info();
|
| 779 |
+
return round(
|
| 780 |
+
($info['used_memory']/$maxMem['maxmemory']*100)
|
| 781 |
+
,0
|
| 782 |
+
,PHP_ROUND_HALF_UP
|
| 783 |
+
);
|
| 784 |
}
|
| 785 |
|
| 786 |
/**
|
| 798 |
{
|
| 799 |
list($tags, $mtime, $inf) = $this->_redis->hMGet(self::PREFIX_KEY.$id, array(self::FIELD_TAGS, self::FIELD_MTIME, self::FIELD_INF));
|
| 800 |
if( ! $mtime) {
|
| 801 |
+
return FALSE;
|
| 802 |
}
|
| 803 |
$tags = explode(',', $this->_decodeData($tags));
|
| 804 |
$expire = $inf === '1' ? FALSE : time() + $this->_redis->ttl(self::PREFIX_KEY.$id);
|
| 861 |
*/
|
| 862 |
protected function _encodeData($data, $level)
|
| 863 |
{
|
| 864 |
+
if ($this->_compressionLib && $level && strlen($data) >= $this->_compressThreshold) {
|
| 865 |
switch($this->_compressionLib) {
|
| 866 |
case 'snappy': $data = snappy_compress($data); break;
|
| 867 |
case 'lzf': $data = lzf_compress($data); break;
|
| 868 |
+
case 'l4z': $data = lz4_compress($data,($level > 1 ? true : false)); break;
|
| 869 |
case 'gzip': $data = gzcompress($data, $level); break;
|
| 870 |
+
default: throw new CredisException("Unrecognized 'compression_lib'.");
|
| 871 |
}
|
| 872 |
if( ! $data) {
|
| 873 |
throw new CredisException("Could not compress cache data.");
|
| 887 |
switch(substr($data,0,2)) {
|
| 888 |
case 'sn': return snappy_uncompress(substr($data,5));
|
| 889 |
case 'lz': return lzf_decompress(substr($data,5));
|
| 890 |
+
case 'l4': return lz4_uncompress(substr($data,5));
|
| 891 |
case 'gz': case 'zc': return gzuncompress(substr($data,5));
|
| 892 |
}
|
| 893 |
}
|
package.xml
CHANGED
|
@@ -1,18 +1,18 @@
|
|
| 1 |
<?xml version="1.0"?>
|
| 2 |
<package>
|
| 3 |
<name>Lib_Cm</name>
|
| 4 |
-
<version>1.
|
| 5 |
<stability>stable</stability>
|
| 6 |
<license uri="http://framework.zend.com/license/new-bsd">New BSD</license>
|
| 7 |
<channel>community</channel>
|
| 8 |
<extends/>
|
| 9 |
<summary>Redis adapter for Zend_Cache</summary>
|
| 10 |
<description>Redis adapter for Zend_Cache</description>
|
| 11 |
-
<notes>1.
|
| 12 |
<authors><author><name>Colin Mollenhour</name><user>core</user><email>colin@mollenhour.com</email></author></authors>
|
| 13 |
-
<date>
|
| 14 |
-
<time>
|
| 15 |
-
<contents><target name="magelib"><dir name="Cm"><dir name="Cache"><dir name="Backend"><file name="Redis.php" hash="
|
| 16 |
<compatible/>
|
| 17 |
-
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>Lib_Credis</name><channel>community</channel><min>1.
|
| 18 |
</package>
|
| 1 |
<?xml version="1.0"?>
|
| 2 |
<package>
|
| 3 |
<name>Lib_Cm</name>
|
| 4 |
+
<version>1.9.2.0</version>
|
| 5 |
<stability>stable</stability>
|
| 6 |
<license uri="http://framework.zend.com/license/new-bsd">New BSD</license>
|
| 7 |
<channel>community</channel>
|
| 8 |
<extends/>
|
| 9 |
<summary>Redis adapter for Zend_Cache</summary>
|
| 10 |
<description>Redis adapter for Zend_Cache</description>
|
| 11 |
+
<notes>1.9.2.0</notes>
|
| 12 |
<authors><author><name>Colin Mollenhour</name><user>core</user><email>colin@mollenhour.com</email></author></authors>
|
| 13 |
+
<date>2015-06-26</date>
|
| 14 |
+
<time>13:48:52</time>
|
| 15 |
+
<contents><target name="magelib"><dir name="Cm"><dir name="Cache"><dir name="Backend"><file name="Redis.php" hash="1c137eef42b9c034fa0b6d5258092c00"/></dir></dir></dir></target></contents>
|
| 16 |
<compatible/>
|
| 17 |
+
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>Lib_Credis</name><channel>community</channel><min>1.9.2.0</min><max>1.9.2.0</max></package></required></dependencies>
|
| 18 |
</package>
|
