mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 09:48:40 +00:00
Expand cache interface
This commit is contained in:
parent
291620b1f0
commit
0646bec94f
|
|
@ -39,6 +39,43 @@ interface ConnectionInterface extends DataStorageConnectionInterface
|
|||
*/
|
||||
public function set(int|string $key, mixed $value, int $expire = -1) : void;
|
||||
|
||||
/**
|
||||
* Increment value.
|
||||
*
|
||||
* @param int|string $key Unique cache key
|
||||
* @param int $value By value
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function increment(int|string $key, int $value = 1) : void;
|
||||
|
||||
/**
|
||||
* Decrement value.
|
||||
*
|
||||
* @param int|string $key Unique cache key
|
||||
* @param int $value By value
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function decrement(int|string $key, int $value = 1) : void;
|
||||
|
||||
/**
|
||||
* Rename cache key.
|
||||
*
|
||||
* @param int|string $old Unique cache key
|
||||
* @param int|string $new Unique cache key
|
||||
* @param int $expire Valid duration (in s). Negative expiration means no expiration.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function rename(int|string $old, int|string $new, int $expire = -1) : void;
|
||||
|
||||
/**
|
||||
* Adding new data if it doesn't exist.
|
||||
*
|
||||
|
|
@ -64,6 +101,30 @@ interface ConnectionInterface extends DataStorageConnectionInterface
|
|||
*/
|
||||
public function get(int|string $key, int $expire = -1) : mixed;
|
||||
|
||||
/**
|
||||
* Get cache by pattern.
|
||||
*
|
||||
* @param string $key Unique cache key
|
||||
* @param int $expire Valid duration (in s). In case the data needs to be newer than the defined expiration time. If the expiration date is larger than the defined expiration time and supposed to be expired it will not remove the outdated cache.
|
||||
*
|
||||
* @return array Cache values
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getLike(string $pattern, int $expire = -1) : array;
|
||||
|
||||
/**
|
||||
* Exists cache by key.
|
||||
*
|
||||
* @param int|string $key Unique cache key
|
||||
* @param int $expire Valid duration (in s). In case the data needs to be newer than the defined expiration time. If the expiration date is larger than the defined expiration time and supposed to be expired it will not remove the outdated cache.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function exists(int|string $key, int $expire = -1) : bool;
|
||||
|
||||
/**
|
||||
* Remove value by key.
|
||||
*
|
||||
|
|
@ -76,6 +137,18 @@ interface ConnectionInterface extends DataStorageConnectionInterface
|
|||
*/
|
||||
public function delete(int|string $key, int $expire = -1) : bool;
|
||||
|
||||
/**
|
||||
* Remove value by pattern.
|
||||
*
|
||||
* @param string $key Unique cache key
|
||||
* @param int $expire Valid duration (in s)
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function deleteLike(string $pattern, int $expire = -1) : bool;
|
||||
|
||||
/**
|
||||
* Removing all cache elements larger or equal to the expiration date. Call flushAll for removing persistent cache elements (expiration is negative) as well.
|
||||
*
|
||||
|
|
@ -109,6 +182,18 @@ interface ConnectionInterface extends DataStorageConnectionInterface
|
|||
*/
|
||||
public function replace(int|string $key, mixed $value, int $expire = -1) : bool;
|
||||
|
||||
/**
|
||||
* Updating expire.
|
||||
*
|
||||
* @param int|string $key Unique cache key
|
||||
* @param int $expire Valid duration (in s)
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function updateExpire(int|string $key, int $expire = -1) : bool;
|
||||
|
||||
/**
|
||||
* Requesting cache stats.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -155,7 +155,14 @@ final class FileCache extends ConnectionAbstract
|
|||
|
||||
$path = Directory::sanitize($key, self::SANITIZE);
|
||||
|
||||
File::put($this->con . '/' . \trim($path, '/') . '.cache', $this->build($value, $expire));
|
||||
$fp = \fopen($this->con . '/' . \trim($path, '/') . '.cache', 'w+');
|
||||
if (\flock($fp, \LOCK_EX)) {
|
||||
\ftruncate($fp, 0);
|
||||
\fwrite($fp, $this->build($value, $expire));
|
||||
\fflush($fp);
|
||||
\flock($fp, \LOCK_UN);
|
||||
}
|
||||
\fclose($fp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -170,7 +177,14 @@ final class FileCache extends ConnectionAbstract
|
|||
$path = $this->getPath($key);
|
||||
|
||||
if (!File::exists($path)) {
|
||||
File::put($path, $this->build($value, $expire));
|
||||
$fp = \fopen($path, 'w+');
|
||||
if (\flock($fp, \LOCK_EX)) {
|
||||
\ftruncate($fp, 0);
|
||||
\fwrite($fp, $this->build($value, $expire));
|
||||
\fflush($fp);
|
||||
\flock($fp, \LOCK_UN);
|
||||
}
|
||||
\fclose($fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -377,18 +391,254 @@ final class FileCache extends ConnectionAbstract
|
|||
$cacheExpire = $this->getExpire($raw);
|
||||
$cacheExpire = ($cacheExpire === -1) ? $created : (int) $cacheExpire;
|
||||
|
||||
if ($cacheExpire >= 0 && $created + $cacheExpire < $now) {
|
||||
return $this->delete($key);
|
||||
}
|
||||
if (($cacheExpire >= 0 && $created + $cacheExpire < $now)
|
||||
|| ($cacheExpire >= 0 && \abs($now - $created) > $expire)
|
||||
) {
|
||||
File::delete($path);
|
||||
|
||||
if ($cacheExpire >= 0 && \abs($now - $created) > $expire) {
|
||||
return $this->delete($key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(int|string $key, int $expire = -1) : bool
|
||||
{
|
||||
if ($this->status !== CacheStatus::OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$path = $this->getPath($key);
|
||||
if (!File::exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$created = File::created($path)->getTimestamp();
|
||||
$now = \time();
|
||||
|
||||
if ($expire >= 0 && $created + $expire < $now) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$raw = \file_get_contents($path);
|
||||
if ($raw === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = (int) $raw[0];
|
||||
$expireStart = (int) \strpos($raw, self::DELIM);
|
||||
$expireEnd = (int) \strpos($raw, self::DELIM, $expireStart + 1);
|
||||
|
||||
if ($expireStart < 0 || $expireEnd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1));
|
||||
$cacheExpire = ($cacheExpire === -1) ? $created : (int) $cacheExpire;
|
||||
|
||||
if ($cacheExpire >= 0 && $created + $cacheExpire + ($expire > 0 ? $expire : 0) < $now) {
|
||||
File::delete($path);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function increment(int|string $key, int $value = 1) : void
|
||||
{
|
||||
$path = $this->getPath($key);
|
||||
if (!File::exists($path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$created = File::created($path)->getTimestamp();
|
||||
$now = \time();
|
||||
|
||||
if ($expire >= 0 && $created + $expire < $now) {
|
||||
return;
|
||||
}
|
||||
|
||||
$raw = \file_get_contents($path);
|
||||
if ($raw === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$type = (int) $raw[0];
|
||||
$expireStart = (int) \strpos($raw, self::DELIM);
|
||||
$expireEnd = (int) \strpos($raw, self::DELIM, $expireStart + 1);
|
||||
|
||||
if ($expireStart < 0 || $expireEnd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1));
|
||||
$cacheExpire = ($cacheExpire === -1) ? $created : (int) $cacheExpire;
|
||||
|
||||
$val = $this->reverseValue($type, $raw, $expireEnd);
|
||||
$this->set($key, $val + $value, $cacheExpire);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decrement(int|string $key, int $value = 1) : void
|
||||
{
|
||||
$path = $this->getPath($key);
|
||||
if (!File::exists($path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$created = File::created($path)->getTimestamp();
|
||||
$now = \time();
|
||||
|
||||
if ($expire >= 0 && $created + $expire < $now) {
|
||||
return;
|
||||
}
|
||||
|
||||
$raw = \file_get_contents($path);
|
||||
if ($raw === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$type = (int) $raw[0];
|
||||
$expireStart = (int) \strpos($raw, self::DELIM);
|
||||
$expireEnd = (int) \strpos($raw, self::DELIM, $expireStart + 1);
|
||||
|
||||
if ($expireStart < 0 || $expireEnd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1));
|
||||
$cacheExpire = ($cacheExpire === -1) ? $created : (int) $cacheExpire;
|
||||
|
||||
$val = $this->reverseValue($type, $raw, $expireEnd);
|
||||
$this->set($key, $val - $value, $cacheExpire);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rename(int|string $old, int|string $new, int $expire = -1) : void
|
||||
{
|
||||
$value = $this->get($old);
|
||||
$this->set($new, $value, $expire);
|
||||
$this->delete($old);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLike(string $pattern, int $expire = -1) : array
|
||||
{
|
||||
if ($this->status !== CacheStatus::OK) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$files = Directory::list($this->con . '/', $pattern . '\.cache', true);
|
||||
$values = [];
|
||||
|
||||
foreach ($files as $path) {
|
||||
$path = $this->con . '/' . $path;
|
||||
$created = File::created($path)->getTimestamp();
|
||||
$now = \time();
|
||||
|
||||
if ($expire >= 0 && $created + $expire < $now) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$raw = \file_get_contents($path);
|
||||
if ($raw === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$type = (int) $raw[0];
|
||||
$expireStart = (int) \strpos($raw, self::DELIM);
|
||||
$expireEnd = (int) \strpos($raw, self::DELIM, $expireStart + 1);
|
||||
|
||||
if ($expireStart < 0 || $expireEnd < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1));
|
||||
$cacheExpire = ($cacheExpire === -1) ? $created : (int) $cacheExpire;
|
||||
|
||||
if ($cacheExpire >= 0 && $created + $cacheExpire + ($expire > 0 ? $expire : 0) < $now) {
|
||||
File::delete($path);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$values[] = $this->reverseValue($type, $raw, $expireEnd);
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteLike(string $pattern, int $expire = -1) : bool
|
||||
{
|
||||
if ($this->status !== CacheStatus::OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$files = Directory::list($this->con . '/', $pattern . '\.cache', true);
|
||||
|
||||
foreach ($files as $path) {
|
||||
$path = $this->con . '/' . $path;
|
||||
|
||||
if ($expire < 0) {
|
||||
File::delete($path);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($expire >= 0) {
|
||||
$created = File::created($path)->getTimestamp();
|
||||
$now = \time();
|
||||
$raw = \file_get_contents($path);
|
||||
|
||||
if ($raw === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cacheExpire = $this->getExpire($raw);
|
||||
$cacheExpire = ($cacheExpire === -1) ? $created : (int) $cacheExpire;
|
||||
|
||||
if (($cacheExpire >= 0 && $created + $cacheExpire < $now)
|
||||
|| ($cacheExpire >= 0 && \abs($now - $created) > $expire)
|
||||
) {
|
||||
File::delete($path);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function updateExpire(int|string $key, int $expire = -1) : bool
|
||||
{
|
||||
$value = $this->get($key);
|
||||
$this->delete($key);
|
||||
$this->set($key, $value, $expire);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
@ -427,7 +677,14 @@ final class FileCache extends ConnectionAbstract
|
|||
$path = $this->getPath($key);
|
||||
|
||||
if (File::exists($path)) {
|
||||
File::put($path, $this->build($value, $expire));
|
||||
$fp = \fopen($path, 'w+');
|
||||
if (\flock($fp, \LOCK_EX)) {
|
||||
\ftruncate($fp, 0);
|
||||
\fwrite($fp, $this->build($value, $expire));
|
||||
\fflush($fp);
|
||||
\flock($fp, \LOCK_UN);
|
||||
}
|
||||
\fclose($fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,6 +139,103 @@ final class MemCached extends ConnectionAbstract
|
|||
return $this->con->delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(int|string $key, int $expire = -1) : bool
|
||||
{
|
||||
if ($this->status !== CacheStatus::OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->con->get($key) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function increment(int|string $key, int $value = 1) : void
|
||||
{
|
||||
$this->con->increment($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decrement(int|string $key, int $value = 1) : void
|
||||
{
|
||||
$this->con->decrement($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rename(int|string $old, int|string $new, int $expire = -1) : void
|
||||
{
|
||||
$value = $this->get($old);
|
||||
$this->set($new, $value, $expire);
|
||||
$this->delete($old);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLike(string $pattern, int $expire = -1) : array
|
||||
{
|
||||
if ($this->status !== CacheStatus::OK) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$keys = $this->con->getAllKeys();
|
||||
$values = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (\preg_match($key, $key) === 1) {
|
||||
$result = $this->con->get($key);
|
||||
if (\is_string($result)) {
|
||||
$type = (int) $result[0];
|
||||
$start = (int) \strpos($result, self::DELIM);
|
||||
$result = $this->reverseValue($type, $result, $start);
|
||||
}
|
||||
|
||||
$values[] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteLike(string $pattern, int $expire = -1) : bool
|
||||
{
|
||||
if ($this->status !== CacheStatus::OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$keys = $this->con->getAllKeys();
|
||||
foreach ($keys as $key) {
|
||||
if (\preg_match($key, $key) === 1) {
|
||||
$this->con->delete($key);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function updateExpire(int|string $key, int $expire = -1) : bool
|
||||
{
|
||||
if ($expire > 0) {
|
||||
$this->con->touch($key, $expire);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -101,4 +101,43 @@ final class NullCache extends ConnectionAbstract
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(int|string $key, int $expire = -1) : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rename(int|string $old, int|string $new, int $expire = -1) : void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLike(string $pattern, int $expire = -1) : array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteLike(string $pattern, int $expire = -1) : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function updateExpire(int|string $key, int $expire = -1) : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,105 @@ final class RedisCache extends ConnectionAbstract
|
|||
return $this->con->del($key) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists(int|string $key, int $expire = -1) : bool
|
||||
{
|
||||
if ($this->status !== CacheStatus::OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->con->exists($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function increment(int|string $key, int $value = 1) : void
|
||||
{
|
||||
$this->con->incrBy($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decrement(int|string $key, int $value = 1) : void
|
||||
{
|
||||
$this->con->decrBy($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rename(int|string $old, int|string $new, int $expire = -1) : void
|
||||
{
|
||||
$this->con->rename($old, $new);
|
||||
|
||||
if ($expire > 0) {
|
||||
$this->con->expire($new, $expire);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLike(string $pattern, int $expire = -1) : array
|
||||
{
|
||||
if ($this->status !== CacheStatus::OK) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$keys = $this->con->keys('*');
|
||||
$values = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (\preg_match($key, $key) === 1) {
|
||||
$result = $this->con->get($key);
|
||||
if (\is_string($result)) {
|
||||
$type = (int) $result[0];
|
||||
$start = (int) \strpos($result, self::DELIM);
|
||||
$result = $this->reverseValue($type, $result, $start);
|
||||
}
|
||||
|
||||
$values[] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteLike(string $pattern, int $expire = -1) : bool
|
||||
{
|
||||
if ($this->status !== CacheStatus::OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$keys = $this->con->keys('*');
|
||||
foreach ($keys as $key) {
|
||||
if (\preg_match($key, $key) === 1) {
|
||||
$this->con->del($key);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function updateExpire(int|string $key, int $expire = -1) : bool
|
||||
{
|
||||
if ($expire > 0) {
|
||||
$this->con->expire($key, $expire);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user