From 5418c98a81caba2da00b2e81fb56fe373737a7c8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 17 Mar 2013 16:01:10 +0100 Subject: [PATCH] Add memcached backend --- lib/memcache/cache.php | 6 ++- lib/memcache/memcached.php | 81 ++++++++++++++++++++++++++++++++ tests/lib/memcache/memcached.php | 17 +++++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 lib/memcache/memcached.php create mode 100644 tests/lib/memcache/memcached.php diff --git a/lib/memcache/cache.php b/lib/memcache/cache.php index d77ea27933f..331c689f065 100644 --- a/lib/memcache/cache.php +++ b/lib/memcache/cache.php @@ -20,6 +20,8 @@ abstract class Cache { return new XCache($global); } elseif (APC::isAvailable()) { return new APC($global); + } elseif (Memcached::isAvailable()) { + return new Memcached($global); } else { return null; } @@ -65,5 +67,7 @@ abstract class Cache { /** * @return bool */ - //static public function isAvailable(); + static public function isAvailable() { + return XCache::isAvailable() || APC::isAvailable() || Memcached::isAvailable(); + } } diff --git a/lib/memcache/memcached.php b/lib/memcache/memcached.php new file mode 100644 index 00000000000..ab35bd8bbac --- /dev/null +++ b/lib/memcache/memcached.php @@ -0,0 +1,81 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Memcache; + +class Memcached extends Cache { + protected $prefix; + + /** + * @var \Memcached $cache + */ + private static $cache = null; + + public function __construct($global = false) { + $this->prefix = \OC_Util::getInstanceId() . '/'; + if (!$global) { + $this->prefix .= \OC_User::getUser() . '/'; + } + if (is_null(self::$cache)) { + self::$cache = new \Memcached(); + list($host, $port) = \OC_Config::getValue('memcached_server', array('localhost', 11211)); + self::$cache->addServer($host, $port); + } + } + + /** + * entries in XCache gets namespaced to prevent collisions between owncloud instances and users + */ + protected function getNameSpace() { + return $this->prefix; + } + + public function get($key) { + $result = self::$cache->get($this->getNamespace() . $key); + if ($result === false and self::$cache->getResultCode() == \Memcached::RES_NOTFOUND) { + return null; + } else { + return $result; + } + } + + public function set($key, $value, $ttl = 0) { + if ($ttl > 0) { + return self::$cache->set($this->getNamespace() . $key, $value, $ttl); + } else { + return self::$cache->set($this->getNamespace() . $key, $value); + } + } + + public function hasKey($key) { + self::$cache->get($this->getNamespace() . $key); + return self::$cache->getResultCode() !== \Memcached::RES_NOTFOUND; + } + + public function remove($key) { + return self::$cache->delete($this->getNamespace() . $key); + } + + public function clear($prefix = '') { + $prefix = $this->getNamespace() . $prefix; + $allKeys = self::$cache->getAllKeys(); + $keys = array(); + $prefixLength = strlen($prefix); + foreach ($allKeys as $key) { + if (substr($key, 0, $prefixLength) === $prefix) { + $keys[] = $key; + } + } + self::$cache->deleteMulti($keys); + return true; + } + + static public function isAvailable() { + return extension_loaded('memcached'); + } +} diff --git a/tests/lib/memcache/memcached.php b/tests/lib/memcache/memcached.php new file mode 100644 index 00000000000..a0be047ed1f --- /dev/null +++ b/tests/lib/memcache/memcached.php @@ -0,0 +1,17 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_Memcache_Memcached extends Test_Cache { + public function setUp() { + if (!\OC\Memcache\Memcached::isAvailable()) { + $this->markTestSkipped('The memcached extension is not available.'); + return; + } + $this->instance = new \OC\Memcache\Memcached(); + } +} -- 2.39.5