Browse Source

extends memcache with add, inc and dec

tags/v8.1.0beta1
Robin Appelman 9 years ago
parent
commit
29213b6136

+ 38
- 1
lib/private/memcache/apc.php View File

@@ -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;

+ 55
- 1
lib/private/memcache/arraycache.php View File

@@ -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();

@@ -76,6 +78,58 @@ class ArrayCache 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) {
// 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}
*/

+ 38
- 1
lib/private/memcache/memcached.php View File

@@ -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');
}

+ 48
- 6
lib/private/memcache/redis.php View File

@@ -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');
}

+ 53
- 13
lib/private/memcache/xcache.php View File

@@ -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;
}

+ 68
- 0
lib/public/imemcache.php View File

@@ -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);
}

+ 36
- 0
tests/lib/memcache/cache.php View File

@@ -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();

Loading…
Cancel
Save