diff options
author | Joas Schilling <213943+nickvergessen@users.noreply.github.com> | 2018-12-17 15:11:28 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-17 15:11:28 +0100 |
commit | 6788e6e75cca95357a64202d331bf61e975df7d3 (patch) | |
tree | ef68a9d86f6c9043a47cadd7aadb3a73913b0d0f /lib | |
parent | 2d07c58f27adf5458dab52c9445d9000c9174f8a (diff) | |
parent | 036475fc91ea913eb4ed4ee14d45915d2bfeb8c6 (diff) | |
download | nextcloud-server-6788e6e75cca95357a64202d331bf61e975df7d3.tar.gz nextcloud-server-6788e6e75cca95357a64202d331bf61e975df7d3.zip |
Merge pull request #12883 from nextcloud/appdata-performance
try to grab the appdata folder directly without going trough the whole tree
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/Files/AppData/AppData.php | 88 | ||||
-rw-r--r-- | lib/private/Files/AppData/Factory.php | 7 |
2 files changed, 69 insertions, 26 deletions
diff --git a/lib/private/Files/AppData/AppData.php b/lib/private/Files/AppData/AppData.php index e25bf450446..3d098ad98ca 100644 --- a/lib/private/Files/AppData/AppData.php +++ b/lib/private/Files/AppData/AppData.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace OC\Files\AppData; +use OC\Cache\CappedMemoryCache; use OC\Files\SimpleFS\SimpleFolder; use OCP\Files\IAppData; use OCP\Files\IRootFolder; @@ -48,6 +49,9 @@ class AppData implements IAppData { /** @var Folder */ private $folder; + /** @var (ISimpleFolder|NotFoundException)[]|CappedMemoryCache */ + private $folders; + /** * AppData constructor. * @@ -62,6 +66,32 @@ class AppData implements IAppData { $this->rootFolder = $rootFolder; $this->config = $systemConfig; $this->appId = $appId; + $this->folders = new CappedMemoryCache(); + } + + private function getAppDataFolderName() { + $instanceId = $this->config->getValue('instanceid', null); + if ($instanceId === null) { + throw new \RuntimeException('no instance id!'); + } + + return 'appdata_' . $instanceId; + } + + private function getAppDataRootFolder(): Folder { + $name = $this->getAppDataFolderName(); + + try { + /** @var Folder $node */ + $node = $this->rootFolder->get($name); + return $node; + } catch (NotFoundException $e) { + try { + return $this->rootFolder->newFolder($name); + } catch (NotPermittedException $e) { + throw new \RuntimeException('Could not get appdata folder'); + } + } } /** @@ -70,56 +100,64 @@ class AppData implements IAppData { */ private function getAppDataFolder(): Folder { if ($this->folder === null) { - $instanceId = $this->config->getValue('instanceid', null); - if ($instanceId === null) { - throw new \RuntimeException('no instance id!'); - } - - $name = 'appdata_' . $instanceId; + $name = $this->getAppDataFolderName(); try { - $appDataFolder = $this->rootFolder->get($name); + $this->folder = $this->rootFolder->get($name . '/' . $this->appId); } catch (NotFoundException $e) { - try { - $appDataFolder = $this->rootFolder->newFolder($name); - } catch (NotPermittedException $e) { - throw new \RuntimeException('Could not get appdata folder'); - } - } + $appDataRootFolder = $this->getAppDataRootFolder(); - try { - $appDataFolder = $appDataFolder->get($this->appId); - } catch (NotFoundException $e) { try { - $appDataFolder = $appDataFolder->newFolder($this->appId); - } catch (NotPermittedException $e) { - throw new \RuntimeException('Could not get appdata folder for ' . $this->appId); + $this->folder = $appDataRootFolder->get($this->appId); + } catch (NotFoundException $e) { + try { + $this->folder = $appDataRootFolder->newFolder($this->appId); + } catch (NotPermittedException $e) { + throw new \RuntimeException('Could not get appdata folder for ' . $this->appId); + } } } - - $this->folder = $appDataFolder; } return $this->folder; } public function getFolder(string $name): ISimpleFolder { - $node = $this->getAppDataFolder()->get($name); + $key = $this->appId . '/' . $name; + if ($cachedFolder = $this->folders->get($key)) { + if ($cachedFolder instanceof \Exception) { + throw $cachedFolder; + } else { + return $cachedFolder; + } + } + try { + $path = $this->getAppDataFolderName() . '/' . $this->appId . '/' . $name; + $node = $this->rootFolder->get($path); + } catch (NotFoundException $e) { + $this->folders->set($key, $e); + throw $e; + } /** @var Folder $node */ - return new SimpleFolder($node); + $folder = new SimpleFolder($node); + $this->folders->set($key, $folder); + return $folder; } public function newFolder(string $name): ISimpleFolder { + $key = $this->appId . '/' . $name; $folder = $this->getAppDataFolder()->newFolder($name); - return new SimpleFolder($folder); + $simpleFolder = new SimpleFolder($folder); + $this->folders->set($key, $simpleFolder); + return $simpleFolder; } public function getDirectoryListing(): array { $listing = $this->getAppDataFolder()->getDirectoryListing(); - $fileListing = array_map(function(Node $folder) { + $fileListing = array_map(function (Node $folder) { if ($folder instanceof Folder) { return new SimpleFolder($folder); } diff --git a/lib/private/Files/AppData/Factory.php b/lib/private/Files/AppData/Factory.php index fba2232db06..5c7d554ba5b 100644 --- a/lib/private/Files/AppData/Factory.php +++ b/lib/private/Files/AppData/Factory.php @@ -34,6 +34,8 @@ class Factory { /** @var SystemConfig */ private $config; + private $folders = []; + public function __construct(IRootFolder $rootFolder, SystemConfig $systemConfig) { @@ -46,6 +48,9 @@ class Factory { * @return AppData */ public function get(string $appId): AppData { - return new AppData($this->rootFolder, $this->config, $appId); + if (!isset($this->folders[$appId])) { + $this->folders[$appId] = new AppData($this->rootFolder, $this->config, $appId); + } + return $this->folders[$appId]; } } |