aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Memcache
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Memcache')
-rw-r--r--lib/private/Memcache/APCu.php64
-rw-r--r--lib/private/Memcache/ArrayCache.php25
-rw-r--r--lib/private/Memcache/CADTrait.php39
-rw-r--r--lib/private/Memcache/CASTrait.php22
-rw-r--r--lib/private/Memcache/Cache.php25
-rw-r--r--lib/private/Memcache/Factory.php108
-rw-r--r--lib/private/Memcache/LoggerWrapperCache.php32
-rw-r--r--lib/private/Memcache/Memcached.php36
-rw-r--r--lib/private/Memcache/NullCache.php32
-rw-r--r--lib/private/Memcache/ProfilerWrapperCache.php35
-rw-r--r--lib/private/Memcache/Redis.php45
-rw-r--r--lib/private/Memcache/WithLocalCache.php4
12 files changed, 172 insertions, 295 deletions
diff --git a/lib/private/Memcache/APCu.php b/lib/private/Memcache/APCu.php
index f3221fc7b77..937f8a863ab 100644
--- a/lib/private/Memcache/APCu.php
+++ b/lib/private/Memcache/APCu.php
@@ -1,29 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Andreas Fischer <bantu@owncloud.com>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Memcache;
@@ -46,6 +26,9 @@ class APCu extends Cache implements IMemcache {
}
public function set($key, $value, $ttl = 0) {
+ if ($ttl === 0) {
+ $ttl = self::DEFAULT_TTL;
+ }
return apcu_store($this->getPrefix() . $key, $value, $ttl);
}
@@ -77,6 +60,9 @@ class APCu extends Cache implements IMemcache {
* @return bool
*/
public function add($key, $value, $ttl = 0) {
+ if ($ttl === 0) {
+ $ttl = self::DEFAULT_TTL;
+ }
return apcu_add($this->getPrefix() . $key, $value, $ttl);
}
@@ -88,22 +74,8 @@ class APCu extends Cache implements IMemcache {
* @return int | bool
*/
public function inc($key, $step = 1) {
- $this->add($key, 0);
- /**
- * TODO - hack around a PHP 7 specific issue in APCu
- *
- * on PHP 7 the apcu_inc method on a non-existing object will increment
- * "0" and result in "1" as value - therefore we check for existence
- * first
- *
- * on PHP 5.6 this is not the case
- *
- * see https://github.com/krakjoe/apcu/issues/183#issuecomment-244038221
- * for details
- */
- return apcu_exists($this->getPrefix() . $key)
- ? apcu_inc($this->getPrefix() . $key, $step)
- : false;
+ $success = null;
+ return apcu_inc($this->getPrefix() . $key, $step, $success, self::DEFAULT_TTL);
}
/**
@@ -114,18 +86,6 @@ class APCu extends Cache implements IMemcache {
* @return int | bool
*/
public function dec($key, $step = 1) {
- /**
- * TODO - hack around a PHP 7 specific issue in APCu
- *
- * on PHP 7 the apcu_dec method on a non-existing object will decrement
- * "0" and result in "-1" as value - therefore we check for existence
- * first
- *
- * on PHP 5.6 this is not the case
- *
- * see https://github.com/krakjoe/apcu/issues/183#issuecomment-244038221
- * for details
- */
return apcu_exists($this->getPrefix() . $key)
? apcu_dec($this->getPrefix() . $key, $step)
: false;
diff --git a/lib/private/Memcache/ArrayCache.php b/lib/private/Memcache/ArrayCache.php
index 8c0af399116..9b3540b771f 100644
--- a/lib/private/Memcache/ArrayCache.php
+++ b/lib/private/Memcache/ArrayCache.php
@@ -1,26 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Memcache;
diff --git a/lib/private/Memcache/CADTrait.php b/lib/private/Memcache/CADTrait.php
index a0843fc7731..d0f6611c4f3 100644
--- a/lib/private/Memcache/CADTrait.php
+++ b/lib/private/Memcache/CADTrait.php
@@ -1,23 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Memcache;
@@ -50,4 +36,21 @@ trait CADTrait {
return false;
}
}
+
+ public function ncad(string $key, mixed $old): bool {
+ //no native cad, emulate with locking
+ if ($this->add($key . '_lock', true)) {
+ $value = $this->get($key);
+ if ($value !== null && $value !== $old) {
+ $this->remove($key);
+ $this->remove($key . '_lock');
+ return true;
+ } else {
+ $this->remove($key . '_lock');
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
}
diff --git a/lib/private/Memcache/CASTrait.php b/lib/private/Memcache/CASTrait.php
index 13688651043..8c2d2a46b19 100644
--- a/lib/private/Memcache/CASTrait.php
+++ b/lib/private/Memcache/CASTrait.php
@@ -1,23 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Memcache;
diff --git a/lib/private/Memcache/Cache.php b/lib/private/Memcache/Cache.php
index f0e794d6582..774769b25fe 100644
--- a/lib/private/Memcache/Cache.php
+++ b/lib/private/Memcache/Cache.php
@@ -1,26 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- *
- * @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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Memcache;
diff --git a/lib/private/Memcache/Factory.php b/lib/private/Memcache/Factory.php
index ab8fcea4e6a..b54189937fc 100644
--- a/lib/private/Memcache/Factory.php
+++ b/lib/private/Memcache/Factory.php
@@ -1,36 +1,13 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Markus Goetz <markus@woboq.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Richard Steinmetz <richard@steinmetz.cloud>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Stefan Weil <sw@weilnetz.de>
- * @author Vincent Petry <vincent@nextcloud.com>
- *
- * @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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Memcache;
+use Closure;
use OCP\Cache\CappedMemoryCache;
use OCP\ICache;
use OCP\ICacheFactory;
@@ -41,7 +18,7 @@ use Psr\Log\LoggerInterface;
class Factory implements ICacheFactory {
public const NULL_CACHE = NullCache::class;
- private string $globalPrefix;
+ private ?string $globalPrefix = null;
private LoggerInterface $logger;
@@ -65,17 +42,23 @@ class Factory implements ICacheFactory {
private IProfiler $profiler;
/**
- * @param string $globalPrefix
+ * @param Closure $globalPrefixClosure
* @param LoggerInterface $logger
* @param ?class-string<ICache> $localCacheClass
* @param ?class-string<ICache> $distributedCacheClass
* @param ?class-string<IMemcache> $lockingCacheClass
* @param string $logFile
*/
- public function __construct(string $globalPrefix, LoggerInterface $logger, IProfiler $profiler,
- ?string $localCacheClass = null, ?string $distributedCacheClass = null, ?string $lockingCacheClass = null, string $logFile = '') {
+ public function __construct(
+ private Closure $globalPrefixClosure,
+ LoggerInterface $logger,
+ IProfiler $profiler,
+ ?string $localCacheClass = null,
+ ?string $distributedCacheClass = null,
+ ?string $lockingCacheClass = null,
+ string $logFile = '',
+ ) {
$this->logFile = $logFile;
- $this->globalPrefix = $globalPrefix;
if (!$localCacheClass) {
$localCacheClass = self::NULL_CACHE;
@@ -84,19 +67,34 @@ class Factory implements ICacheFactory {
if (!$distributedCacheClass) {
$distributedCacheClass = $localCacheClass;
}
+
$distributedCacheClass = ltrim($distributedCacheClass, '\\');
$missingCacheMessage = 'Memcache {class} not available for {use} cache';
$missingCacheHint = 'Is the matching PHP module installed and enabled?';
if (!class_exists($localCacheClass) || !$localCacheClass::isAvailable()) {
- throw new \OCP\HintException(strtr($missingCacheMessage, [
- '{class}' => $localCacheClass, '{use}' => 'local'
- ]), $missingCacheHint);
+ if (\OC::$CLI && !defined('PHPUNIT_RUN') && $localCacheClass === APCu::class) {
+ // CLI should not fail if APCu is not available but fallback to NullCache.
+ // This can be the case if APCu is used without apc.enable_cli=1.
+ // APCu however cannot be shared between PHP instances (CLI and web) anyway.
+ $localCacheClass = self::NULL_CACHE;
+ } else {
+ throw new \OCP\HintException(strtr($missingCacheMessage, [
+ '{class}' => $localCacheClass, '{use}' => 'local'
+ ]), $missingCacheHint);
+ }
}
if (!class_exists($distributedCacheClass) || !$distributedCacheClass::isAvailable()) {
- throw new \OCP\HintException(strtr($missingCacheMessage, [
- '{class}' => $distributedCacheClass, '{use}' => 'distributed'
- ]), $missingCacheHint);
+ if (\OC::$CLI && !defined('PHPUNIT_RUN') && $distributedCacheClass === APCu::class) {
+ // CLI should not fail if APCu is not available but fallback to NullCache.
+ // This can be the case if APCu is used without apc.enable_cli=1.
+ // APCu however cannot be shared between Nextcloud (PHP) instances anyway.
+ $distributedCacheClass = self::NULL_CACHE;
+ } else {
+ throw new \OCP\HintException(strtr($missingCacheMessage, [
+ '{class}' => $distributedCacheClass, '{use}' => 'distributed'
+ ]), $missingCacheHint);
+ }
}
if (!($lockingCacheClass && class_exists($lockingCacheClass) && $lockingCacheClass::isAvailable())) {
// don't fall back since the fallback might not be suitable for storing lock
@@ -110,6 +108,13 @@ class Factory implements ICacheFactory {
$this->profiler = $profiler;
}
+ private function getGlobalPrefix(): ?string {
+ if (is_null($this->globalPrefix)) {
+ $this->globalPrefix = ($this->globalPrefixClosure)();
+ }
+ return $this->globalPrefix;
+ }
+
/**
* create a cache instance for storing locks
*
@@ -117,16 +122,21 @@ class Factory implements ICacheFactory {
* @return IMemcache
*/
public function createLocking(string $prefix = ''): IMemcache {
+ $globalPrefix = $this->getGlobalPrefix();
+ if (is_null($globalPrefix)) {
+ return new ArrayCache($prefix);
+ }
+
assert($this->lockingCacheClass !== null);
- $cache = new $this->lockingCacheClass($this->globalPrefix . '/' . $prefix);
+ $cache = new $this->lockingCacheClass($globalPrefix . '/' . $prefix);
if ($this->lockingCacheClass === Redis::class && $this->profiler->isEnabled()) {
// We only support the profiler with Redis
$cache = new ProfilerWrapperCache($cache, 'Locking');
$this->profiler->add($cache);
}
- if ($this->lockingCacheClass === Redis::class &&
- $this->logFile !== '' && is_writable(dirname($this->logFile)) && (!file_exists($this->logFile) || is_writable($this->logFile))) {
+ if ($this->lockingCacheClass === Redis::class
+ && $this->logFile !== '' && is_writable(dirname($this->logFile)) && (!file_exists($this->logFile) || is_writable($this->logFile))) {
$cache = new LoggerWrapperCache($cache, $this->logFile);
}
return $cache;
@@ -139,8 +149,13 @@ class Factory implements ICacheFactory {
* @return ICache
*/
public function createDistributed(string $prefix = ''): ICache {
+ $globalPrefix = $this->getGlobalPrefix();
+ if (is_null($globalPrefix)) {
+ return new ArrayCache($prefix);
+ }
+
assert($this->distributedCacheClass !== null);
- $cache = new $this->distributedCacheClass($this->globalPrefix . '/' . $prefix);
+ $cache = new $this->distributedCacheClass($globalPrefix . '/' . $prefix);
if ($this->distributedCacheClass === Redis::class && $this->profiler->isEnabled()) {
// We only support the profiler with Redis
$cache = new ProfilerWrapperCache($cache, 'Distributed');
@@ -161,8 +176,13 @@ class Factory implements ICacheFactory {
* @return ICache
*/
public function createLocal(string $prefix = ''): ICache {
+ $globalPrefix = $this->getGlobalPrefix();
+ if (is_null($globalPrefix)) {
+ return new ArrayCache($prefix);
+ }
+
assert($this->localCacheClass !== null);
- $cache = new $this->localCacheClass($this->globalPrefix . '/' . $prefix);
+ $cache = new $this->localCacheClass($globalPrefix . '/' . $prefix);
if ($this->localCacheClass === Redis::class && $this->profiler->isEnabled()) {
// We only support the profiler with Redis
$cache = new ProfilerWrapperCache($cache, 'Local');
diff --git a/lib/private/Memcache/LoggerWrapperCache.php b/lib/private/Memcache/LoggerWrapperCache.php
index a59520a11e5..c2a06731910 100644
--- a/lib/private/Memcache/LoggerWrapperCache.php
+++ b/lib/private/Memcache/LoggerWrapperCache.php
@@ -2,25 +2,8 @@
declare(strict_types = 1);
/**
- * @copyright 2022 Carl Schwan <carl@carlschwan.eu>
- *
- * @author Carl Schwan <carl@carlschwan.eu>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\Memcache;
@@ -167,6 +150,17 @@ class LoggerWrapperCache extends Cache implements IMemcacheTTL {
}
/** @inheritDoc */
+ public function ncad(string $key, mixed $old): bool {
+ file_put_contents(
+ $this->logFile,
+ $this->getNameSpace() . '::ncad::' . $key . "\n",
+ FILE_APPEND
+ );
+
+ return $this->wrappedCache->cad($key, $old);
+ }
+
+ /** @inheritDoc */
public function setTTL(string $key, int $ttl) {
$this->wrappedCache->setTTL($key, $ttl);
}
diff --git a/lib/private/Memcache/Memcached.php b/lib/private/Memcache/Memcached.php
index 7d512d4d1ae..d8b624a978a 100644
--- a/lib/private/Memcache/Memcached.php
+++ b/lib/private/Memcache/Memcached.php
@@ -1,33 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Andreas Fischer <bantu@owncloud.com>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Victor Dubiniuk <dubiniuk@owncloud.com>
- *
- * @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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Memcache;
@@ -73,8 +49,8 @@ class Memcached extends Cache implements IMemcache {
* @psalm-suppress TypeDoesNotContainType
*/
if (\Memcached::HAVE_IGBINARY) {
- $defaultOptions[\Memcached::OPT_SERIALIZER] =
- \Memcached::SERIALIZER_IGBINARY;
+ $defaultOptions[\Memcached::OPT_SERIALIZER]
+ = \Memcached::SERIALIZER_IGBINARY;
}
$options = \OC::$server->getConfig()->getSystemValue('memcached_options', []);
if (is_array($options)) {
diff --git a/lib/private/Memcache/NullCache.php b/lib/private/Memcache/NullCache.php
index fc41595dfe1..eac1e6ddadc 100644
--- a/lib/private/Memcache/NullCache.php
+++ b/lib/private/Memcache/NullCache.php
@@ -1,28 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <vincent@nextcloud.com>
- *
- * @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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Memcache;
@@ -63,6 +44,11 @@ class NullCache extends Cache implements \OCP\IMemcache {
return true;
}
+ public function ncad(string $key, mixed $old): bool {
+ return true;
+ }
+
+
public function clear($prefix = '') {
return true;
}
diff --git a/lib/private/Memcache/ProfilerWrapperCache.php b/lib/private/Memcache/ProfilerWrapperCache.php
index 68fa4e7f22c..97d9d828a32 100644
--- a/lib/private/Memcache/ProfilerWrapperCache.php
+++ b/lib/private/Memcache/ProfilerWrapperCache.php
@@ -2,25 +2,8 @@
declare(strict_types = 1);
/**
- * @copyright 2022 Carl Schwan <carl@carlschwan.eu>
- *
- * @author Carl Schwan <carl@carlschwan.eu>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * 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
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\Memcache;
@@ -35,7 +18,7 @@ use OCP\IMemcacheTTL;
* @template-implements \ArrayAccess<string,mixed>
*/
class ProfilerWrapperCache extends AbstractDataCollector implements IMemcacheTTL, \ArrayAccess {
- /** @var Redis $wrappedCache*/
+ /** @var Redis $wrappedCache */
protected $wrappedCache;
/** @var string $prefix */
@@ -184,6 +167,18 @@ class ProfilerWrapperCache extends AbstractDataCollector implements IMemcacheTTL
}
/** @inheritDoc */
+ public function ncad(string $key, mixed $old): bool {
+ $start = microtime(true);
+ $ret = $this->wrappedCache->ncad($key, $old);
+ $this->data['queries'][] = [
+ 'start' => $start,
+ 'end' => microtime(true),
+ 'op' => $this->getPrefix() . '::ncad::' . $key,
+ ];
+ return $ret;
+ }
+
+ /** @inheritDoc */
public function setTTL(string $key, int $ttl) {
$this->wrappedCache->setTTL($key, $ttl);
}
diff --git a/lib/private/Memcache/Redis.php b/lib/private/Memcache/Redis.php
index 4f86ff68052..f8c51570c4f 100644
--- a/lib/private/Memcache/Redis.php
+++ b/lib/private/Memcache/Redis.php
@@ -1,31 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Stefan Weil <sw@weilnetz.de>
- *
- * @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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Memcache;
@@ -46,13 +24,16 @@ class Redis extends Cache implements IMemcacheTTL {
'if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end',
'cf0e94b2e9ffc7e04395cf88f7583fc309985910',
],
+ 'ncad' => [
+ 'if redis.call("get", KEYS[1]) ~= ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end',
+ '75526f8048b13ce94a41b58eee59c664b4990ab2',
+ ],
'caSetTtl' => [
'if redis.call("get", KEYS[1]) == ARGV[1] then redis.call("expire", KEYS[1], ARGV[2]) return 1 else return 0 end',
'fa4acbc946d23ef41d7d3910880b60e6e4972d72',
],
];
- private const DEFAULT_TTL = 24 * 60 * 60; // 1 day
private const MAX_TTL = 30 * 24 * 60 * 60; // 1 month
/**
@@ -188,6 +169,12 @@ class Redis extends Cache implements IMemcacheTTL {
return $this->evalLua('cad', [$key], [$old]) > 0;
}
+ public function ncad(string $key, mixed $old): bool {
+ $old = self::encodeValue($old);
+
+ return $this->evalLua('ncad', [$key], [$old]) > 0;
+ }
+
public function setTTL($key, $ttl) {
if ($ttl === 0) {
// having infinite TTL can lead to leaked keys as the prefix changes with version upgrades
@@ -226,10 +213,10 @@ class Redis extends Cache implements IMemcacheTTL {
}
protected static function encodeValue(mixed $value): string {
- return is_int($value) ? (string) $value : json_encode($value);
+ return is_int($value) ? (string)$value : json_encode($value);
}
protected static function decodeValue(string $value): mixed {
- return is_numeric($value) ? (int) $value : json_decode($value, true);
+ return is_numeric($value) ? (int)$value : json_decode($value, true);
}
}
diff --git a/lib/private/Memcache/WithLocalCache.php b/lib/private/Memcache/WithLocalCache.php
index 5b7ccc10e39..0fc5d310801 100644
--- a/lib/private/Memcache/WithLocalCache.php
+++ b/lib/private/Memcache/WithLocalCache.php
@@ -1,5 +1,9 @@
<?php
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
namespace OC\Memcache;
use OCP\Cache\CappedMemoryCache;