Skip to content
Snippets Groups Projects
Commit 1bc56a99 authored by Robin Appelman's avatar Robin Appelman
Browse files

compare-and-set and compare-and-delete using lua scripts for redis

parent 446f6281
No related branches found
No related tags found
No related merge requests found
...@@ -26,13 +26,15 @@ namespace OC\Memcache; ...@@ -26,13 +26,15 @@ namespace OC\Memcache;
use OCP\IMemcache; use OCP\IMemcache;
class Redis extends Cache implements IMemcache { class Redis extends Cache implements IMemcache {
use CASTrait;
/** /**
* @var \Redis $cache * @var \Redis $cache
*/ */
private static $cache = null; private static $cache = null;
private static $casScript;
private static $cadScript;
public function __construct($prefix = '') { public function __construct($prefix = '') {
parent::__construct($prefix); parent::__construct($prefix);
if (is_null(self::$cache)) { if (is_null(self::$cache)) {
...@@ -57,6 +59,29 @@ class Redis extends Cache implements IMemcache { ...@@ -57,6 +59,29 @@ class Redis extends Cache implements IMemcache {
self::$cache->connect($host, $port, $timeout); self::$cache->connect($host, $port, $timeout);
self::$casScript = self::$cache->script('load', '
local key = ARGV[1]
local old = ARGV[2]
local new = ARGV[3]
if redis.call(\'get\', key) == old then
redis.call(\'set\', key, new)
return true
end
return false');
self::$cadScript = self::$cache->script('load', '
local key = ARGV[1]
local old = ARGV[2]
if redis.call(\'get\', key) == old then
redis.call(\'del\', key)
return true
end
return false');
if (isset($config['dbindex'])) { if (isset($config['dbindex'])) {
self::$cache->select($config['dbindex']); self::$cache->select($config['dbindex']);
} }
...@@ -150,6 +175,29 @@ class Redis extends Cache implements IMemcache { ...@@ -150,6 +175,29 @@ class Redis extends Cache implements IMemcache {
return self::$cache->decrBy($this->getNamespace() . $key, $step); return self::$cache->decrBy($this->getNamespace() . $key, $step);
} }
/**
* Compare and set
*
* @param string $key
* @param mixed $old
* @param mixed $new
* @return bool
*/
public function cas($key, $old, $new) {
return (bool) self::$cache->evalSha(self::$casScript, [$this->getNamespace() . $key, json_encode($old), json_encode($new)]);
}
/**
* Compare and delete
*
* @param string $key
* @param mixed $old
* @return bool
*/
public function cad($key, $old) {
return (bool)self::$cache->evalSha(self::$cadScript, [$this->getNamespace() . $key, json_encode($old)]);
}
static public function isAvailable() { static public function isAvailable() {
return extension_loaded('redis') return extension_loaded('redis')
&& version_compare(phpversion('redis'), '2.2.5', '>='); && version_compare(phpversion('redis'), '2.2.5', '>=');
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment