summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl Schwan <carl@carlschwan.eu>2022-01-17 10:14:56 +0100
committerGitHub <noreply@github.com>2022-01-17 10:14:56 +0100
commit77e24274347a229f7df249b73c9a98a1420dab7e (patch)
tree303b3376c046b9b50c11862ba0e5a019302f6ae4
parenteb8b7b821847419875315fd991aa01066b3af6d3 (diff)
parent396157af18370a4dd8114a958c5cfe2da6f50393 (diff)
downloadnextcloud-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.php32
-rw-r--r--lib/private/Files/Storage/Wrapper/Wrapper.php21
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