Commit d1136313 authored by Vincent Petry's avatar Vincent Petry Committed by GitHub

Merge pull request #27312 from owncloud/cache-getStorageById

cache getStorageById
parents 1661431d 62cebd5f
......@@ -31,9 +31,11 @@
namespace OCA\Files_Sharing\Tests;
use OC\Files\Cache\Storage;
use OC\Files\Filesystem;
use OCA\Files_Sharing\AppInfo\Application;
use OCA\Files_Sharing\SharedStorage;
use OCP\ICache;
/**
* Class TestCase
......@@ -187,6 +189,24 @@ abstract class TestCase extends \Test\TestCase {
$isInitialized->setAccessible(true);
$isInitialized->setValue($storage, false);
$isInitialized->setAccessible(false);
$storage = new \ReflectionClass(Storage::class);
$property = $storage->getProperty('localCache');
$property->setAccessible(true);
/** @var ICache $localCache */
$localCache = $property->getValue();
if ($localCache instanceof ICache) {
$localCache->clear();
}
$property->setAccessible(false);
$property = $storage->getProperty('distributedCache');
$property->setAccessible(true);
/** @var ICache $localCache */
$distributedCache = $property->getValue();
if ($distributedCache instanceof ICache) {
$distributedCache->clear();
}
$property->setAccessible(false);
}
/**
......
......@@ -543,11 +543,7 @@ class Cache implements ICache {
* remove all entries for files that are stored on the storage from the cache
*/
public function clear() {
$sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?';
$this->connection->executeQuery($sql, [$this->getNumericStorageId()]);
$sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?';
$this->connection->executeQuery($sql, [$this->storageId]);
Storage::remove($this->storageId);
}
/**
......
......@@ -26,6 +26,8 @@
*/
namespace OC\Files\Cache;
use OC\Cache\CappedMemoryCache;
use OCP\ICache;
/**
* Handle the mapping between the string and numeric storage ids
......@@ -42,6 +44,14 @@ class Storage {
private $storageId;
private $numericId;
/** @var CappedMemoryCache */
protected static $localCache = null;
/** @var ICache */
private static $distributedCache = null;
private static $distributedCacheTTL = 300; // 5 Min
/**
* @param \OC\Files\Storage\Storage|string $storage
* @param bool $isAvailable
......@@ -58,10 +68,27 @@ class Storage {
if ($row = self::getStorageById($this->storageId)) {
$this->numericId = (int)$row['numeric_id'];
} else {
self::unsetCache($this->storageId);
$connection = \OC::$server->getDatabaseConnection();
$available = $isAvailable ? 1 : 0;
if ($connection->insertIfNotExist('*PREFIX*storages', ['id' => $this->storageId, 'available' => $available])) {
$storageData = ['id' => $this->storageId, 'available' => $available];
if ($connection->insertIfNotExist('*PREFIX*storages', $storageData)) {
$this->numericId = (int)$connection->lastInsertId('*PREFIX*storages');
// add missing fields before caching
$storageData['numeric_id'] = $this->numericId;
$storageData['last_checked'] = null;
// local cache has been initialized by self::getStorageById
self::$localCache->set($this->storageId, $storageData);
// distributed cache may need initializing
self::getDistributedCache()->set(
$this->storageId, $storageData, self::$distributedCacheTTL
);
} else {
if ($row = self::getStorageById($this->storageId)) {
$this->numericId = (int)$row['numeric_id'];
......@@ -73,13 +100,67 @@ class Storage {
}
/**
* query the local cache, a distributed cache and the db for a storageid
* @param string $storageId
* @return array|null
* @return array|false
*/
public static function getStorageById($storageId) {
if (self::$localCache === null) {
self::$localCache = new CappedMemoryCache();
}
$result = self::$localCache->get($storageId);
if ($result === null) {
$result = self::getStorageByIdFromCache($storageId);
self::$localCache->set($storageId, $result);
}
return $result;
}
/**
* @return ICache
*/
private static function getDistributedCache() {
if (self::$distributedCache === null) {
self::$distributedCache =
\OC::$server->getMemCacheFactory()->create('getStorageById');
}
return self::$distributedCache;
}
/**
* query the distributed cache for a storageid
* @param string $storageId
* @return array|false
*/
private static function getStorageByIdFromCache($storageId) {
$result = self::getDistributedCache()->get($storageId);
if ($result === null) {
$result = self::getStorageByIdFromDb($storageId);
self::getDistributedCache()->set(
$storageId, $result, self::$distributedCacheTTL
);
}
return $result;
}
/**
* query the db for a storageid
* @param string $storageId
* @return array|false
*/
private static function getStorageByIdFromDb($storageId) {
$sql = 'SELECT * FROM `*PREFIX*storages` WHERE `id` = ?';
$result = \OC_DB::executeAudited($sql, [$storageId]);
return $result->fetchRow();
$resultSet = \OC_DB::executeAudited($sql, [$storageId]);
return $resultSet->fetchRow();
}
private static function unsetCache($storageId) {
// delete from local cache
if(self::$localCache !== null) {
self::$localCache->remove($storageId);
}
// delete from distributed cache
self::getDistributedCache()->remove($storageId);
}
/**
......@@ -155,6 +236,8 @@ class Storage {
* @param bool $isAvailable
*/
public function setAvailability($isAvailable) {
// delete from local cache
self::unsetCache($this->storageId);
$sql = 'UPDATE `*PREFIX*storages` SET `available` = ?, `last_checked` = ? WHERE `id` = ?';
$available = $isAvailable ? 1 : 0;
\OC_DB::executeAudited($sql, [$available, time(), $this->storageId]);
......@@ -181,6 +264,9 @@ class Storage {
$sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?';
\OC_DB::executeAudited($sql, [$storageId]);
// delete from local cache
self::unsetCache($storageId);
// delete from db
if (!is_null($numericId)) {
$sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?';
\OC_DB::executeAudited($sql, [$numericId]);
......
......@@ -23,6 +23,7 @@
*/
namespace Test\Files\External\Service;
use OC\Files\Cache\Storage;
use OC\Files\Filesystem;
use OC\Files\External\StorageConfig;
use OC\Files\External\Service\StoragesService;
......@@ -302,6 +303,7 @@ abstract class StoragesServiceTest extends TestCase {
->from('storages')
->where($qb->expr()->eq('numeric_id', $qb->expr()->literal($numericId)));
$this->assertCount($expectedCountAfterDeletion, $storageCheckQuery->execute()->fetchAll());
Storage::remove($rustyStorageId);
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment