aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Appelman <icewind@owncloud.com>2015-04-28 15:39:38 +0200
committerRobin Appelman <icewind@owncloud.com>2015-04-30 14:48:36 +0200
commit29213b6136a4b2f71e5f981e9bc08e3e76128d4e (patch)
tree986bdf2bce27ff1c2b49828625c7f632d15cb865
parentd308ec4f0ea54e8cb0c99228a480da8cb7cf30a8 (diff)
downloadnextcloud-server-29213b6136a4b2f71e5f981e9bc08e3e76128d4e.tar.gz
nextcloud-server-29213b6136a4b2f71e5f981e9bc08e3e76128d4e.zip
extends memcache with add, inc and dec
-rw-r--r--lib/private/memcache/apc.php39
-rw-r--r--lib/private/memcache/arraycache.php56
-rw-r--r--lib/private/memcache/memcached.php39
-rw-r--r--lib/private/memcache/redis.php54
-rw-r--r--lib/private/memcache/xcache.php66
-rw-r--r--lib/public/imemcache.php68
-rw-r--r--tests/lib/memcache/cache.php36
7 files changed, 336 insertions, 22 deletions
diff --git a/lib/private/memcache/apc.php b/lib/private/memcache/apc.php
index b8b2b608124..ba16972e6d6 100644
--- a/lib/private/memcache/apc.php
+++ b/lib/private/memcache/apc.php
@@ -24,7 +24,9 @@
namespace OC\Memcache;
-class APC extends Cache {
+use OCP\IMemcache;
+
+class APC extends Cache implements IMemcache {
public function get($key) {
$result = apc_fetch($this->getPrefix() . $key, $success);
if (!$success) {
@@ -52,6 +54,41 @@ class APC extends Cache {
return apc_delete($iter);
}
+ /**
+ * Set a value in the cache if it's not already stored
+ *
+ * @param string $key
+ * @param mixed $value
+ * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
+ * @return bool
+ */
+ public function add($key, $value, $ttl = 0) {
+ return apc_add($this->getPrefix() . $key, $value, $ttl);
+ }
+
+ /**
+ * Increase a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ */
+ public function inc($key, $step = 1) {
+ $this->add($key, 0);
+ return apc_inc($this->getPrefix() . $key, $step);
+ }
+
+ /**
+ * Decrease a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ */
+ public function dec($key, $step = 1) {
+ return apc_dec($this->getPrefix() . $key, $step);
+ }
+
static public function isAvailable() {
if (!extension_loaded('apc')) {
return false;
diff --git a/lib/private/memcache/arraycache.php b/lib/private/memcache/arraycache.php
index 939472dc518..6db920a69a8 100644
--- a/lib/private/memcache/arraycache.php
+++ b/lib/private/memcache/arraycache.php
@@ -22,7 +22,9 @@
namespace OC\Memcache;
-class ArrayCache extends Cache {
+use OCP\IMemcache;
+
+class ArrayCache extends Cache implements IMemcache {
/** @var array Array with the cached data */
protected $cachedData = array();
@@ -77,6 +79,58 @@ class ArrayCache extends Cache {
}
/**
+ * Set a value in the cache if it's not already stored
+ *
+ * @param string $key
+ * @param mixed $value
+ * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
+ * @return bool
+ */
+ public function add($key, $value, $ttl = 0) {
+ // since this cache is not shared race conditions aren't an issue
+ if ($this->hasKey($key)) {
+ return false;
+ } else {
+ return $this->set($key, $value, $ttl);
+ }
+ }
+
+ /**
+ * Increase a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ */
+ public function inc($key, $step = 1) {
+ $oldValue = $this->get($key);
+ if (is_int($oldValue)) {
+ $this->set($key, $oldValue + $step);
+ return $oldValue + $step;
+ } else {
+ $success = $this->add($key, $step);
+ return ($success) ? $step : false;
+ }
+ }
+
+ /**
+ * Decrease a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ */
+ public function dec($key, $step = 1) {
+ $oldValue = $this->get($key);
+ if (is_int($oldValue)) {
+ $this->set($key, $oldValue - $step);
+ return $oldValue - $step;
+ } else {
+ return false;
+ }
+ }
+
+ /**
* {@inheritDoc}
*/
static public function isAvailable() {
diff --git a/lib/private/memcache/memcached.php b/lib/private/memcache/memcached.php
index a2b3440317f..9566e54c42b 100644
--- a/lib/private/memcache/memcached.php
+++ b/lib/private/memcache/memcached.php
@@ -24,7 +24,9 @@
namespace OC\Memcache;
-class Memcached extends Cache {
+use OCP\IMemcache;
+
+class Memcached extends Cache implements IMemcache {
/**
* @var \Memcached $cache
*/
@@ -100,6 +102,41 @@ class Memcached extends Cache {
return true;
}
+ /**
+ * Set a value in the cache if it's not already stored
+ *
+ * @param string $key
+ * @param mixed $value
+ * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
+ * @return bool
+ */
+ public function add($key, $value, $ttl = 0) {
+ return self::$cache->add($this->getPrefix() . $key, $value, $ttl);
+ }
+
+ /**
+ * Increase a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ */
+ public function inc($key, $step = 1) {
+ $this->add($key, 0);
+ return self::$cache->increment($this->getPrefix() . $key, $step);
+ }
+
+ /**
+ * Decrease a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ */
+ public function dec($key, $step = 1) {
+ return self::$cache->decrement($this->getPrefix() . $key, $step);
+ }
+
static public function isAvailable() {
return extension_loaded('memcached');
}
diff --git a/lib/private/memcache/redis.php b/lib/private/memcache/redis.php
index e7425726b2b..dc52c03422a 100644
--- a/lib/private/memcache/redis.php
+++ b/lib/private/memcache/redis.php
@@ -23,7 +23,9 @@
namespace OC\Memcache;
-class Redis extends Cache {
+use OCP\IMemcache;
+
+class Redis extends Cache implements IMemcache {
/**
* @var \Redis $cache
@@ -52,10 +54,10 @@ class Redis extends Cache {
$timeout = 0.0; // unlimited
}
- self::$cache->connect( $host, $port, $timeout );
+ self::$cache->connect($host, $port, $timeout);
if (isset($config['dbindex'])) {
- self::$cache->select( $config['dbindex'] );
+ self::$cache->select($config['dbindex']);
}
}
}
@@ -94,19 +96,59 @@ class Redis extends Cache {
} else {
return false;
}
-
}
public function clear($prefix = '') {
- $prefix = $this->getNamespace() . $prefix.'*';
+ $prefix = $this->getNamespace() . $prefix . '*';
$it = null;
self::$cache->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY);
- while($keys = self::$cache->scan($it, $prefix)) {
+ while ($keys = self::$cache->scan($it, $prefix)) {
self::$cache->delete($keys);
}
return true;
}
+ /**
+ * Set a value in the cache if it's not already stored
+ *
+ * @param string $key
+ * @param mixed $value
+ * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
+ * @return bool
+ */
+ public function add($key, $value, $ttl = 0) {
+ // dont encode ints for inc/dec
+ if (!is_int($value)) {
+ $value = json_encode($value);
+ }
+ return self::$cache->setnx($this->getPrefix() . $key, $value);
+ }
+
+ /**
+ * Increase a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ */
+ public function inc($key, $step = 1) {
+ return self::$cache->incrBy($this->getNamespace() . $key, $step);
+ }
+
+ /**
+ * Decrease a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ */
+ public function dec($key, $step = 1) {
+ if (!$this->hasKey($key)) {
+ return false;
+ }
+ return self::$cache->decrBy($this->getNamespace() . $key, $step);
+ }
+
static public function isAvailable() {
return extension_loaded('redis');
}
diff --git a/lib/private/memcache/xcache.php b/lib/private/memcache/xcache.php
index 33cea23e62b..48b0bd8a289 100644
--- a/lib/private/memcache/xcache.php
+++ b/lib/private/memcache/xcache.php
@@ -24,12 +24,13 @@
*/
namespace OC\Memcache;
+use OCP\IMemcache;
/**
* See http://xcache.lighttpd.net/wiki/XcacheApi for provided constants and
* functions etc.
*/
-class XCache extends Cache {
+class XCache extends Cache implements IMemcache {
/**
* entries in XCache gets namespaced to prevent collisions between ownCloud instances and users
*/
@@ -38,28 +39,28 @@ class XCache extends Cache {
}
public function get($key) {
- return xcache_get($this->getNamespace().$key);
+ return xcache_get($this->getNamespace() . $key);
}
- public function set($key, $value, $ttl=0) {
- if($ttl>0) {
- return xcache_set($this->getNamespace().$key, $value, $ttl);
- }else{
- return xcache_set($this->getNamespace().$key, $value);
+ public function set($key, $value, $ttl = 0) {
+ if ($ttl > 0) {
+ return xcache_set($this->getNamespace() . $key, $value, $ttl);
+ } else {
+ return xcache_set($this->getNamespace() . $key, $value);
}
}
public function hasKey($key) {
- return xcache_isset($this->getNamespace().$key);
+ return xcache_isset($this->getNamespace() . $key);
}
public function remove($key) {
- return xcache_unset($this->getNamespace().$key);
+ return xcache_unset($this->getNamespace() . $key);
}
- public function clear($prefix='') {
+ public function clear($prefix = '') {
if (function_exists('xcache_unset_by_prefix')) {
- return xcache_unset_by_prefix($this->getNamespace().$prefix);
+ return xcache_unset_by_prefix($this->getNamespace() . $prefix);
} else {
// Since we can not clear by prefix, we just clear the whole cache.
xcache_clear_cache(\XC_TYPE_VAR, 0);
@@ -67,7 +68,46 @@ class XCache extends Cache {
return true;
}
- static public function isAvailable(){
+ /**
+ * Set a value in the cache if it's not already stored
+ *
+ * @param string $key
+ * @param mixed $value
+ * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
+ * @return bool
+ */
+ public function add($key, $value, $ttl = 0) {
+ if ($this->hasKey($key)) {
+ return false;
+ } else {
+ return $this->set($key, $value, $ttl);
+ }
+ }
+
+ /**
+ * Increase a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ */
+ public function inc($key, $step = 1) {
+ $this->add($key, 0);
+ return xcache_inc($this->getPrefix() . $key, $step);
+ }
+
+ /**
+ * Decrease a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ */
+ public function dec($key, $step = 1) {
+ return xcache_dec($this->getPrefix() . $key, $step);
+ }
+
+ static public function isAvailable() {
if (!extension_loaded('xcache')) {
return false;
}
@@ -80,7 +120,7 @@ class XCache extends Cache {
// AND administration functions are password-protected.
return false;
}
- $var_size = (int) ini_get('xcache.var_size');
+ $var_size = (int)ini_get('xcache.var_size');
if (!$var_size) {
return false;
}
diff --git a/lib/public/imemcache.php b/lib/public/imemcache.php
new file mode 100644
index 00000000000..bc7762f80f9
--- /dev/null
+++ b/lib/public/imemcache.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * Cache interface
+ *
+ */
+
+// use OCP namespace for all classes that are considered public.
+// This means that they should be used by apps instead of the internal ownCloud classes
+namespace OCP;
+
+/**
+ * This interface defines method for accessing the file based user cache.
+ *
+ * @since 8.1.0
+ */
+interface IMemcache extends ICache {
+ /**
+ * Set a value in the cache if it's not already stored
+ *
+ * @param string $key
+ * @param mixed $value
+ * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
+ * @return bool
+ * @since 8.0.0
+ */
+ public function add($key, $value, $ttl = 0);
+
+ /**
+ * Increase a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ * @since 8.0.0
+ */
+ public function inc($key, $step = 1);
+
+ /**
+ * Decrease a stored number
+ *
+ * @param string $key
+ * @param int $step
+ * @return int | bool
+ * @since 8.0.0
+ */
+ public function dec($key, $step = 1);
+}
diff --git a/tests/lib/memcache/cache.php b/tests/lib/memcache/cache.php
index e5ceae52fb0..80ad182b6bf 100644
--- a/tests/lib/memcache/cache.php
+++ b/tests/lib/memcache/cache.php
@@ -10,6 +10,11 @@
namespace Test\Memcache;
abstract class Cache extends \Test_Cache {
+ /**
+ * @var \OCP\IMemcache cache;
+ */
+ protected $instance;
+
public function testExistsAfterSet() {
$this->assertFalse($this->instance->hasKey('foo'));
$this->instance->set('foo', 'bar');
@@ -56,6 +61,37 @@ abstract class Cache extends \Test_Cache {
$this->assertFalse($this->instance->hasKey('foo'));
}
+ public function testAdd() {
+ $this->assertTrue($this->instance->add('foo', 'bar'));
+ $this->assertEquals('bar', $this->instance->get('foo'));
+ $this->assertFalse($this->instance->add('foo', 'asd'));
+ $this->assertEquals('bar', $this->instance->get('foo'));
+ }
+
+ public function testInc() {
+ $this->assertEquals(1, $this->instance->inc('foo'));
+ $this->assertEquals(1, $this->instance->get('foo'));
+ $this->assertEquals(2, $this->instance->inc('foo'));
+ $this->assertEquals(12, $this->instance->inc('foo', 10));
+
+ $this->instance->set('foo', 'bar');
+ $this->assertFalse($this->instance->inc('foo'));
+ $this->assertEquals('bar', $this->instance->get('foo'));
+ }
+
+ public function testDec() {
+ $this->assertEquals(false, $this->instance->dec('foo'));
+ $this->instance->set('foo', 20);
+ $this->assertEquals(19, $this->instance->dec('foo'));
+ $this->assertEquals(19, $this->instance->get('foo'));
+ $this->assertEquals(9, $this->instance->dec('foo', 10));
+
+ $this->instance->set('foo', 'bar');
+ $this->assertFalse($this->instance->dec('foo'));
+ $this->assertEquals('bar', $this->instance->get('foo'));
+ }
+
+
protected function tearDown() {
if ($this->instance) {
$this->instance->clear();