From 44813ee14a8c978edae4735966ee4aeb1fd86624 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Fri, 19 Jun 2026 12:15:35 +0200 Subject: [PATCH] perf: Only sort wrappers when adding them Instead of doing that each time a new mount point is created (e.g. for the 7000 shares we have in production). Signed-off-by: Carl Schwan --- lib/private/Files/Storage/StorageFactory.php | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/private/Files/Storage/StorageFactory.php b/lib/private/Files/Storage/StorageFactory.php index 603df7fe007b9..0b76e89504295 100644 --- a/lib/private/Files/Storage/StorageFactory.php +++ b/lib/private/Files/Storage/StorageFactory.php @@ -14,10 +14,11 @@ use Psr\Log\LoggerInterface; class StorageFactory implements IStorageFactory { - /** - * @var array[] [$name=>['priority'=>$priority, 'wrapper'=>$callable] $storageWrappers - */ - private $storageWrappers = []; + /** @var array $storageWrappers */ + private array $storageWrappers = []; + + /** @var bool $dirty Whether the list of storage wrappers is sorted */ + private bool $dirty = true; public function addStorageWrapper(string $wrapperName, callable $callback, int $priority = 50, array $existingMounts = []): bool { if (isset($this->storageWrappers[$wrapperName])) { @@ -30,6 +31,7 @@ public function addStorageWrapper(string $wrapperName, callable $callback, int $ } $this->storageWrappers[$wrapperName] = ['wrapper' => $callback, 'priority' => $priority]; + $this->dirty = true; return true; } @@ -54,16 +56,14 @@ public function getInstance(IMountPoint $mountPoint, string $class, array $argum } public function wrap(IMountPoint $mountPoint, IStorage $storage): IStorage { - $wrappers = array_values($this->storageWrappers); - usort($wrappers, function ($a, $b) { - return $b['priority'] - $a['priority']; - }); - /** @var callable[] $wrappers */ - $wrappers = array_map(function ($wrapper) { - return $wrapper['wrapper']; - }, $wrappers); - foreach ($wrappers as $wrapper) { - $storage = $wrapper($mountPoint->getMountPoint(), $storage, $mountPoint); + if ($this->dirty) { + uasort($this->storageWrappers, static fn (array $a, array $b) => $b['priority'] - $a['priority']); + $this->dirty = false; + } + foreach ($this->storageWrappers as $wrapper) { + /** @var callable(string, IStorage, IMountPoint): IStorage $wrapperCallable */ + $wrapperCallable = $wrapper['wrapper']; + $storage = $wrapperCallable($mountPoint->getMountPoint(), $storage, $mountPoint); if (!($storage instanceof IStorage)) { throw new \Exception('Invalid result from storage wrapper'); }