Skip to content

Commit 77e2427

Browse files
authored
Merge pull request #30682 from nextcloud/backport/30531/stable21
[stable21] Optimize FileSystemTags workflow for groupfolder
2 parents eb8b7b8 + 396157a commit 77e2427

File tree

2 files changed

+42
-11
lines changed

2 files changed

+42
-11
lines changed

apps/workflowengine/lib/Check/FileSystemTags.php

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use OCP\SystemTag\TagNotFoundException;
3232
use OCP\WorkflowEngine\ICheck;
3333
use OCP\WorkflowEngine\IFileCheck;
34+
use OC\Files\Storage\Wrapper\Wrapper;
3435

3536
class FileSystemTags implements ICheck, IFileCheck {
3637
use TFileCheck;
@@ -127,13 +128,26 @@ protected function getSystemTags() {
127128
* @return int[]
128129
*/
129130
protected function getFileIds(ICache $cache, $path, $isExternalStorage) {
130-
// TODO: Fix caching inside group folders
131-
// Do not cache file ids inside group folders because multiple file ids might be mapped to
132-
// the same combination of cache id + path.
133131
/** @psalm-suppress InvalidArgument */
134-
$shouldCacheFileIds = !$this->storage->instanceOfStorage(\OCA\GroupFolders\Mount\GroupFolderStorage::class);
135-
$cacheId = $cache->getNumericStorageId();
136-
if ($shouldCacheFileIds && isset($this->fileIds[$cacheId][$path])) {
132+
if ($this->storage->instanceOfStorage(\OCA\GroupFolders\Mount\GroupFolderStorage::class)) {
133+
// Special implementation for groupfolder since all groupfolders share the same storage
134+
// id so add the group folder id in the cache key too.
135+
$groupFolderStorage = $this->storage;
136+
if ($this->storage instanceof Wrapper) {
137+
$groupFolderStorage = $this->storage->getInstanceOfStorage(\OCA\GroupFolders\Mount\GroupFolderStorage::class);
138+
}
139+
if ($groupFolderStorage === null) {
140+
throw new \LogicException('Should not happen: Storage is instance of GroupFolderStorage but no group folder storage found while unwrapping.');
141+
}
142+
/**
143+
* @psalm-suppress UndefinedDocblockClass
144+
* @psalm-suppress UndefinedInterfaceMethod
145+
*/
146+
$cacheId = $cache->getNumericStorageId() . '/' . $groupFolderStorage->getFolderId();
147+
} else {
148+
$cacheId = $cache->getNumericStorageId();
149+
}
150+
if (isset($this->fileIds[$cacheId][$path])) {
137151
return $this->fileIds[$cacheId][$path];
138152
}
139153

@@ -146,12 +160,10 @@ protected function getFileIds(ICache $cache, $path, $isExternalStorage) {
146160

147161
$fileId = $cache->getId($path);
148162
if ($fileId !== -1) {
149-
$parentIds[] = $cache->getId($path);
163+
$parentIds[] = $fileId;
150164
}
151165

152-
if ($shouldCacheFileIds) {
153-
$this->fileIds[$cacheId][$path] = $parentIds;
154-
}
166+
$this->fileIds[$cacheId][$path] = $parentIds;
155167

156168
return $parentIds;
157169
}

lib/private/Files/Storage/Wrapper/Wrapper.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ public function isLocal() {
487487
/**
488488
* Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class
489489
*
490-
* @param string $class
490+
* @param class-string<IStorage> $class
491491
* @return bool
492492
*/
493493
public function instanceOfStorage($class) {
@@ -498,6 +498,25 @@ public function instanceOfStorage($class) {
498498
return is_a($this, $class) or $this->getWrapperStorage()->instanceOfStorage($class);
499499
}
500500

501+
/**
502+
* @psalm-template T of IStorage
503+
* @psalm-param class-string<T> $class
504+
* @psalm-return T|null
505+
*/
506+
public function getInstanceOfStorage(string $class) {
507+
$storage = $this;
508+
while ($storage instanceof Wrapper) {
509+
if ($storage instanceof $class) {
510+
break;
511+
}
512+
$storage = $storage->getWrapperStorage();
513+
}
514+
if (!($storage instanceof $class)) {
515+
return null;
516+
}
517+
return $storage;
518+
}
519+
501520
/**
502521
* Pass any methods custom to specific storage implementations to the wrapped storage
503522
*

0 commit comments

Comments
 (0)