redis.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <?php
  2. /**
  3. * @author Joas Schilling <nickvergessen@owncloud.com>
  4. * @author Jörn Friedrich Dreyer <jfd@butonic.de>
  5. * @author Morris Jobke <hey@morrisjobke.de>
  6. *
  7. * @copyright Copyright (c) 2015, ownCloud, Inc.
  8. * @license AGPL-3.0
  9. *
  10. * This code is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License, version 3,
  12. * as published by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License, version 3,
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>
  21. *
  22. */
  23. namespace OC\Memcache;
  24. use OCP\IMemcache;
  25. class Redis extends Cache implements IMemcache {
  26. use CASTrait;
  27. /**
  28. * @var \Redis $cache
  29. */
  30. private static $cache = null;
  31. public function __construct($prefix = '') {
  32. parent::__construct($prefix);
  33. if (is_null(self::$cache)) {
  34. // TODO allow configuring a RedisArray, see https://github.com/nicolasff/phpredis/blob/master/arrays.markdown#redis-arrays
  35. self::$cache = new \Redis();
  36. $config = \OC::$server->getSystemConfig()->getValue('redis', array());
  37. if (isset($config['host'])) {
  38. $host = $config['host'];
  39. } else {
  40. $host = '127.0.0.1';
  41. }
  42. if (isset($config['port'])) {
  43. $port = $config['port'];
  44. } else {
  45. $port = 6379;
  46. }
  47. if (isset($config['timeout'])) {
  48. $timeout = $config['timeout'];
  49. } else {
  50. $timeout = 0.0; // unlimited
  51. }
  52. self::$cache->connect($host, $port, $timeout);
  53. if (isset($config['dbindex'])) {
  54. self::$cache->select($config['dbindex']);
  55. }
  56. }
  57. }
  58. /**
  59. * entries in redis get namespaced to prevent collisions between ownCloud instances and users
  60. */
  61. protected function getNameSpace() {
  62. return $this->prefix;
  63. }
  64. public function get($key) {
  65. $result = self::$cache->get($this->getNamespace() . $key);
  66. if ($result === false && !self::$cache->exists($this->getNamespace() . $key)) {
  67. return null;
  68. } else {
  69. return json_decode($result, true);
  70. }
  71. }
  72. public function set($key, $value, $ttl = 0) {
  73. if ($ttl > 0) {
  74. return self::$cache->setex($this->getNamespace() . $key, $ttl, json_encode($value));
  75. } else {
  76. return self::$cache->set($this->getNamespace() . $key, json_encode($value));
  77. }
  78. }
  79. public function hasKey($key) {
  80. return self::$cache->exists($this->getNamespace() . $key);
  81. }
  82. public function remove($key) {
  83. if (self::$cache->delete($this->getNamespace() . $key)) {
  84. return true;
  85. } else {
  86. return false;
  87. }
  88. }
  89. public function clear($prefix = '') {
  90. $prefix = $this->getNamespace() . $prefix . '*';
  91. $it = null;
  92. self::$cache->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY);
  93. while ($keys = self::$cache->scan($it, $prefix)) {
  94. self::$cache->delete($keys);
  95. }
  96. return true;
  97. }
  98. /**
  99. * Set a value in the cache if it's not already stored
  100. *
  101. * @param string $key
  102. * @param mixed $value
  103. * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
  104. * @return bool
  105. */
  106. public function add($key, $value, $ttl = 0) {
  107. // dont encode ints for inc/dec
  108. if (!is_int($value)) {
  109. $value = json_encode($value);
  110. }
  111. return self::$cache->setnx($this->getPrefix() . $key, $value);
  112. }
  113. /**
  114. * Increase a stored number
  115. *
  116. * @param string $key
  117. * @param int $step
  118. * @return int | bool
  119. */
  120. public function inc($key, $step = 1) {
  121. return self::$cache->incrBy($this->getNamespace() . $key, $step);
  122. }
  123. /**
  124. * Decrease a stored number
  125. *
  126. * @param string $key
  127. * @param int $step
  128. * @return int | bool
  129. */
  130. public function dec($key, $step = 1) {
  131. if (!$this->hasKey($key)) {
  132. return false;
  133. }
  134. return self::$cache->decrBy($this->getNamespace() . $key, $step);
  135. }
  136. static public function isAvailable() {
  137. return extension_loaded('redis');
  138. }
  139. }