diff options
Diffstat (limited to 'vendor/react/cache')
-rw-r--r-- | vendor/react/cache/LICENSE | 21 | ||||
-rw-r--r-- | vendor/react/cache/composer.json | 41 | ||||
-rw-r--r-- | vendor/react/cache/src/ArrayCache.php | 181 | ||||
-rw-r--r-- | vendor/react/cache/src/CacheInterface.php | 194 |
4 files changed, 437 insertions, 0 deletions
diff --git a/vendor/react/cache/LICENSE b/vendor/react/cache/LICENSE new file mode 100644 index 0000000..d6f8901 --- /dev/null +++ b/vendor/react/cache/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2012 Christian Lück, Cees-Jan Kiewiet, Jan Sorgalla, Chris Boden, Igor Wiedler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/react/cache/composer.json b/vendor/react/cache/composer.json new file mode 100644 index 0000000..ad0d9fe --- /dev/null +++ b/vendor/react/cache/composer.json @@ -0,0 +1,41 @@ +{ + "name": "react/cache", + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": ["cache", "caching", "promise", "ReactPHP"], + "license": "MIT", + "authors": [ + { + "name": "Christian Lück", + "homepage": "https://clue.engineering/", + "email": "christian@clue.engineering" + }, + { + "name": "Cees-Jan Kiewiet", + "homepage": "https://wyrihaximus.net/", + "email": "reactphp@ceesjankiewiet.nl" + }, + { + "name": "Jan Sorgalla", + "homepage": "https://sorgalla.com/", + "email": "jsorgalla@gmail.com" + }, + { + "name": "Chris Boden", + "homepage": "https://cboden.dev/", + "email": "cboden@gmail.com" + } + ], + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "autoload": { + "psr-4": { "React\\Cache\\": "src/" } + }, + "autoload-dev": { + "psr-4": { "React\\Tests\\Cache\\": "tests/" } + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" + } +} diff --git a/vendor/react/cache/src/ArrayCache.php b/vendor/react/cache/src/ArrayCache.php new file mode 100644 index 0000000..81f25ef --- /dev/null +++ b/vendor/react/cache/src/ArrayCache.php @@ -0,0 +1,181 @@ +<?php + +namespace React\Cache; + +use React\Promise; +use React\Promise\PromiseInterface; + +class ArrayCache implements CacheInterface +{ + private $limit; + private $data = array(); + private $expires = array(); + private $supportsHighResolution; + + /** + * The `ArrayCache` provides an in-memory implementation of the [`CacheInterface`](#cacheinterface). + * + * ```php + * $cache = new ArrayCache(); + * + * $cache->set('foo', 'bar'); + * ``` + * + * Its constructor accepts an optional `?int $limit` parameter to limit the + * maximum number of entries to store in the LRU cache. If you add more + * entries to this instance, it will automatically take care of removing + * the one that was least recently used (LRU). + * + * For example, this snippet will overwrite the first value and only store + * the last two entries: + * + * ```php + * $cache = new ArrayCache(2); + * + * $cache->set('foo', '1'); + * $cache->set('bar', '2'); + * $cache->set('baz', '3'); + * ``` + * + * This cache implementation is known to rely on wall-clock time to schedule + * future cache expiration times when using any version before PHP 7.3, + * because a monotonic time source is only available as of PHP 7.3 (`hrtime()`). + * While this does not affect many common use cases, this is an important + * distinction for programs that rely on a high time precision or on systems + * that are subject to discontinuous time adjustments (time jumps). + * This means that if you store a cache item with a TTL of 30s on PHP < 7.3 + * and then adjust your system time forward by 20s, the cache item may + * expire in 10s. See also [`set()`](#set) for more details. + * + * @param int|null $limit maximum number of entries to store in the LRU cache + */ + public function __construct($limit = null) + { + $this->limit = $limit; + + // prefer high-resolution timer, available as of PHP 7.3+ + $this->supportsHighResolution = \function_exists('hrtime'); + } + + public function get($key, $default = null) + { + // delete key if it is already expired => below will detect this as a cache miss + if (isset($this->expires[$key]) && $this->now() - $this->expires[$key] > 0) { + unset($this->data[$key], $this->expires[$key]); + } + + if (!\array_key_exists($key, $this->data)) { + return Promise\resolve($default); + } + + // remove and append to end of array to keep track of LRU info + $value = $this->data[$key]; + unset($this->data[$key]); + $this->data[$key] = $value; + + return Promise\resolve($value); + } + + public function set($key, $value, $ttl = null) + { + // unset before setting to ensure this entry will be added to end of array (LRU info) + unset($this->data[$key]); + $this->data[$key] = $value; + + // sort expiration times if TTL is given (first will expire first) + unset($this->expires[$key]); + if ($ttl !== null) { + $this->expires[$key] = $this->now() + $ttl; + \asort($this->expires); + } + + // ensure size limit is not exceeded or remove first entry from array + if ($this->limit !== null && \count($this->data) > $this->limit) { + // first try to check if there's any expired entry + // expiration times are sorted, so we can simply look at the first one + \reset($this->expires); + $key = \key($this->expires); + + // check to see if the first in the list of expiring keys is already expired + // if the first key is not expired, we have to overwrite by using LRU info + if ($key === null || $this->now() - $this->expires[$key] < 0) { + \reset($this->data); + $key = \key($this->data); + } + unset($this->data[$key], $this->expires[$key]); + } + + return Promise\resolve(true); + } + + public function delete($key) + { + unset($this->data[$key], $this->expires[$key]); + + return Promise\resolve(true); + } + + public function getMultiple(array $keys, $default = null) + { + $values = array(); + + foreach ($keys as $key) { + $values[$key] = $this->get($key, $default); + } + + return Promise\all($values); + } + + public function setMultiple(array $values, $ttl = null) + { + foreach ($values as $key => $value) { + $this->set($key, $value, $ttl); + } + + return Promise\resolve(true); + } + + public function deleteMultiple(array $keys) + { + foreach ($keys as $key) { + unset($this->data[$key], $this->expires[$key]); + } + + return Promise\resolve(true); + } + + public function clear() + { + $this->data = array(); + $this->expires = array(); + + return Promise\resolve(true); + } + + public function has($key) + { + // delete key if it is already expired + if (isset($this->expires[$key]) && $this->now() - $this->expires[$key] > 0) { + unset($this->data[$key], $this->expires[$key]); + } + + if (!\array_key_exists($key, $this->data)) { + return Promise\resolve(false); + } + + // remove and append to end of array to keep track of LRU info + $value = $this->data[$key]; + unset($this->data[$key]); + $this->data[$key] = $value; + + return Promise\resolve(true); + } + + /** + * @return float + */ + private function now() + { + return $this->supportsHighResolution ? \hrtime(true) * 1e-9 : \microtime(true); + } +} diff --git a/vendor/react/cache/src/CacheInterface.php b/vendor/react/cache/src/CacheInterface.php new file mode 100644 index 0000000..8e51c19 --- /dev/null +++ b/vendor/react/cache/src/CacheInterface.php @@ -0,0 +1,194 @@ +<?php + +namespace React\Cache; + +use React\Promise\PromiseInterface; + +interface CacheInterface +{ + /** + * Retrieves an item from the cache. + * + * This method will resolve with the cached value on success or with the + * given `$default` value when no item can be found or when an error occurs. + * Similarly, an expired cache item (once the time-to-live is expired) is + * considered a cache miss. + * + * ```php + * $cache + * ->get('foo') + * ->then('var_dump'); + * ``` + * + * This example fetches the value of the key `foo` and passes it to the + * `var_dump` function. You can use any of the composition provided by + * [promises](https://github.com/reactphp/promise). + * + * @param string $key + * @param mixed $default Default value to return for cache miss or null if not given. + * @return PromiseInterface<mixed> + */ + public function get($key, $default = null); + + /** + * Stores an item in the cache. + * + * This method will resolve with `true` on success or `false` when an error + * occurs. If the cache implementation has to go over the network to store + * it, it may take a while. + * + * The optional `$ttl` parameter sets the maximum time-to-live in seconds + * for this cache item. If this parameter is omitted (or `null`), the item + * will stay in the cache for as long as the underlying implementation + * supports. Trying to access an expired cache item results in a cache miss, + * see also [`get()`](#get). + * + * ```php + * $cache->set('foo', 'bar', 60); + * ``` + * + * This example eventually sets the value of the key `foo` to `bar`. If it + * already exists, it is overridden. + * + * This interface does not enforce any particular TTL resolution, so special + * care may have to be taken if you rely on very high precision with + * millisecond accuracy or below. Cache implementations SHOULD work on a + * best effort basis and SHOULD provide at least second accuracy unless + * otherwise noted. Many existing cache implementations are known to provide + * microsecond or millisecond accuracy, but it's generally not recommended + * to rely on this high precision. + * + * This interface suggests that cache implementations SHOULD use a monotonic + * time source if available. Given that a monotonic time source is only + * available as of PHP 7.3 by default, cache implementations MAY fall back + * to using wall-clock time. + * While this does not affect many common use cases, this is an important + * distinction for programs that rely on a high time precision or on systems + * that are subject to discontinuous time adjustments (time jumps). + * This means that if you store a cache item with a TTL of 30s and then + * adjust your system time forward by 20s, the cache item SHOULD still + * expire in 30s. + * + * @param string $key + * @param mixed $value + * @param ?float $ttl + * @return PromiseInterface<bool> Returns a promise which resolves to `true` on success or `false` on error + */ + public function set($key, $value, $ttl = null); + + /** + * Deletes an item from the cache. + * + * This method will resolve with `true` on success or `false` when an error + * occurs. When no item for `$key` is found in the cache, it also resolves + * to `true`. If the cache implementation has to go over the network to + * delete it, it may take a while. + * + * ```php + * $cache->delete('foo'); + * ``` + * + * This example eventually deletes the key `foo` from the cache. As with + * `set()`, this may not happen instantly and a promise is returned to + * provide guarantees whether or not the item has been removed from cache. + * + * @param string $key + * @return PromiseInterface<bool> Returns a promise which resolves to `true` on success or `false` on error + */ + public function delete($key); + + /** + * Retrieves multiple cache items by their unique keys. + * + * This method will resolve with an array of cached values on success or with the + * given `$default` value when an item can not be found or when an error occurs. + * Similarly, an expired cache item (once the time-to-live is expired) is + * considered a cache miss. + * + * ```php + * $cache->getMultiple(array('name', 'age'))->then(function (array $values) { + * $name = $values['name'] ?? 'User'; + * $age = $values['age'] ?? 'n/a'; + * + * echo $name . ' is ' . $age . PHP_EOL; + * }); + * ``` + * + * This example fetches the cache items for the `name` and `age` keys and + * prints some example output. You can use any of the composition provided + * by [promises](https://github.com/reactphp/promise). + * + * @param string[] $keys A list of keys that can obtained in a single operation. + * @param mixed $default Default value to return for keys that do not exist. + * @return PromiseInterface<array> Returns a promise which resolves to an `array` of cached values + */ + public function getMultiple(array $keys, $default = null); + + /** + * Persists a set of key => value pairs in the cache, with an optional TTL. + * + * This method will resolve with `true` on success or `false` when an error + * occurs. If the cache implementation has to go over the network to store + * it, it may take a while. + * + * The optional `$ttl` parameter sets the maximum time-to-live in seconds + * for these cache items. If this parameter is omitted (or `null`), these items + * will stay in the cache for as long as the underlying implementation + * supports. Trying to access an expired cache items results in a cache miss, + * see also [`get()`](#get). + * + * ```php + * $cache->setMultiple(array('foo' => 1, 'bar' => 2), 60); + * ``` + * + * This example eventually sets the list of values - the key `foo` to 1 value + * and the key `bar` to 2. If some of the keys already exist, they are overridden. + * + * @param array $values A list of key => value pairs for a multiple-set operation. + * @param ?float $ttl Optional. The TTL value of this item. + * @return PromiseInterface<bool> Returns a promise which resolves to `true` on success or `false` on error + */ + public function setMultiple(array $values, $ttl = null); + + /** + * Deletes multiple cache items in a single operation. + * + * @param string[] $keys A list of string-based keys to be deleted. + * @return PromiseInterface<bool> Returns a promise which resolves to `true` on success or `false` on error + */ + public function deleteMultiple(array $keys); + + /** + * Wipes clean the entire cache. + * + * @return PromiseInterface<bool> Returns a promise which resolves to `true` on success or `false` on error + */ + public function clear(); + + /** + * Determines whether an item is present in the cache. + * + * This method will resolve with `true` on success or `false` when no item can be found + * or when an error occurs. Similarly, an expired cache item (once the time-to-live + * is expired) is considered a cache miss. + * + * ```php + * $cache + * ->has('foo') + * ->then('var_dump'); + * ``` + * + * This example checks if the value of the key `foo` is set in the cache and passes + * the result to the `var_dump` function. You can use any of the composition provided by + * [promises](https://github.com/reactphp/promise). + * + * NOTE: It is recommended that has() is only to be used for cache warming type purposes + * and not to be used within your live applications operations for get/set, as this method + * is subject to a race condition where your has() will return true and immediately after, + * another script can remove it making the state of your app out of date. + * + * @param string $key The cache item key. + * @return PromiseInterface<bool> Returns a promise which resolves to `true` on success or `false` on error + */ + public function has($key); +} |