Merge pull request #26593 from nextcloud/bugfix/noid/getMountsForFileId-performance

Filter mounts for file id before trying to get user information
This commit is contained in:
blizzz 2021-04-30 10:52:44 +02:00 committed by GitHub
commit 36c9441c37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 4 deletions

View File

@ -326,18 +326,30 @@ class UserMountCache implements IUserMountCache {
} catch (NotFoundException $e) { } catch (NotFoundException $e) {
return []; return [];
} }
$mountsForStorage = $this->getMountsForStorageId($storageId, $user); $builder = $this->connection->getQueryBuilder();
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
->from('mounts', 'm')
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($storageId, IQueryBuilder::PARAM_INT)));
if ($user) {
$query->andWhere($builder->expr()->eq('user_id', $builder->createPositionalParameter($user)));
}
$result = $query->execute();
$rows = $result->fetchAll();
$result->closeCursor();
// filter mounts that are from the same storage but a different directory // filter mounts that are from the same storage but a different directory
$filteredMounts = array_filter($mountsForStorage, function (ICachedMountInfo $mount) use ($internalPath, $fileId) { $filteredMounts = array_filter($rows, function (array $row) use ($internalPath, $fileId) {
if ($fileId === $mount->getRootId()) { if ($fileId === (int)$row['root_id']) {
return true; return true;
} }
$internalMountPath = $mount->getRootInternalPath(); $internalMountPath = isset($row['path']) ? $row['path'] : '';
return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath . '/'; return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath . '/';
}); });
$filteredMounts = array_filter(array_map([$this, 'dbRowToMountInfo'], $filteredMounts));
return array_map(function (ICachedMountInfo $mount) use ($internalPath) { return array_map(function (ICachedMountInfo $mount) use ($internalPath) {
return new CachedMountFileInfo( return new CachedMountFileInfo(
$mount->getUser(), $mount->getUser(),