diff --git a/lib/public/Cache/CappedMemoryCache.php b/lib/public/Cache/CappedMemoryCache.php index 20d42cfe706..fd080b35464 100644 --- a/lib/public/Cache/CappedMemoryCache.php +++ b/lib/public/Cache/CappedMemoryCache.php @@ -1,38 +1,111 @@ set('foo', 'bar'); // give key 'foo' value 'bar' + * if ($cache->hasKey('foo')) { + * echo $cache->get('foo'); // outputs 'bar' + * } + * ``` + * Or using array syntax: + * ```php + * [...] + * $cache['baz'] = 'qux'; + * if (isset($cache['baz']) { + * echo $cache['baz']; // outputs 'qux' + * } + * ``` + * + * @link https://docs.nextcloud.com/server/latest/developer_manual/basics/caching.html + * @link https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/caching_configuration.html * - * @since 25.0.0 * @template T - * @template-implements \ArrayAccess + * @template-implements \ArrayAccess + * @since 25.0.0 */ class CappedMemoryCache implements ICache, \ArrayAccess { + + /** + * Maximum number of entries allowed in the cache. + * + * @var int + */ private int $capacity; - /** @var T[] */ + + /** + * Internal cache data storage. + * + * @var array + */ private array $cache = []; /** - * @inheritdoc + * Current count of items stored in cache. + * + * @var int + */ + private int $itemCount = 0; + + /** + * Constructor. + * + * @param int $capacity Maximum number of items in the cache. Defaults to 512. * @since 25.0.0 */ public function __construct(int $capacity = 512) { $this->capacity = $capacity; } + // + // Cache Operations + // + /** - * @inheritdoc + * Checks if the cache contains the specified key. + * + * @param string $key + * @return bool True if the key exists, false otherwise. * @since 25.0.0 */ public function hasKey($key): bool { @@ -40,7 +113,10 @@ class CappedMemoryCache implements ICache, \ArrayAccess { } /** - * @return ?T + * Retrieves the value for the specified key from the cache. + * + * @param string $key + * @return T|null The value, or null if the key does not exist. * @since 25.0.0 */ public function get($key) { @@ -48,41 +124,68 @@ class CappedMemoryCache implements ICache, \ArrayAccess { } /** - * @inheritdoc + * Adds or updates a value in the cache. + * If capacity is exceeded, evicts the oldest entries. + * * @param string $key * @param T $value - * @param int $ttl + * @param int $ttl Unused. Included for interface compatibility. + * @return bool True on success. * @since 25.0.0 - * @return bool */ public function set($key, $value, $ttl = 0): bool { - if (is_null($key)) { - $this->cache[] = $value; - } else { + $isNewKey = !isset($this->cache[$key]) || $key === null; + + if ($key !== null) { $this->cache[$key] = $value; + } else { // for offsetSet() when $key is null + $this->cache[] = $value; + } + + if ($isNewKey) { + $this->itemCount++; } $this->garbageCollect(); return true; } /** + * Removes the specified key from the cache. + * + * @param string $key + * @return bool True on success. * @since 25.0.0 */ public function remove($key): bool { - unset($this->cache[$key]); + if (isset($this->cache[$key])) { + unset($this->cache[$key]); + $this->itemCount--; + } return true; } /** - * @inheritdoc + * Clears all cache entries. + * + * @param string $prefix Unused. Included for interface compatibility. + * @return bool True on success. * @since 25.0.0 */ public function clear($prefix = ''): bool { $this->cache = []; + $this->itemCount = 0; return true; } + // + // ArrayAccess Support + // + /** + * Determines if an offset exists in the cache. + * + * @param string $offset + * @return bool * @since 25.0.0 */ public function offsetExists($offset): bool { @@ -90,17 +193,21 @@ class CappedMemoryCache implements ICache, \ArrayAccess { } /** - * @inheritdoc - * @return T + * Retrieves the value at the specified offset. + * + * @param string $offset + * @return T|null * @since 25.0.0 */ #[\ReturnTypeWillChange] public function &offsetGet($offset) { + // TODO: Any side effects with the new GC tracking? return $this->cache[$offset]; } /** - * @inheritdoc + * Sets the value at the specified offset. + * * @param string $offset * @param T $value * @since 25.0.0 @@ -110,35 +217,51 @@ class CappedMemoryCache implements ICache, \ArrayAccess { } /** - * @inheritdoc + * Unsets the value at the specified offset. + * + * @param string $offset * @since 25.0.0 */ public function offsetUnset($offset): void { $this->remove($offset); } + // + // Utilities + // + /** - * @return T[] + * Returns all cache data as an associative array. + * + * @return array * @since 25.0.0 */ public function getData(): array { return $this->cache; } - /** + * Removes oldest entries if cache exceeds its capacity. + * + * @return void * @since 25.0.0 */ private function garbageCollect(): void { - while (count($this->cache) > $this->capacity) { + while ($this->itemCount > $this->capacity) { reset($this->cache); $key = key($this->cache); $this->remove($key); } } + // + // Static Methods + // + /** - * @inheritdoc + * Indicates if this cache implementation is available. + * + * @return bool Always returns true. * @since 25.0.0 */ public static function isAvailable(): bool {