@@ -31,6 +31,8 @@ class APC extends Cache implements IMemcache { | |||
cas as casEmulated; | |||
} | |||
use CADTrait; | |||
public function get($key) { | |||
$result = apc_fetch($this->getPrefix() . $key, $success); | |||
if (!$success) { |
@@ -28,6 +28,8 @@ class ArrayCache extends Cache implements IMemcache { | |||
/** @var array Array with the cached data */ | |||
protected $cachedData = array(); | |||
use CADTrait; | |||
/** | |||
* {@inheritDoc} | |||
*/ |
@@ -0,0 +1,53 @@ | |||
<?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/> | |||
* | |||
*/ | |||
namespace OC\Memcache; | |||
trait CADTrait { | |||
abstract public function get($key); | |||
abstract public function remove($key); | |||
abstract public function add($key, $value, $ttl = 0); | |||
/** | |||
* Compare and delete | |||
* | |||
* @param string $key | |||
* @param mixed $old | |||
* @return bool | |||
*/ | |||
public function cad($key, $old) { | |||
//no native cas, emulate with locking | |||
if ($this->add($key . '_lock', true)) { | |||
if ($this->get($key) === $old) { | |||
$this->remove($key); | |||
$this->remove($key . '_lock'); | |||
return true; | |||
} else { | |||
$this->remove($key . '_lock'); | |||
return false; | |||
} | |||
} else { | |||
return false; | |||
} | |||
} | |||
} |
@@ -34,6 +34,8 @@ class Memcached extends Cache implements IMemcache { | |||
*/ | |||
private static $cache = null; | |||
use CADTrait; | |||
public function __construct($prefix = '') { | |||
parent::__construct($prefix); | |||
if (is_null(self::$cache)) { |
@@ -55,6 +55,10 @@ class NullCache extends Cache implements \OCP\IMemcache { | |||
return true; | |||
} | |||
public function cad($key, $old) { | |||
return true; | |||
} | |||
public function clear($prefix = '') { | |||
return true; | |||
} |
@@ -34,6 +34,8 @@ use OCP\IMemcache; | |||
class XCache extends Cache implements IMemcache { | |||
use CASTrait; | |||
use CADTrait; | |||
/** | |||
* entries in XCache gets namespaced to prevent collisions between ownCloud instances and users | |||
*/ |
@@ -76,4 +76,14 @@ interface IMemcache extends ICache { | |||
* @since 8.1.0 | |||
*/ | |||
public function cas($key, $old, $new); | |||
/** | |||
* Compare and delete | |||
* | |||
* @param string $key | |||
* @param mixed $old | |||
* @return bool | |||
* @since 8.1.0 | |||
*/ | |||
public function cad($key, $old); | |||
} |
@@ -103,6 +103,18 @@ abstract class Cache extends \Test_Cache { | |||
$this->assertEquals('bar1', $this->instance->get('foo')); | |||
} | |||
public function testCadNotChanged() { | |||
$this->instance->set('foo', 'bar'); | |||
$this->assertTrue($this->instance->cad('foo', 'bar')); | |||
$this->assertFalse($this->instance->hasKey('foo')); | |||
} | |||
public function testCadChanged() { | |||
$this->instance->set('foo', 'bar1'); | |||
$this->assertFalse($this->instance->cad('foo', 'bar')); | |||
$this->assertTrue($this->instance->hasKey('foo')); | |||
} | |||
protected function tearDown() { | |||
if ($this->instance) { |