APCu.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Andreas Fischer <bantu@owncloud.com>
  6. * @author Bart Visscher <bartv@thisnet.nl>
  7. * @author Clark Tomlinson <fallen013@gmail.com>
  8. * @author Lukas Reschke <lukas@statuscode.ch>
  9. * @author Morris Jobke <hey@morrisjobke.de>
  10. * @author Robin Appelman <robin@icewind.nl>
  11. *
  12. * @license AGPL-3.0
  13. *
  14. * This code is free software: you can redistribute it and/or modify
  15. * it under the terms of the GNU Affero General Public License, version 3,
  16. * as published by the Free Software Foundation.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License, version 3,
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>
  25. *
  26. */
  27. namespace OC\Memcache;
  28. use OCP\IMemcache;
  29. class APCu extends Cache implements IMemcache {
  30. use CASTrait {
  31. cas as casEmulated;
  32. }
  33. use CADTrait;
  34. public function get($key) {
  35. $result = apcu_fetch($this->getPrefix() . $key, $success);
  36. if (!$success) {
  37. return null;
  38. }
  39. return $result;
  40. }
  41. public function set($key, $value, $ttl = 0) {
  42. return apcu_store($this->getPrefix() . $key, $value, $ttl);
  43. }
  44. public function hasKey($key) {
  45. return apcu_exists($this->getPrefix() . $key);
  46. }
  47. public function remove($key) {
  48. return apcu_delete($this->getPrefix() . $key);
  49. }
  50. public function clear($prefix = '') {
  51. $ns = $this->getPrefix() . $prefix;
  52. $ns = preg_quote($ns, '/');
  53. if(class_exists('\APCIterator')) {
  54. $iter = new \APCIterator('user', '/^' . $ns . '/', APC_ITER_KEY);
  55. } else {
  56. $iter = new \APCUIterator('/^' . $ns . '/', APC_ITER_KEY);
  57. }
  58. return apcu_delete($iter);
  59. }
  60. /**
  61. * Set a value in the cache if it's not already stored
  62. *
  63. * @param string $key
  64. * @param mixed $value
  65. * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
  66. * @return bool
  67. */
  68. public function add($key, $value, $ttl = 0) {
  69. return apcu_add($this->getPrefix() . $key, $value, $ttl);
  70. }
  71. /**
  72. * Increase a stored number
  73. *
  74. * @param string $key
  75. * @param int $step
  76. * @return int | bool
  77. */
  78. public function inc($key, $step = 1) {
  79. $this->add($key, 0);
  80. /**
  81. * TODO - hack around a PHP 7 specific issue in APCu
  82. *
  83. * on PHP 7 the apcu_inc method on a non-existing object will increment
  84. * "0" and result in "1" as value - therefore we check for existence
  85. * first
  86. *
  87. * on PHP 5.6 this is not the case
  88. *
  89. * see https://github.com/krakjoe/apcu/issues/183#issuecomment-244038221
  90. * for details
  91. */
  92. return apcu_exists($this->getPrefix() . $key)
  93. ? apcu_inc($this->getPrefix() . $key, $step)
  94. : false;
  95. }
  96. /**
  97. * Decrease a stored number
  98. *
  99. * @param string $key
  100. * @param int $step
  101. * @return int | bool
  102. */
  103. public function dec($key, $step = 1) {
  104. /**
  105. * TODO - hack around a PHP 7 specific issue in APCu
  106. *
  107. * on PHP 7 the apcu_dec method on a non-existing object will decrement
  108. * "0" and result in "-1" as value - therefore we check for existence
  109. * first
  110. *
  111. * on PHP 5.6 this is not the case
  112. *
  113. * see https://github.com/krakjoe/apcu/issues/183#issuecomment-244038221
  114. * for details
  115. */
  116. return apcu_exists($this->getPrefix() . $key)
  117. ? apcu_dec($this->getPrefix() . $key, $step)
  118. : false;
  119. }
  120. /**
  121. * Compare and set
  122. *
  123. * @param string $key
  124. * @param mixed $old
  125. * @param mixed $new
  126. * @return bool
  127. */
  128. public function cas($key, $old, $new) {
  129. // apc only does cas for ints
  130. if (is_int($old) and is_int($new)) {
  131. return apcu_cas($this->getPrefix() . $key, $old, $new);
  132. } else {
  133. return $this->casEmulated($key, $old, $new);
  134. }
  135. }
  136. /**
  137. * @return bool
  138. */
  139. static public function isAvailable() {
  140. if (!extension_loaded('apcu')) {
  141. return false;
  142. } elseif (!\OC::$server->getIniWrapper()->getBool('apc.enabled')) {
  143. return false;
  144. } elseif (!\OC::$server->getIniWrapper()->getBool('apc.enable_cli') && \OC::$CLI) {
  145. return false;
  146. } elseif (
  147. version_compare(phpversion('apc') ?: '0.0.0', '4.0.6') === -1 &&
  148. version_compare(phpversion('apcu') ?: '0.0.0', '5.1.0') === -1
  149. ) {
  150. return false;
  151. } else {
  152. return true;
  153. }
  154. }
  155. }