APCu.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OC\Memcache;
  8. use bantu\IniGetWrapper\IniGetWrapper;
  9. use OCP\IMemcache;
  10. class APCu extends Cache implements IMemcache {
  11. use CASTrait {
  12. cas as casEmulated;
  13. }
  14. use CADTrait;
  15. public function get($key) {
  16. $result = apcu_fetch($this->getPrefix() . $key, $success);
  17. if (!$success) {
  18. return null;
  19. }
  20. return $result;
  21. }
  22. public function set($key, $value, $ttl = 0) {
  23. return apcu_store($this->getPrefix() . $key, $value, $ttl);
  24. }
  25. public function hasKey($key) {
  26. return apcu_exists($this->getPrefix() . $key);
  27. }
  28. public function remove($key) {
  29. return apcu_delete($this->getPrefix() . $key);
  30. }
  31. public function clear($prefix = '') {
  32. $ns = $this->getPrefix() . $prefix;
  33. $ns = preg_quote($ns, '/');
  34. if (class_exists('\APCIterator')) {
  35. $iter = new \APCIterator('user', '/^' . $ns . '/', APC_ITER_KEY);
  36. } else {
  37. $iter = new \APCUIterator('/^' . $ns . '/', APC_ITER_KEY);
  38. }
  39. return apcu_delete($iter);
  40. }
  41. /**
  42. * Set a value in the cache if it's not already stored
  43. *
  44. * @param string $key
  45. * @param mixed $value
  46. * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
  47. * @return bool
  48. */
  49. public function add($key, $value, $ttl = 0) {
  50. return apcu_add($this->getPrefix() . $key, $value, $ttl);
  51. }
  52. /**
  53. * Increase a stored number
  54. *
  55. * @param string $key
  56. * @param int $step
  57. * @return int | bool
  58. */
  59. public function inc($key, $step = 1) {
  60. $this->add($key, 0);
  61. /**
  62. * TODO - hack around a PHP 7 specific issue in APCu
  63. *
  64. * on PHP 7 the apcu_inc method on a non-existing object will increment
  65. * "0" and result in "1" as value - therefore we check for existence
  66. * first
  67. *
  68. * on PHP 5.6 this is not the case
  69. *
  70. * see https://github.com/krakjoe/apcu/issues/183#issuecomment-244038221
  71. * for details
  72. */
  73. return apcu_exists($this->getPrefix() . $key)
  74. ? apcu_inc($this->getPrefix() . $key, $step)
  75. : false;
  76. }
  77. /**
  78. * Decrease a stored number
  79. *
  80. * @param string $key
  81. * @param int $step
  82. * @return int | bool
  83. */
  84. public function dec($key, $step = 1) {
  85. /**
  86. * TODO - hack around a PHP 7 specific issue in APCu
  87. *
  88. * on PHP 7 the apcu_dec method on a non-existing object will decrement
  89. * "0" and result in "-1" as value - therefore we check for existence
  90. * first
  91. *
  92. * on PHP 5.6 this is not the case
  93. *
  94. * see https://github.com/krakjoe/apcu/issues/183#issuecomment-244038221
  95. * for details
  96. */
  97. return apcu_exists($this->getPrefix() . $key)
  98. ? apcu_dec($this->getPrefix() . $key, $step)
  99. : false;
  100. }
  101. /**
  102. * Compare and set
  103. *
  104. * @param string $key
  105. * @param mixed $old
  106. * @param mixed $new
  107. * @return bool
  108. */
  109. public function cas($key, $old, $new) {
  110. // apc only does cas for ints
  111. if (is_int($old) and is_int($new)) {
  112. return apcu_cas($this->getPrefix() . $key, $old, $new);
  113. } else {
  114. return $this->casEmulated($key, $old, $new);
  115. }
  116. }
  117. public static function isAvailable(): bool {
  118. if (!extension_loaded('apcu')) {
  119. return false;
  120. } elseif (!\OC::$server->get(IniGetWrapper::class)->getBool('apc.enabled')) {
  121. return false;
  122. } elseif (!\OC::$server->get(IniGetWrapper::class)->getBool('apc.enable_cli') && \OC::$CLI) {
  123. return false;
  124. } elseif (version_compare(phpversion('apcu') ?: '0.0.0', '5.1.0') === -1) {
  125. return false;
  126. } else {
  127. return true;
  128. }
  129. }
  130. }