/**
* @brief Returns all the cache keys sorted alphabetically
*
+ * @param string $prefix Prefix of the keys (optional)
+ *
* @return array|null Null if the driver doesn't support this feature
*/
- public static function getAllKeys()
+ public static function getAllKeys($prefix = null)
{
$time = microtime(true);
- $return = self::getDriver()->getAllKeys();
-
- // Keys are prefixed with the node hostname, let's remove it
- array_walk($return, function (&$value) {
- $value = preg_replace('/^' . self::getApp()->get_hostname() . ':/', '', $value);
- });
-
- sort($return);
+ $return = self::getDriver()->getAllKeys($prefix);
self::getApp()->save_timestamp($time, 'cache');
* @param string $key The original key
* @return string The cache key used for the cache
*/
- protected function getCacheKey($key) {
+ protected function getCacheKey($key)
+ {
// We fetch with the hostname as key to avoid problems with other applications
return self::getApp()->get_hostname() . ":" . $key;
}
+
+ /**
+ * @param array $keys A list of cached keys
+ * @return array A list of original keys
+ */
+ protected function getOriginalKeys($keys)
+ {
+ if (empty($keys)) {
+ return [];
+ } else {
+ // Keys are prefixed with the node hostname, let's remove it
+ array_walk($keys, function (&$value) {
+ $value = preg_replace('/^' . self::getApp()->get_hostname() . ':/', '', $value);
+ });
+
+ sort($keys);
+
+ return $keys;
+ }
+ }
+
+ /**
+ * Filters a list for a given prefix
+ *
+ * @param array $list the list
+ * @param string|null $prefix the prefix
+ *
+ * @return array the filtered list
+ */
+ protected function filterPrefix($list, $prefix = null)
+ {
+ if (empty($prefix)) {
+ return array_keys($list);
+ } else {
+ $result = [];
+
+ foreach (array_keys($list) as $key) {
+ if (strpos($key, $prefix) === 0) {
+ array_push($result, $key);
+ }
+ }
+
+ return $result;
+ }
+
+ }
}
/**
* (@inheritdoc)
*/
- public function getAllKeys()
+ public function getAllKeys($prefix = null)
{
- return array_keys($this->cachedData);
+ return $this->filterPrefix($this->cachedData, $prefix);
}
/**
/**
* (@inheritdoc)
*/
- public function getAllKeys()
+ public function getAllKeys($prefix = null)
{
- $stmt = DBA::select('cache', ['k'], ['`expires` >= ?', DateTimeFormat::utcNow()]);
+ if (empty($prefix)) {
+ $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
+ } else {
+ $where = ['`expires` >= ? AND k LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
+ }
+
+ $stmt = DBA::select('cache', ['k'], $where);
+
+ $list = [];
+ while ($key = DBA::fetch($stmt)) {
+ array_push($list, $key['k']);
+ }
+ DBA::close($stmt);
- return DBA::toArray($stmt);
+ return $list;
}
/**
/**
* Lists all cache keys
*
+ * @param string prefix optional a prefix to search
+ *
* @return array|null Null if it isn't supported by the cache driver
*/
- public function getAllKeys();
+ public function getAllKeys($prefix = null);
/**
* Fetches cached data according to the key
/**
* (@inheritdoc)
*/
- public function getAllKeys()
+ public function getAllKeys($prefix = null)
{
$list = [];
$allSlabs = $this->memcache->getExtendedStats('slabs');
}
}
- return $list;
+ $list = $this->getOriginalKeys($list);
+
+ return $this->filterPrefix($list, $prefix);
}
/**
use Friendica\Core\Cache;
use Exception;
+use Friendica\Network\HTTPException\InternalServerErrorException;
use Memcached;
/**
$this->memcached = new Memcached();
+
+ $this->memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, false);
+
array_walk($memcached_hosts, function (&$value) {
if (is_string($value)) {
$value = array_map('trim', explode(',', $value));
/**
* (@inheritdoc)
*/
- public function getAllKeys()
+ public function getAllKeys($prefix = null)
{
- return $this->memcached->getAllKeys();
+ // Doesn't work because of https://github.com/php-memcached-dev/php-memcached/issues/367
+ // returns everytime an empty array
+ throw new InternalServerErrorException('getAllKeys for Memcached not supported yet');
+
+ $list = $this->getOriginalKeys($this->memcached->getAllKeys());
+
+ return $this->filterPrefix($list, $prefix);
}
/**
/**
* (@inheritdoc)
*/
- public function getAllKeys()
+ public function getAllKeys($prefix = null)
{
- return null;
+ if (empty($prefix)) {
+ $search = '*';
+ } else {
+ $search = $prefix . '*';
+ }
+
+ $list = $this->redis->keys($this->getCacheKey($search));
+
+ return $this->getOriginalKeys($list);
}
/**
private function executeList()
{
$prefix = $this->getArgument(1);
- $keys = Core\Cache::getAllKeys();
+ $keys = Core\Cache::getAllKeys($prefix);
if (empty($prefix)) {
$this->out('Listing all cache keys:');
class ArrayCacheDriverTest extends MemoryCacheTest
{
- /**
- * @var \Friendica\Core\Cache\IMemoryCacheDriver
- */
- private $cache;
-
protected function getInstance()
{
$this->cache = new ArrayCache();
namespace Friendica\Test\src\Core\Cache;
+use Friendica\Core\Cache\MemcachedCacheDriver;
use Friendica\Core\Config;
use Friendica\Test\DatabaseTest;
use Friendica\Util\DateTimeFormat;
*/
protected $instance;
+ /**
+ * @var \Friendica\Core\Cache\IMemoryCacheDriver
+ */
+ protected $cache;
+
+
abstract protected function getInstance();
protected function setUp()
Config::set('system', 'throttle_limit_week', 100);
Config::set('system', 'throttle_limit_month', 100);
Config::set('system', 'theme', 'system_theme');
+
+ $this->instance->clear(false);
}
/**
$received = $this->instance->get('objVal');
$this->assertEquals($value, $received, 'Value type changed from ' . gettype($value) . ' to ' . gettype($received));
}
+
+ /**
+ * @small
+ */
+ public function testGetAllKeys() {
+ if ($this->cache instanceof MemcachedCacheDriver) {
+ $this->markTestSkipped('Memcached doesn\'t support getAllKeys anymore');
+ }
+
+ $this->assertTrue($this->instance->set('value1', 'test'));
+ $this->assertTrue($this->instance->set('value2', 'test'));
+ $this->assertTrue($this->instance->set('test_value3', 'test'));
+
+ $list = $this->instance->getAllKeys();
+
+ $this->assertContains('value1', $list);
+ $this->assertContains('value2', $list);
+ $this->assertContains('test_value3', $list);
+
+ $list = $this->instance->getAllKeys('test');
+
+ $this->assertContains('test_value3', $list);
+ }
}
class DatabaseCacheDriverTest extends CacheTest
{
- /**
- * @var \Friendica\Core\Cache\IMemoryCacheDriver
- */
- private $cache;
-
protected function getInstance()
{
$this->cache = CacheDriverFactory::create('database');
*/
class MemcacheCacheDriverTest extends MemoryCacheTest
{
- /**
- * @var \Friendica\Core\Cache\IMemoryCacheDriver
- */
- private $cache;
-
protected function getInstance()
{
$this->cache = CacheDriverFactory::create('memcache');
*/
class MemcachedCacheDriverTest extends MemoryCacheTest
{
- /**
- * @var \Friendica\Core\Cache\IMemoryCacheDriver
- */
- private $cache;
-
protected function getInstance()
{
$this->cache = CacheDriverFactory::create('memcached');
*/
class RedisCacheDriverTest extends MemoryCacheTest
{
- /**
- * @var \Friendica\Core\Cache\IMemoryCacheDriver
- */
- private $cache;
-
protected function getInstance()
{
$this->cache = CacheDriverFactory::create('redis');