From a6ed3bf623091162819e35dae31905febff36351 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Mon, 13 Aug 2018 11:42:14 -0400 Subject: [PATCH 01/17] Adding support for Memcached getMulti implementing the AbstractCachePool getMultiple method --- src/Adapter/Memcached/MemcachedCachePool.php | 29 ++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index ad3eca1f..ce9614cf 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -11,6 +11,9 @@ namespace Cache\Adapter\Memcached; +use Cache\Adapter\Common\Exception\CacheException; +use Cache\Adapter\Common\Exception\CachePoolException; +use Cache\Adapter\Common\Exception\InvalidArgumentException; use Cache\Adapter\Common\AbstractCachePool; use Cache\Adapter\Common\PhpCacheItem; use Cache\Adapter\Common\TagSupportWithArray; @@ -52,6 +55,32 @@ protected function fetchObjectFromCache($key) return $result; } + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + if (!is_array($keys)) { + if (!$keys instanceof \Traversable) { + throw new InvalidArgumentException('$keys is neither an array nor Traversable'); + } + // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. + $keys = iterator_to_array($keys, false); + } + $items = []; + foreach ($keys as $key) { + $this->validateKey($key); + $items[] = $this->getHierarchyKey($key); + } + $null = null; + $results = $this->cache->getMulti($items, $null, \Memcached::GET_PRESERVE_ORDER); + $return = []; + foreach ($keys as $idx => $key) { + $return[$key] = (false === $return[$key] = (isset($results[$items[$idx]]) ? unserialize($results[$items[$idx]]) : false)) ? $default : $return[$key][1]; + } + return $return;; + } + /** * {@inheritdoc} */ From 13f78c30d4207b6e91f130bf30467139b7ba2758 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Mon, 13 Aug 2018 12:59:03 -0400 Subject: [PATCH 02/17] adding support for Memcached setMulti and deleteMulti calls via setMultiple and deleteMultiple calls in the adapter --- src/Adapter/Memcached/MemcachedCachePool.php | 66 ++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index ce9614cf..e6c477ef 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -81,6 +81,72 @@ public function getMultiple($keys, $default = null) return $return;; } + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + if (!is_array($values)) { + if (!$values instanceof \Traversable) { + throw new InvalidArgumentException('$values is neither an array nor Traversable'); + } + } + $keys = []; + $arrayValues = []; + foreach ($values as $key => $value) { + if (is_int($key)) { + $key = (string) $key; + } + $this->validateKey($key); + $keys[] = $key; + $arrayValues[$key] = $value; + } + $items = $this->getItems($keys); + $itemSuccess = true; + $set = []; + if ($ttl === null) { + $expirationTimestamp = null; + } elseif ($ttl instanceof \DateTimeInterface) { + $expirationTimestamp = $ttl->getTimestamp(); + } elseif ($ttl instanceof \DateInterval) { + $date = new \DateTime(); + $date->add($ttl); + $expirationTimestamp = $date->getTimestamp(); + } elseif (is_object($ttl)) { + $expirationTimestamp = null; + } else { + $expirationTimestamp = $ttl; + } + foreach ($items as $key => $item) { + $item->expiresAfter($ttl); + $set[$this->getHierarchyKey($key)] = serialize([true, $arrayValues[$key], $item->getTags(), $item->getExpirationTimestamp()]); + } + $itemSuccess = $this->cache->setMulti($set, $expirationTimestamp); + return $itemSuccess; + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + if (!is_array($keys)) { + if (!$keys instanceof \Traversable) { + throw new InvalidArgumentException('$keys is neither an array nor Traversable'); + } + // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. + $keys = iterator_to_array($keys, false); + } + $items = []; + foreach ($keys as $key) { + $this->validateKey($key); + $items[] = $this->getHierarchyKey($key); + } + $this->cache->deleteMulti($items); + return true; + //return $this->deleteItems($keys); + } + /** * {@inheritdoc} */ From 26d3fed11840065d12361946a5cd41f6af70878a Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Mon, 13 Aug 2018 20:29:19 -0400 Subject: [PATCH 03/17] Updates supporting both pre 3.0.0 and style getMulti calls --- src/Adapter/Memcached/MemcachedCachePool.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index e6c477ef..62b6e3d7 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -72,8 +72,12 @@ public function getMultiple($keys, $default = null) $this->validateKey($key); $items[] = $this->getHierarchyKey($key); } - $null = null; - $results = $this->cache->getMulti($items, $null, \Memcached::GET_PRESERVE_ORDER); + if (defined('\Memcached::GET_EXTENDED') === false) { + $null = null; + $results = $this->cache->getMulti($items, $null, \Memcached::GET_PRESERVE_ORDER); + } else { + $results = $this->cache->getMulti($items, \Memcached::GET_EXTENDED); + } $return = []; foreach ($keys as $idx => $key) { $return[$key] = (false === $return[$key] = (isset($results[$items[$idx]]) ? unserialize($results[$items[$idx]]) : false)) ? $default : $return[$key][1]; From f2a60f768276a99e888c7baa2aa042001e4f62e1 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Mon, 13 Aug 2018 22:47:19 -0400 Subject: [PATCH 04/17] style/formatting updates --- src/Adapter/Memcached/MemcachedCachePool.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index 62b6e3d7..3c83465b 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -11,10 +11,8 @@ namespace Cache\Adapter\Memcached; -use Cache\Adapter\Common\Exception\CacheException; -use Cache\Adapter\Common\Exception\CachePoolException; -use Cache\Adapter\Common\Exception\InvalidArgumentException; use Cache\Adapter\Common\AbstractCachePool; +use Cache\Adapter\Common\Exception\InvalidArgumentException; use Cache\Adapter\Common\PhpCacheItem; use Cache\Adapter\Common\TagSupportWithArray; use Cache\Hierarchy\HierarchicalCachePoolTrait; @@ -73,7 +71,7 @@ public function getMultiple($keys, $default = null) $items[] = $this->getHierarchyKey($key); } if (defined('\Memcached::GET_EXTENDED') === false) { - $null = null; + $null = null; $results = $this->cache->getMulti($items, $null, \Memcached::GET_PRESERVE_ORDER); } else { $results = $this->cache->getMulti($items, \Memcached::GET_EXTENDED); @@ -82,7 +80,8 @@ public function getMultiple($keys, $default = null) foreach ($keys as $idx => $key) { $return[$key] = (false === $return[$key] = (isset($results[$items[$idx]]) ? unserialize($results[$items[$idx]]) : false)) ? $default : $return[$key][1]; } - return $return;; + + return $return; } /** @@ -107,12 +106,12 @@ public function setMultiple($values, $ttl = null) } $items = $this->getItems($keys); $itemSuccess = true; - $set = []; + $set = []; if ($ttl === null) { $expirationTimestamp = null; } elseif ($ttl instanceof \DateTimeInterface) { $expirationTimestamp = $ttl->getTimestamp(); - } elseif ($ttl instanceof \DateInterval) { + } elseif ($ttl instanceof \DateInterval) { $date = new \DateTime(); $date->add($ttl); $expirationTimestamp = $date->getTimestamp(); @@ -126,6 +125,7 @@ public function setMultiple($values, $ttl = null) $set[$this->getHierarchyKey($key)] = serialize([true, $arrayValues[$key], $item->getTags(), $item->getExpirationTimestamp()]); } $itemSuccess = $this->cache->setMulti($set, $expirationTimestamp); + return $itemSuccess; } @@ -147,6 +147,7 @@ public function deleteMultiple($keys) $items[] = $this->getHierarchyKey($key); } $this->cache->deleteMulti($items); + return true; //return $this->deleteItems($keys); } From 8aef0948ffe9aeed6c5a071cc00ccdca4d3ad86a Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Mon, 13 Aug 2018 22:50:44 -0400 Subject: [PATCH 05/17] updates fixing the one test error --- src/Adapter/Memcached/MemcachedCachePool.php | 384 +++++++++---------- 1 file changed, 192 insertions(+), 192 deletions(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index 3c83465b..c0c8632f 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -24,196 +24,196 @@ */ class MemcachedCachePool extends AbstractCachePool implements HierarchicalPoolInterface { - use HierarchicalCachePoolTrait; - use TagSupportWithArray; - - /** - * @type \Memcached - */ - protected $cache; - - /** - * @param \Memcached $cache - */ - public function __construct(\Memcached $cache) - { - $this->cache = $cache; - $this->cache->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); - } - - /** - * {@inheritdoc} - */ - protected function fetchObjectFromCache($key) - { - if (false === $result = unserialize($this->cache->get($this->getHierarchyKey($key)))) { - return [false, null, [], null]; - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function getMultiple($keys, $default = null) - { - if (!is_array($keys)) { - if (!$keys instanceof \Traversable) { - throw new InvalidArgumentException('$keys is neither an array nor Traversable'); - } - // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. - $keys = iterator_to_array($keys, false); - } - $items = []; - foreach ($keys as $key) { - $this->validateKey($key); - $items[] = $this->getHierarchyKey($key); - } - if (defined('\Memcached::GET_EXTENDED') === false) { - $null = null; - $results = $this->cache->getMulti($items, $null, \Memcached::GET_PRESERVE_ORDER); - } else { - $results = $this->cache->getMulti($items, \Memcached::GET_EXTENDED); - } - $return = []; - foreach ($keys as $idx => $key) { - $return[$key] = (false === $return[$key] = (isset($results[$items[$idx]]) ? unserialize($results[$items[$idx]]) : false)) ? $default : $return[$key][1]; - } - - return $return; - } - - /** - * {@inheritdoc} - */ - public function setMultiple($values, $ttl = null) - { - if (!is_array($values)) { - if (!$values instanceof \Traversable) { - throw new InvalidArgumentException('$values is neither an array nor Traversable'); - } - } - $keys = []; - $arrayValues = []; - foreach ($values as $key => $value) { - if (is_int($key)) { - $key = (string) $key; - } - $this->validateKey($key); - $keys[] = $key; - $arrayValues[$key] = $value; - } - $items = $this->getItems($keys); - $itemSuccess = true; - $set = []; - if ($ttl === null) { - $expirationTimestamp = null; - } elseif ($ttl instanceof \DateTimeInterface) { - $expirationTimestamp = $ttl->getTimestamp(); - } elseif ($ttl instanceof \DateInterval) { - $date = new \DateTime(); - $date->add($ttl); - $expirationTimestamp = $date->getTimestamp(); - } elseif (is_object($ttl)) { - $expirationTimestamp = null; - } else { - $expirationTimestamp = $ttl; - } - foreach ($items as $key => $item) { - $item->expiresAfter($ttl); - $set[$this->getHierarchyKey($key)] = serialize([true, $arrayValues[$key], $item->getTags(), $item->getExpirationTimestamp()]); - } - $itemSuccess = $this->cache->setMulti($set, $expirationTimestamp); - - return $itemSuccess; - } - - /** - * {@inheritdoc} - */ - public function deleteMultiple($keys) - { - if (!is_array($keys)) { - if (!$keys instanceof \Traversable) { - throw new InvalidArgumentException('$keys is neither an array nor Traversable'); - } - // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. - $keys = iterator_to_array($keys, false); - } - $items = []; - foreach ($keys as $key) { - $this->validateKey($key); - $items[] = $this->getHierarchyKey($key); - } - $this->cache->deleteMulti($items); - - return true; - //return $this->deleteItems($keys); - } - - /** - * {@inheritdoc} - */ - protected function clearAllObjectsFromCache() - { - return $this->cache->flush(); - } - - /** - * {@inheritdoc} - */ - protected function clearOneObjectFromCache($key) - { - $this->commit(); - $path = null; - $key = $this->getHierarchyKey($key, $path); - if ($path) { - $this->cache->increment($path, 1, 0); - } - $this->clearHierarchyKeyCache(); - - if ($this->cache->delete($key)) { - return true; - } - - // Return true if key not found - return $this->cache->getResultCode() === \Memcached::RES_NOTFOUND; - } - - /** - * {@inheritdoc} - */ - protected function storeItemInCache(PhpCacheItem $item, $ttl) - { - if ($ttl === null) { - $ttl = 0; - } elseif ($ttl < 0) { - return false; - } elseif ($ttl > 86400 * 30) { - // Any time higher than 30 days is interpreted as a unix timestamp date. - // https://github.com/memcached/memcached/wiki/Programming#expiration - $ttl = time() + $ttl; - } - - $key = $this->getHierarchyKey($item->getKey()); - - return $this->cache->set($key, serialize([true, $item->get(), $item->getTags(), $item->getExpirationTimestamp()]), $ttl); - } - - /** - * {@inheritdoc} - */ - public function getDirectValue($name) - { - return $this->cache->get($name); - } - - /** - * {@inheritdoc} - */ - public function setDirectValue($name, $value) - { - $this->cache->set($name, $value); - } + use HierarchicalCachePoolTrait; + use TagSupportWithArray; + + /** + * @type \Memcached + */ + protected $cache; + + /** + * @param \Memcached $cache + */ + public function __construct(\Memcached $cache) + { + $this->cache = $cache; + $this->cache->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); + } + + /** + * {@inheritdoc} + */ + protected function fetchObjectFromCache($key) + { + if (false === $result = unserialize($this->cache->get($this->getHierarchyKey($key)))) { + return [false, null, [], null]; + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + if (!is_array($keys)) { + if (!$keys instanceof \Traversable) { + throw new InvalidArgumentException('$keys is neither an array nor Traversable'); + } + // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. + $keys = iterator_to_array($keys, false); + } + $items = []; + foreach ($keys as $key) { + $this->validateKey($key); + $items[] = $this->getHierarchyKey($key); + } + if (defined('\Memcached::GET_EXTENDED') === false) { + $null = null; + $results = $this->cache->getMulti($items, $null, \Memcached::GET_PRESERVE_ORDER); + } else { + $results = $this->cache->getMulti($items, \Memcached::GET_EXTENDED); + } + $return = []; + foreach ($keys as $idx => $key) { + $return[$key] = (false === $return[$key] = (isset($results[$items[$idx]]) ? (is_array($results[$items[$idx]]) ? $results[$items[$idx]] : unserialize($results[$items[$idx]])) : false)) ? $default : $return[$key][1]; + } + + return $return; + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + if (!is_array($values)) { + if (!$values instanceof \Traversable) { + throw new InvalidArgumentException('$values is neither an array nor Traversable'); + } + } + $keys = []; + $arrayValues = []; + foreach ($values as $key => $value) { + if (is_int($key)) { + $key = (string) $key; + } + $this->validateKey($key); + $keys[] = $key; + $arrayValues[$key] = $value; + } + $items = $this->getItems($keys); + $itemSuccess = true; + $set = []; + if ($ttl === null) { + $expirationTimestamp = null; + } elseif ($ttl instanceof \DateTimeInterface) { + $expirationTimestamp = $ttl->getTimestamp(); + } elseif ($ttl instanceof \DateInterval) { + $date = new \DateTime(); + $date->add($ttl); + $expirationTimestamp = $date->getTimestamp(); + } elseif (is_object($ttl)) { + $expirationTimestamp = null; + } else { + $expirationTimestamp = $ttl; + } + foreach ($items as $key => $item) { + $item->expiresAfter($ttl); + $set[$this->getHierarchyKey($key)] = serialize([true, $arrayValues[$key], $item->getTags(), $item->getExpirationTimestamp()]); + } + $itemSuccess = $this->cache->setMulti($set, $expirationTimestamp); + + return $itemSuccess; + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + if (!is_array($keys)) { + if (!$keys instanceof \Traversable) { + throw new InvalidArgumentException('$keys is neither an array nor Traversable'); + } + // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. + $keys = iterator_to_array($keys, false); + } + $items = []; + foreach ($keys as $key) { + $this->validateKey($key); + $items[] = $this->getHierarchyKey($key); + } + $this->cache->deleteMulti($items); + + return true; + //return $this->deleteItems($keys); + } + + /** + * {@inheritdoc} + */ + protected function clearAllObjectsFromCache() + { + return $this->cache->flush(); + } + + /** + * {@inheritdoc} + */ + protected function clearOneObjectFromCache($key) + { + $this->commit(); + $path = null; + $key = $this->getHierarchyKey($key, $path); + if ($path) { + $this->cache->increment($path, 1, 0); + } + $this->clearHierarchyKeyCache(); + + if ($this->cache->delete($key)) { + return true; + } + + // Return true if key not found + return $this->cache->getResultCode() === \Memcached::RES_NOTFOUND; + } + + /** + * {@inheritdoc} + */ + protected function storeItemInCache(PhpCacheItem $item, $ttl) + { + if ($ttl === null) { + $ttl = 0; + } elseif ($ttl < 0) { + return false; + } elseif ($ttl > 86400 * 30) { + // Any time higher than 30 days is interpreted as a unix timestamp date. + // https://github.com/memcached/memcached/wiki/Programming#expiration + $ttl = time() + $ttl; + } + + $key = $this->getHierarchyKey($item->getKey()); + + return $this->cache->set($key, serialize([true, $item->get(), $item->getTags(), $item->getExpirationTimestamp()]), $ttl); + } + + /** + * {@inheritdoc} + */ + public function getDirectValue($name) + { + return $this->cache->get($name); + } + + /** + * {@inheritdoc} + */ + public function setDirectValue($name, $value) + { + $this->cache->set($name, $value); + } } From 1522b63b825a1c1f15896afaa3687d5c757bf8cf Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Mon, 13 Aug 2018 22:52:29 -0400 Subject: [PATCH 06/17] updates fixing the one test error --- src/Adapter/Memcached/MemcachedCachePool.php | 384 +++++++++---------- 1 file changed, 192 insertions(+), 192 deletions(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index c0c8632f..1778be4a 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -24,196 +24,196 @@ */ class MemcachedCachePool extends AbstractCachePool implements HierarchicalPoolInterface { - use HierarchicalCachePoolTrait; - use TagSupportWithArray; - - /** - * @type \Memcached - */ - protected $cache; - - /** - * @param \Memcached $cache - */ - public function __construct(\Memcached $cache) - { - $this->cache = $cache; - $this->cache->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); - } - - /** - * {@inheritdoc} - */ - protected function fetchObjectFromCache($key) - { - if (false === $result = unserialize($this->cache->get($this->getHierarchyKey($key)))) { - return [false, null, [], null]; - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function getMultiple($keys, $default = null) - { - if (!is_array($keys)) { - if (!$keys instanceof \Traversable) { - throw new InvalidArgumentException('$keys is neither an array nor Traversable'); - } - // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. - $keys = iterator_to_array($keys, false); - } - $items = []; - foreach ($keys as $key) { - $this->validateKey($key); - $items[] = $this->getHierarchyKey($key); - } - if (defined('\Memcached::GET_EXTENDED') === false) { - $null = null; - $results = $this->cache->getMulti($items, $null, \Memcached::GET_PRESERVE_ORDER); - } else { - $results = $this->cache->getMulti($items, \Memcached::GET_EXTENDED); - } - $return = []; - foreach ($keys as $idx => $key) { - $return[$key] = (false === $return[$key] = (isset($results[$items[$idx]]) ? (is_array($results[$items[$idx]]) ? $results[$items[$idx]] : unserialize($results[$items[$idx]])) : false)) ? $default : $return[$key][1]; - } - - return $return; - } - - /** - * {@inheritdoc} - */ - public function setMultiple($values, $ttl = null) - { - if (!is_array($values)) { - if (!$values instanceof \Traversable) { - throw new InvalidArgumentException('$values is neither an array nor Traversable'); - } - } - $keys = []; - $arrayValues = []; - foreach ($values as $key => $value) { - if (is_int($key)) { - $key = (string) $key; - } - $this->validateKey($key); - $keys[] = $key; - $arrayValues[$key] = $value; - } - $items = $this->getItems($keys); - $itemSuccess = true; - $set = []; - if ($ttl === null) { - $expirationTimestamp = null; - } elseif ($ttl instanceof \DateTimeInterface) { - $expirationTimestamp = $ttl->getTimestamp(); - } elseif ($ttl instanceof \DateInterval) { - $date = new \DateTime(); - $date->add($ttl); - $expirationTimestamp = $date->getTimestamp(); - } elseif (is_object($ttl)) { - $expirationTimestamp = null; - } else { - $expirationTimestamp = $ttl; - } - foreach ($items as $key => $item) { - $item->expiresAfter($ttl); - $set[$this->getHierarchyKey($key)] = serialize([true, $arrayValues[$key], $item->getTags(), $item->getExpirationTimestamp()]); - } - $itemSuccess = $this->cache->setMulti($set, $expirationTimestamp); - - return $itemSuccess; - } - - /** - * {@inheritdoc} - */ - public function deleteMultiple($keys) - { - if (!is_array($keys)) { - if (!$keys instanceof \Traversable) { - throw new InvalidArgumentException('$keys is neither an array nor Traversable'); - } - // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. - $keys = iterator_to_array($keys, false); - } - $items = []; - foreach ($keys as $key) { - $this->validateKey($key); - $items[] = $this->getHierarchyKey($key); - } - $this->cache->deleteMulti($items); - - return true; - //return $this->deleteItems($keys); - } - - /** - * {@inheritdoc} - */ - protected function clearAllObjectsFromCache() - { - return $this->cache->flush(); - } - - /** - * {@inheritdoc} - */ - protected function clearOneObjectFromCache($key) - { - $this->commit(); - $path = null; - $key = $this->getHierarchyKey($key, $path); - if ($path) { - $this->cache->increment($path, 1, 0); - } - $this->clearHierarchyKeyCache(); - - if ($this->cache->delete($key)) { - return true; - } - - // Return true if key not found - return $this->cache->getResultCode() === \Memcached::RES_NOTFOUND; - } - - /** - * {@inheritdoc} - */ - protected function storeItemInCache(PhpCacheItem $item, $ttl) - { - if ($ttl === null) { - $ttl = 0; - } elseif ($ttl < 0) { - return false; - } elseif ($ttl > 86400 * 30) { - // Any time higher than 30 days is interpreted as a unix timestamp date. - // https://github.com/memcached/memcached/wiki/Programming#expiration - $ttl = time() + $ttl; - } - - $key = $this->getHierarchyKey($item->getKey()); - - return $this->cache->set($key, serialize([true, $item->get(), $item->getTags(), $item->getExpirationTimestamp()]), $ttl); - } - - /** - * {@inheritdoc} - */ - public function getDirectValue($name) - { - return $this->cache->get($name); - } - - /** - * {@inheritdoc} - */ - public function setDirectValue($name, $value) - { - $this->cache->set($name, $value); - } + use HierarchicalCachePoolTrait; + use TagSupportWithArray; + + /** + * @type \Memcached + */ + protected $cache; + + /** + * @param \Memcached $cache + */ + public function __construct(\Memcached $cache) + { + $this->cache = $cache; + $this->cache->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); + } + + /** + * {@inheritdoc} + */ + protected function fetchObjectFromCache($key) + { + if (false === $result = unserialize($this->cache->get($this->getHierarchyKey($key)))) { + return [false, null, [], null]; + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + if (!is_array($keys)) { + if (!$keys instanceof \Traversable) { + throw new InvalidArgumentException('$keys is neither an array nor Traversable'); + } + // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. + $keys = iterator_to_array($keys, false); + } + $items = []; + foreach ($keys as $key) { + $this->validateKey($key); + $items[] = $this->getHierarchyKey($key); + } + if (defined('\Memcached::GET_EXTENDED') === false) { + $null = null; + $results = $this->cache->getMulti($items, $null, \Memcached::GET_PRESERVE_ORDER); + } else { + $results = $this->cache->getMulti($items, \Memcached::GET_EXTENDED); + } + $return = []; + foreach ($keys as $idx => $key) { + $return[$key] = (false === $return[$key] = (isset($results[$items[$idx]]) ? (is_array($results[$items[$idx]]) ? $results[$items[$idx]] : unserialize($results[$items[$idx]])) : false)) ? $default : $return[$key][1]; + } + + return $return; + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + if (!is_array($values)) { + if (!$values instanceof \Traversable) { + throw new InvalidArgumentException('$values is neither an array nor Traversable'); + } + } + $keys = []; + $arrayValues = []; + foreach ($values as $key => $value) { + if (is_int($key)) { + $key = (string) $key; + } + $this->validateKey($key); + $keys[] = $key; + $arrayValues[$key] = $value; + } + $items = $this->getItems($keys); + $itemSuccess = true; + $set = []; + if ($ttl === null) { + $expirationTimestamp = null; + } elseif ($ttl instanceof \DateTimeInterface) { + $expirationTimestamp = $ttl->getTimestamp(); + } elseif ($ttl instanceof \DateInterval) { + $date = new \DateTime(); + $date->add($ttl); + $expirationTimestamp = $date->getTimestamp(); + } elseif (is_object($ttl)) { + $expirationTimestamp = null; + } else { + $expirationTimestamp = $ttl; + } + foreach ($items as $key => $item) { + $item->expiresAfter($ttl); + $set[$this->getHierarchyKey($key)] = serialize([true, $arrayValues[$key], $item->getTags(), $item->getExpirationTimestamp()]); + } + $itemSuccess = $this->cache->setMulti($set, $expirationTimestamp); + + return $itemSuccess; + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + if (!is_array($keys)) { + if (!$keys instanceof \Traversable) { + throw new InvalidArgumentException('$keys is neither an array nor Traversable'); + } + // Since we need to throw an exception if *any* key is invalid, it doesn't make sense to wrap iterators or something like that. + $keys = iterator_to_array($keys, false); + } + $items = []; + foreach ($keys as $key) { + $this->validateKey($key); + $items[] = $this->getHierarchyKey($key); + } + $this->cache->deleteMulti($items); + + return true; + //return $this->deleteItems($keys); + } + + /** + * {@inheritdoc} + */ + protected function clearAllObjectsFromCache() + { + return $this->cache->flush(); + } + + /** + * {@inheritdoc} + */ + protected function clearOneObjectFromCache($key) + { + $this->commit(); + $path = null; + $key = $this->getHierarchyKey($key, $path); + if ($path) { + $this->cache->increment($path, 1, 0); + } + $this->clearHierarchyKeyCache(); + + if ($this->cache->delete($key)) { + return true; + } + + // Return true if key not found + return $this->cache->getResultCode() === \Memcached::RES_NOTFOUND; + } + + /** + * {@inheritdoc} + */ + protected function storeItemInCache(PhpCacheItem $item, $ttl) + { + if ($ttl === null) { + $ttl = 0; + } elseif ($ttl < 0) { + return false; + } elseif ($ttl > 86400 * 30) { + // Any time higher than 30 days is interpreted as a unix timestamp date. + // https://github.com/memcached/memcached/wiki/Programming#expiration + $ttl = time() + $ttl; + } + + $key = $this->getHierarchyKey($item->getKey()); + + return $this->cache->set($key, serialize([true, $item->get(), $item->getTags(), $item->getExpirationTimestamp()]), $ttl); + } + + /** + * {@inheritdoc} + */ + public function getDirectValue($name) + { + return $this->cache->get($name); + } + + /** + * {@inheritdoc} + */ + public function setDirectValue($name, $value) + { + $this->cache->set($name, $value); + } } From 1d523a6099d927d51684fd26b9fd46e90b5b0aa2 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Mon, 13 Aug 2018 23:11:07 -0400 Subject: [PATCH 07/17] fix --- src/Adapter/Memcached/MemcachedCachePool.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index 1778be4a..c4895037 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -74,7 +74,7 @@ public function getMultiple($keys, $default = null) $null = null; $results = $this->cache->getMulti($items, $null, \Memcached::GET_PRESERVE_ORDER); } else { - $results = $this->cache->getMulti($items, \Memcached::GET_EXTENDED); + $results = $this->cache->getMulti($items, \Memcached::GET_PRESERVE_ORDER); } $return = []; foreach ($keys as $idx => $key) { From de2b98de6b5acd32b2d1e9df62f47a3e49f91a3c Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Tue, 14 Aug 2018 00:00:37 -0400 Subject: [PATCH 08/17] updates returning an Iterator from getMultiple and not using the custom deleteMulti logic when were on a version of memcached that does not have it [ <2.0.0 && >0.1.0 ] --- src/Adapter/Memcached/MemcachedCachePool.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index c4895037..b1c0ebfa 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -76,12 +76,13 @@ public function getMultiple($keys, $default = null) } else { $results = $this->cache->getMulti($items, \Memcached::GET_PRESERVE_ORDER); } - $return = []; + $return = new \ArrayObject(); foreach ($keys as $idx => $key) { - $return[$key] = (false === $return[$key] = (isset($results[$items[$idx]]) ? (is_array($results[$items[$idx]]) ? $results[$items[$idx]] : unserialize($results[$items[$idx]])) : false)) ? $default : $return[$key][1]; + $value = (false === $return[$key] = (isset($results[$items[$idx]]) ? (is_array($results[$items[$idx]]) ? $results[$items[$idx]] : unserialize($results[$items[$idx]])) : false)) ? $default : $return[$key][1]; + $return->offsetSet($key, $value); } - return $return; + return $return->getIterator(); } /** @@ -134,6 +135,8 @@ public function setMultiple($values, $ttl = null) */ public function deleteMultiple($keys) { + if (!method_exists('\Memcached', 'deleteMulti')) + return parent::deleteMultiple($keys); if (!is_array($keys)) { if (!$keys instanceof \Traversable) { throw new InvalidArgumentException('$keys is neither an array nor Traversable'); From d86f656c4c04f6725ffba11a56d0e3989371ca64 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Tue, 14 Aug 2018 00:08:43 -0400 Subject: [PATCH 09/17] style conformity --- src/Adapter/Memcached/MemcachedCachePool.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index b1c0ebfa..d0c8a2e2 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -135,8 +135,9 @@ public function setMultiple($values, $ttl = null) */ public function deleteMultiple($keys) { - if (!method_exists('\Memcached', 'deleteMulti')) + if (!method_exists('\Memcached', 'deleteMulti')) { return parent::deleteMultiple($keys); + } if (!is_array($keys)) { if (!$keys instanceof \Traversable) { throw new InvalidArgumentException('$keys is neither an array nor Traversable'); From ffbd85ceacfe76cac454f5929e1d405fc6aceffd Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Tue, 14 Aug 2018 01:17:26 -0400 Subject: [PATCH 10/17] added setting the serializer to use php serializer and removed serializing and unserializing data before setting and getting, improved the ttl handling a bit as well --- src/Adapter/Memcached/MemcachedCachePool.php | 30 +++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index d0c8a2e2..020a9b27 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -39,6 +39,7 @@ public function __construct(\Memcached $cache) { $this->cache = $cache; $this->cache->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); + $this->cache->setOption(\Memcached::OPT_SERIALIZER, \Memcached::SERIALIZER_PHP); } /** @@ -46,7 +47,8 @@ public function __construct(\Memcached $cache) */ protected function fetchObjectFromCache($key) { - if (false === $result = unserialize($this->cache->get($this->getHierarchyKey($key)))) { + $value = $this->cache->get($this->getHierarchyKey($key)); + if (false === $result = (is_array($value) ? $value : unserialize($value))) { return [false, null, [], null]; } @@ -88,7 +90,7 @@ public function getMultiple($keys, $default = null) /** * {@inheritdoc} */ - public function setMultiple($values, $ttl = null) + public function setMultiple($values, $ttl = 0) { if (!is_array($values)) { if (!$values instanceof \Traversable) { @@ -108,24 +110,18 @@ public function setMultiple($values, $ttl = null) $items = $this->getItems($keys); $itemSuccess = true; $set = []; - if ($ttl === null) { - $expirationTimestamp = null; - } elseif ($ttl instanceof \DateTimeInterface) { - $expirationTimestamp = $ttl->getTimestamp(); - } elseif ($ttl instanceof \DateInterval) { - $date = new \DateTime(); - $date->add($ttl); - $expirationTimestamp = $date->getTimestamp(); - } elseif (is_object($ttl)) { - $expirationTimestamp = null; - } else { - $expirationTimestamp = $ttl; - } foreach ($items as $key => $item) { $item->expiresAfter($ttl); - $set[$this->getHierarchyKey($key)] = serialize([true, $arrayValues[$key], $item->getTags(), $item->getExpirationTimestamp()]); + $set[$this->getHierarchyKey($key)] = [true, $arrayValues[$key], $item->getTags(), $item->getExpirationTimestamp()]; + } + if ($ttl instanceof \DateInterval) { + $date = new \DateTime(); + $date->add($ttl); + $ttl = $date->getTimestamp(); + } elseif ($ttl instanceof \DateTimeInterface) { + $ttl = $ttl->getTimestamp(); } - $itemSuccess = $this->cache->setMulti($set, $expirationTimestamp); + $itemSuccess = $this->cache->setMulti($set, $ttl); return $itemSuccess; } From 38bd855f695ba90c5e0c80ccfc774b0224cdc683 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Tue, 14 Aug 2018 01:26:45 -0400 Subject: [PATCH 11/17] minor fix --- src/Adapter/Memcached/MemcachedCachePool.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index 020a9b27..be1b6b66 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -90,7 +90,7 @@ public function getMultiple($keys, $default = null) /** * {@inheritdoc} */ - public function setMultiple($values, $ttl = 0) + public function setMultiple($values, $ttl = null) { if (!is_array($values)) { if (!$values instanceof \Traversable) { From 99aa20d1a4088ccd5f93340bf0544fdfaf67e837 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Tue, 14 Aug 2018 04:25:05 -0400 Subject: [PATCH 12/17] updates improving the ttl handling --- src/Adapter/Memcached/MemcachedCachePool.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index be1b6b66..d843ecaf 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -115,11 +115,15 @@ public function setMultiple($values, $ttl = null) $set[$this->getHierarchyKey($key)] = [true, $arrayValues[$key], $item->getTags(), $item->getExpirationTimestamp()]; } if ($ttl instanceof \DateInterval) { - $date = new \DateTime(); - $date->add($ttl); - $ttl = $date->getTimestamp(); + $ttl = $ttl->format('%s'); } elseif ($ttl instanceof \DateTimeInterface) { - $ttl = $ttl->getTimestamp(); + $ttl = $ttl->getTimestamp() - time(); + } + if (is_numeric($ttl)) { + $ttl = intval($ttl); + if ($ttl <= (86400 * 30)) { + $ttl++; + } } $itemSuccess = $this->cache->setMulti($set, $ttl); From 3837822a09c6a0fa96c538c08d4f13231820e402 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Tue, 14 Aug 2018 04:38:46 -0400 Subject: [PATCH 13/17] returning a generator now from getmultple --- src/Adapter/Memcached/MemcachedCachePool.php | 22 +++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index d843ecaf..888e0155 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -78,13 +78,21 @@ public function getMultiple($keys, $default = null) } else { $results = $this->cache->getMulti($items, \Memcached::GET_PRESERVE_ORDER); } - $return = new \ArrayObject(); - foreach ($keys as $idx => $key) { - $value = (false === $return[$key] = (isset($results[$items[$idx]]) ? (is_array($results[$items[$idx]]) ? $results[$items[$idx]] : unserialize($results[$items[$idx]])) : false)) ? $default : $return[$key][1]; - $return->offsetSet($key, $value); - } - - return $return->getIterator(); + /** + * @param $default + * @param $items + * @param $results + * @param $keys + * + * @return \Generator + */ + $return = function($default, $items, $results, $keys) { + foreach ($keys as $idx => $key) { + $value = (false === $return[$key] = (isset($results[$items[$idx]]) ? (is_array($results[$items[$idx]]) ? $results[$items[$idx]] : unserialize($results[$items[$idx]])) : false)) ? $default : $return[$key][1]; + yield $key => $value; + } + }; + return $return($default, $items, $results, $keys); } /** From 5b247895e65a71628bb7b66474652a587fdc7e21 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Tue, 14 Aug 2018 04:39:41 -0400 Subject: [PATCH 14/17] styling --- src/Adapter/Memcached/MemcachedCachePool.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index 888e0155..178a5f24 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -86,12 +86,13 @@ public function getMultiple($keys, $default = null) * * @return \Generator */ - $return = function($default, $items, $results, $keys) { + $return = function ($default, $items, $results, $keys) { foreach ($keys as $idx => $key) { $value = (false === $return[$key] = (isset($results[$items[$idx]]) ? (is_array($results[$items[$idx]]) ? $results[$items[$idx]] : unserialize($results[$items[$idx]])) : false)) ? $default : $return[$key][1]; yield $key => $value; } }; + return $return($default, $items, $results, $keys); } From 42e10a22e3ab887c07d700db3cb9828a788e35f4 Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Tue, 14 Aug 2018 04:40:08 -0400 Subject: [PATCH 15/17] styling --- src/Adapter/Memcached/MemcachedCachePool.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index 178a5f24..a68cea5c 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -92,7 +92,7 @@ public function getMultiple($keys, $default = null) yield $key => $value; } }; - + return $return($default, $items, $results, $keys); } From 833051816027a80bd5157c7dcf68c4611560e31a Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Tue, 14 Aug 2018 10:04:16 -0400 Subject: [PATCH 16/17] reverting undesired change --- src/Adapter/Memcached/MemcachedCachePool.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Adapter/Memcached/MemcachedCachePool.php b/src/Adapter/Memcached/MemcachedCachePool.php index a68cea5c..efd8e5a8 100644 --- a/src/Adapter/Memcached/MemcachedCachePool.php +++ b/src/Adapter/Memcached/MemcachedCachePool.php @@ -39,7 +39,6 @@ public function __construct(\Memcached $cache) { $this->cache = $cache; $this->cache->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); - $this->cache->setOption(\Memcached::OPT_SERIALIZER, \Memcached::SERIALIZER_PHP); } /** From ba35d786a6c756c79833dfdf5207d0cf9a6ea1ab Mon Sep 17 00:00:00 2001 From: Joe Huss Date: Thu, 7 May 2026 01:00:35 -0400 Subject: [PATCH 17/17] Update composer.json keywords --- composer.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 858c316f..691de1c2 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,23 @@ "type": "library", "keywords": [ "cache", - "psr6" + "psr6", + "psr-6", + "php-cache", + "cache-adapter", + "caching", + "apcu", + "redis", + "memcached", + "mongodb", + "mysql", + "doctrine-cache", + "predis", + "file-cache", + "memcache", + "session-cache", + "serverside-cache", + "php" ], "authors": [ {