diff options
author | Carl Schwan <carl@carlschwan.eu> | 2022-01-17 10:14:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-17 10:14:56 +0100 |
commit | 77e24274347a229f7df249b73c9a98a1420dab7e (patch) | |
tree | 303b3376c046b9b50c11862ba0e5a019302f6ae4 | |
parent | eb8b7b821847419875315fd991aa01066b3af6d3 (diff) | |
parent | 396157af18370a4dd8114a958c5cfe2da6f50393 (diff) | |
download | nextcloud-server-77e24274347a229f7df249b73c9a98a1420dab7e.tar.gz nextcloud-server-77e24274347a229f7df249b73c9a98a1420dab7e.zip |
Merge pull request #30682 from nextcloud/backport/30531/stable21
[stable21] Optimize FileSystemTags workflow for groupfolder
-rw-r--r-- | apps/workflowengine/lib/Check/FileSystemTags.php | 32 | ||||
-rw-r--r-- | lib/private/Files/Storage/Wrapper/Wrapper.php | 21 |
2 files changed, 42 insertions, 11 deletions
diff --git a/apps/workflowengine/lib/Check/FileSystemTags.php b/apps/workflowengine/lib/Check/FileSystemTags.php index c9cce240eb4..944552bef59 100644 --- a/apps/workflowengine/lib/Check/FileSystemTags.php +++ b/apps/workflowengine/lib/Check/FileSystemTags.php @@ -31,6 +31,7 @@ use OCP\SystemTag\ISystemTagObjectMapper; use OCP\SystemTag\TagNotFoundException; use OCP\WorkflowEngine\ICheck; use OCP\WorkflowEngine\IFileCheck; +use OC\Files\Storage\Wrapper\Wrapper; class FileSystemTags implements ICheck, IFileCheck { use TFileCheck; @@ -127,13 +128,26 @@ class FileSystemTags implements ICheck, IFileCheck { * @return int[] */ protected function getFileIds(ICache $cache, $path, $isExternalStorage) { - // TODO: Fix caching inside group folders - // Do not cache file ids inside group folders because multiple file ids might be mapped to - // the same combination of cache id + path. /** @psalm-suppress InvalidArgument */ - $shouldCacheFileIds = !$this->storage->instanceOfStorage(\OCA\GroupFolders\Mount\GroupFolderStorage::class); - $cacheId = $cache->getNumericStorageId(); - if ($shouldCacheFileIds && isset($this->fileIds[$cacheId][$path])) { + if ($this->storage->instanceOfStorage(\OCA\GroupFolders\Mount\GroupFolderStorage::class)) { + // Special implementation for groupfolder since all groupfolders share the same storage + // id so add the group folder id in the cache key too. + $groupFolderStorage = $this->storage; + if ($this->storage instanceof Wrapper) { + $groupFolderStorage = $this->storage->getInstanceOfStorage(\OCA\GroupFolders\Mount\GroupFolderStorage::class); + } + if ($groupFolderStorage === null) { + throw new \LogicException('Should not happen: Storage is instance of GroupFolderStorage but no group folder storage found while unwrapping.'); + } + /** + * @psalm-suppress UndefinedDocblockClass + * @psalm-suppress UndefinedInterfaceMethod + */ + $cacheId = $cache->getNumericStorageId() . '/' . $groupFolderStorage->getFolderId(); + } else { + $cacheId = $cache->getNumericStorageId(); + } + if (isset($this->fileIds[$cacheId][$path])) { return $this->fileIds[$cacheId][$path]; } @@ -146,12 +160,10 @@ class FileSystemTags implements ICheck, IFileCheck { $fileId = $cache->getId($path); if ($fileId !== -1) { - $parentIds[] = $cache->getId($path); + $parentIds[] = $fileId; } - if ($shouldCacheFileIds) { - $this->fileIds[$cacheId][$path] = $parentIds; - } + $this->fileIds[$cacheId][$path] = $parentIds; return $parentIds; } diff --git a/lib/private/Files/Storage/Wrapper/Wrapper.php b/lib/private/Files/Storage/Wrapper/Wrapper.php index 606fb3e24ee..586262ddab4 100644 --- a/lib/private/Files/Storage/Wrapper/Wrapper.php +++ b/lib/private/Files/Storage/Wrapper/Wrapper.php @@ -487,7 +487,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStrea /** * Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class * - * @param string $class + * @param class-string<IStorage> $class * @return bool */ public function instanceOfStorage($class) { @@ -499,6 +499,25 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStrea } /** + * @psalm-template T of IStorage + * @psalm-param class-string<T> $class + * @psalm-return T|null + */ + public function getInstanceOfStorage(string $class) { + $storage = $this; + while ($storage instanceof Wrapper) { + if ($storage instanceof $class) { + break; + } + $storage = $storage->getWrapperStorage(); + } + if (!($storage instanceof $class)) { + return null; + } + return $storage; + } + + /** * Pass any methods custom to specific storage implementations to the wrapped storage * * @param string $method |