aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/Files/Config/LazyPathCachedMountInfo.php63
-rw-r--r--lib/private/Files/Config/UserMountCache.php65
4 files changed, 115 insertions, 15 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 65c00e53bcd..04511af269e 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1360,6 +1360,7 @@ return array(
'OC\\Files\\Cache\\Wrapper\\JailPropagator' => $baseDir . '/lib/private/Files/Cache/Wrapper/JailPropagator.php',
'OC\\Files\\Config\\CachedMountFileInfo' => $baseDir . '/lib/private/Files/Config/CachedMountFileInfo.php',
'OC\\Files\\Config\\CachedMountInfo' => $baseDir . '/lib/private/Files/Config/CachedMountInfo.php',
+ 'OC\\Files\\Config\\LazyPathCachedMountInfo' => $baseDir . '/lib/private/Files/Config/LazyPathCachedMountInfo.php',
'OC\\Files\\Config\\LazyStorageMountInfo' => $baseDir . '/lib/private/Files/Config/LazyStorageMountInfo.php',
'OC\\Files\\Config\\MountProviderCollection' => $baseDir . '/lib/private/Files/Config/MountProviderCollection.php',
'OC\\Files\\Config\\UserMountCache' => $baseDir . '/lib/private/Files/Config/UserMountCache.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 814245a79b8..4754e82106d 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1393,6 +1393,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Files\\Cache\\Wrapper\\JailPropagator' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Wrapper/JailPropagator.php',
'OC\\Files\\Config\\CachedMountFileInfo' => __DIR__ . '/../../..' . '/lib/private/Files/Config/CachedMountFileInfo.php',
'OC\\Files\\Config\\CachedMountInfo' => __DIR__ . '/../../..' . '/lib/private/Files/Config/CachedMountInfo.php',
+ 'OC\\Files\\Config\\LazyPathCachedMountInfo' => __DIR__ . '/../../..' . '/lib/private/Files/Config/LazyPathCachedMountInfo.php',
'OC\\Files\\Config\\LazyStorageMountInfo' => __DIR__ . '/../../..' . '/lib/private/Files/Config/LazyStorageMountInfo.php',
'OC\\Files\\Config\\MountProviderCollection' => __DIR__ . '/../../..' . '/lib/private/Files/Config/MountProviderCollection.php',
'OC\\Files\\Config\\UserMountCache' => __DIR__ . '/../../..' . '/lib/private/Files/Config/UserMountCache.php',
diff --git a/lib/private/Files/Config/LazyPathCachedMountInfo.php b/lib/private/Files/Config/LazyPathCachedMountInfo.php
new file mode 100644
index 00000000000..d42052c5f83
--- /dev/null
+++ b/lib/private/Files/Config/LazyPathCachedMountInfo.php
@@ -0,0 +1,63 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OC\Files\Config;
+
+use OCP\IUser;
+
+class LazyPathCachedMountInfo extends CachedMountInfo {
+ // we don't allow \ in paths so it makes a great placeholder
+ private const PATH_PLACEHOLDER = '\\PLACEHOLDER\\';
+
+ /** @var callable(CachedMountInfo): string */
+ protected $rootInternalPathCallback;
+
+ /**
+ * @param IUser $user
+ * @param int $storageId
+ * @param int $rootId
+ * @param string $mountPoint
+ * @param string $mountProvider
+ * @param int|null $mountId
+ * @param callable(CachedMountInfo): string $rootInternalPathCallback
+ * @throws \Exception
+ */
+ public function __construct(
+ IUser $user,
+ int $storageId,
+ int $rootId,
+ string $mountPoint,
+ string $mountProvider,
+ int $mountId = null,
+ callable $rootInternalPathCallback,
+ ) {
+ parent::__construct($user, $storageId, $rootId, $mountPoint, $mountProvider, $mountId, self::PATH_PLACEHOLDER);
+ $this->rootInternalPathCallback = $rootInternalPathCallback;
+ }
+
+ public function getRootInternalPath(): string {
+ if ($this->rootInternalPath === self::PATH_PLACEHOLDER) {
+ $this->rootInternalPath = ($this->rootInternalPathCallback)($this);
+ }
+ return $this->rootInternalPath;
+ }
+}
diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php
index 2fb7a7d83f4..27d84e93838 100644
--- a/lib/private/Files/Config/UserMountCache.php
+++ b/lib/private/Files/Config/UserMountCache.php
@@ -52,6 +52,11 @@ class UserMountCache implements IUserMountCache {
* @var CappedMemoryCache<ICachedMountInfo[]>
**/
private CappedMemoryCache $mountsForUsers;
+ /**
+ * fileid => internal path mapping for cached mount info.
+ * @var CappedMemoryCache<string>
+ **/
+ private CappedMemoryCache $internalPathCache;
private LoggerInterface $logger;
/** @var CappedMemoryCache<array> */
private CappedMemoryCache $cacheInfoCache;
@@ -71,6 +76,7 @@ class UserMountCache implements IUserMountCache {
$this->logger = $logger;
$this->eventLogger = $eventLogger;
$this->cacheInfoCache = new CappedMemoryCache();
+ $this->internalPathCache = new CappedMemoryCache();
$this->mountsForUsers = new CappedMemoryCache();
}
@@ -204,7 +210,12 @@ class UserMountCache implements IUserMountCache {
$query->execute();
}
- private function dbRowToMountInfo(array $row) {
+ /**
+ * @param array $row
+ * @param (callable(CachedMountInfo): string)|null $pathCallback
+ * @return CachedMountInfo|null
+ */
+ private function dbRowToMountInfo(array $row, ?callable $pathCallback = null): ?ICachedMountInfo {
$user = $this->userManager->get($row['user_id']);
if (is_null($user)) {
return null;
@@ -213,15 +224,27 @@ class UserMountCache implements IUserMountCache {
if (!is_null($mount_id)) {
$mount_id = (int)$mount_id;
}
- return new CachedMountInfo(
- $user,
- (int)$row['storage_id'],
- (int)$row['root_id'],
- $row['mount_point'],
- $row['mount_provider_class'] ?? '',
- $mount_id,
- $row['path'] ?? '',
- );
+ if ($pathCallback) {
+ return new LazyPathCachedMountInfo(
+ $user,
+ (int)$row['storage_id'],
+ (int)$row['root_id'],
+ $row['mount_point'],
+ $row['mount_provider_class'] ?? '',
+ $mount_id,
+ $pathCallback,
+ );
+ } else {
+ return new CachedMountInfo(
+ $user,
+ (int)$row['storage_id'],
+ (int)$row['root_id'],
+ $row['mount_point'],
+ $row['mount_provider_class'] ?? '',
+ $mount_id,
+ $row['path'] ?? '',
+ );
+ }
}
/**
@@ -232,27 +255,39 @@ class UserMountCache implements IUserMountCache {
$userUID = $user->getUID();
if (!isset($this->mountsForUsers[$userUID])) {
$builder = $this->connection->getQueryBuilder();
- $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class')
+ $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'mount_provider_class')
->from('mounts', 'm')
- ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
->where($builder->expr()->eq('user_id', $builder->createPositionalParameter($userUID)));
$result = $query->execute();
$rows = $result->fetchAll();
$result->closeCursor();
- $this->mountsForUsers[$userUID] = [];
/** @var array<string, ICachedMountInfo> $mounts */
+ $mounts = [];
foreach ($rows as $row) {
- $mount = $this->dbRowToMountInfo($row);
+ $mount = $this->dbRowToMountInfo($row, [$this, 'getInternalPathForMountInfo']);
if ($mount !== null) {
- $this->mountsForUsers[$userUID][$mount->getKey()] = $mount;
+ $mounts[$mount->getKey()] = $mount;
}
}
+ $this->mountsForUsers[$userUID] = $mounts;
}
return $this->mountsForUsers[$userUID];
}
+ public function getInternalPathForMountInfo(CachedMountInfo $info): string {
+ $cached = $this->internalPathCache->get($info->getRootId());
+ if ($cached !== null) {
+ return $cached;
+ }
+ $builder = $this->connection->getQueryBuilder();
+ $query = $builder->select('path')
+ ->from('filecache')
+ ->where($builder->expr()->eq('fileid', $builder->createPositionalParameter($info->getRootId())));
+ return $query->executeQuery()->fetchOne() ?: '';
+ }
+
/**
* @param int $numericStorageId
* @param string|null $user limit the results to a single user