Skip to content

Commit 4c0a598

Browse files
committed
perf: only load possible results in UserMountCache::getMountForPath
Signed-off-by: Robin Appelman <robin@icewind.nl>
1 parent 149bbf7 commit 4c0a598

1 file changed

Lines changed: 33 additions & 13 deletions

File tree

lib/private/Files/Config/UserMountCache.php

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -488,28 +488,48 @@ public function clear(): void {
488488
}
489489

490490
public function getMountForPath(IUser $user, string $path): ICachedMountInfo {
491-
$mounts = [];
492-
foreach ($this->getMountsForUser($user) as $mount) {
493-
$mounts[$mount->getMountPoint()] = $mount;
494-
}
495-
491+
$searchPaths = [];
496492
$current = rtrim($path, '/');
497-
// walk up the directory tree until we find a path that has a mountpoint set
498-
// the loop will return if a mountpoint is found or break if none are found
499-
while (true) {
493+
// get all paths that we are interested in, $path and all it's parents
494+
while ($current !== '') {
500495
$mountPoint = $current . '/';
501-
if (isset($mounts[$mountPoint])) {
502-
return $mounts[$mountPoint];
503-
} elseif ($current === '') {
504-
break;
505-
}
496+
497+
$searchPaths[] = $mountPoint;
506498

507499
$current = dirname($current);
508500
if ($current === '.' || $current === '/') {
509501
$current = '';
510502
}
511503
}
512504

505+
$mounts = [];
506+
if (isset($this->mountsForUsers[$user->getUID()])) {
507+
foreach ($this->mountsForUsers[$user->getUID()] as $mount) {
508+
$mounts[$mount->getMountPoint()] = $mount;
509+
}
510+
} else {
511+
$searchPathHashes = array_map(static fn (string $path) => hash('xxh128', $path), $searchPaths);
512+
513+
$builder = $this->connection->getQueryBuilder();
514+
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class')
515+
->from('mounts', 'm')
516+
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
517+
->where($builder->expr()->eq('user_id', $builder->createNamedParameter($user->getUID())))
518+
->andWhere($builder->expr()->in('mount_point_hash', $builder->createNamedParameter($searchPathHashes, IQueryBuilder::PARAM_STR_ARRAY)));
519+
520+
foreach ($query->executeQuery()->fetchAll() as $row) {
521+
$mount = $this->dbRowToMountInfo($row);
522+
$mounts[$mount->getMountPoint()] = $mount;
523+
}
524+
}
525+
526+
// note that $searchPaths is sorted deepest path first
527+
foreach ($searchPaths as $searchPath) {
528+
if (isset($mounts[$searchPath])) {
529+
return $mounts[$searchPath];
530+
}
531+
}
532+
513533
throw new NotFoundException('No cached mount for path ' . $path);
514534
}
515535

0 commit comments

Comments
 (0)