Lib_Cm - Version 1.9.2.0

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

Files changed (2) hide show
  1. lib/Cm/Cache/Backend/Redis.php +226 -40
  2. 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'], $options['port'], $timeout, $persistent);
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 ( ! is_array($tags)) $tags = $tags ? array($tags) : array();
 
 
 
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
- self::FIELD_DATA => $this->_encodeData($data, $this->_compressData),
216
- self::FIELD_TAGS => $this->_encodeData(implode(',',$tags), $this->_compressTags),
217
- self::FIELD_MTIME => time(),
218
- self::FIELD_INF => $lifetime ? 0 : 1,
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
- $this->_redis->expire(self::PREFIX_KEY.$id, min($lifetime, self::MAX_LIFETIME));
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
- if($mode == Zend_Cache::CLEANING_MODE_ALL) {
449
- return $this->_redis->flushDb();
450
- }
451
-
452
- if($mode == Zend_Cache::CLEANING_MODE_OLD) {
453
- $this->_collectGarbage();
454
- return TRUE;
455
- }
456
-
457
- if( ! count($tags)) {
458
- return TRUE;
459
- }
460
-
461
- $result = TRUE;
462
-
463
- switch ($mode)
464
- {
465
- case Zend_Cache::CLEANING_MODE_MATCHING_TAG:
466
 
467
- $this->_removeByMatchingTags($tags);
468
- break;
469
 
470
- case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG:
471
 
472
- $this->_removeByNotMatchingTags($tags);
473
- break;
474
 
475
- case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG:
476
 
477
- $this->_removeByMatchingAnyTags($tags);
478
- break;
479
 
480
- default:
481
- Zend_Cache::throwException('Invalid mode for clean() method: '.$mode);
 
 
 
482
  }
483
- return (bool) $result;
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
- return 0;
 
 
 
 
 
 
 
 
 
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
- return FALSE;
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.8.0.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.8.0.0</notes>
12
  <authors><author><name>Colin Mollenhour</name><user>core</user><email>colin@mollenhour.com</email></author></authors>
13
- <date>2013-09-24</date>
14
- <time>09:09:42</time>
15
- <contents><target name="magelib"><dir name="Cm"><dir name="Cache"><dir name="Backend"><file name="Redis.php" hash="d904f3d17d9554a79e635957ed60d0a4"/></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.8.0.0</min><max>1.9.0.0</max></package></required></dependencies>
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>