Skip to content

Commit 70d62d7

Browse files
Carl SchwanCarlSchwan
authored andcommitted
feat(trashbin): Use a lazy folder for roots of trashbin
Introduze a LazyMountPoint which is similar to LazyFile/LazyFolder and allow to avoid doing DB request when we just want the storage id and we already have it. Signed-off-by: Carl Schwan <carlschwan@kde.org>
1 parent fb92a7a commit 70d62d7

10 files changed

Lines changed: 143 additions & 7 deletions

File tree

apps/dav/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@
264264
'OCA\\DAV\\Controller\\UpcomingEventsController' => $baseDir . '/../lib/Controller/UpcomingEventsController.php',
265265
'OCA\\DAV\\DAV\\CustomPropertiesBackend' => $baseDir . '/../lib/DAV/CustomPropertiesBackend.php',
266266
'OCA\\DAV\\DAV\\GroupPrincipalBackend' => $baseDir . '/../lib/DAV/GroupPrincipalBackend.php',
267+
'OCA\\DAV\\DAV\\ICacheableDirectory' => $baseDir . '/../lib/DAV/ICacheableDirectory.php',
267268
'OCA\\DAV\\DAV\\PublicAuth' => $baseDir . '/../lib/DAV/PublicAuth.php',
268269
'OCA\\DAV\\DAV\\RemoteUserPrincipalBackend' => $baseDir . '/../lib/DAV/RemoteUserPrincipalBackend.php',
269270
'OCA\\DAV\\DAV\\Sharing\\Backend' => $baseDir . '/../lib/DAV/Sharing/Backend.php',

apps/dav/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ class ComposerStaticInitDAV
279279
'OCA\\DAV\\Controller\\UpcomingEventsController' => __DIR__ . '/..' . '/../lib/Controller/UpcomingEventsController.php',
280280
'OCA\\DAV\\DAV\\CustomPropertiesBackend' => __DIR__ . '/..' . '/../lib/DAV/CustomPropertiesBackend.php',
281281
'OCA\\DAV\\DAV\\GroupPrincipalBackend' => __DIR__ . '/..' . '/../lib/DAV/GroupPrincipalBackend.php',
282+
'OCA\\DAV\\DAV\\ICacheableDirectory' => __DIR__ . '/..' . '/../lib/DAV/ICacheableDirectory.php',
282283
'OCA\\DAV\\DAV\\PublicAuth' => __DIR__ . '/..' . '/../lib/DAV/PublicAuth.php',
283284
'OCA\\DAV\\DAV\\RemoteUserPrincipalBackend' => __DIR__ . '/..' . '/../lib/DAV/RemoteUserPrincipalBackend.php',
284285
'OCA\\DAV\\DAV\\Sharing\\Backend' => __DIR__ . '/..' . '/../lib/DAV/Sharing/Backend.php',

apps/dav/lib/Connector/Sabre/Directory.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ class Directory extends Node implements
4848
\Sabre\DAV\IMoveTarget,
4949
\Sabre\DAV\ICopyTarget,
5050
INodeByPath,
51-
ICacheableDirectory
52-
{
51+
ICacheableDirectory {
5352
/**
5453
* Cached directory content
5554
* @var FileInfo[]

apps/dav/lib/DAV/ICacheableDirectory.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
<?php
22

3+
declare (strict_types=1);
4+
/**
5+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
6+
* SPDX-License-Identifier: AGPL-3.0-or-later
7+
*/
8+
39
namespace OCA\DAV\DAV;
410

511
use OCP\Files\Folder;

apps/files_trashbin/lib/Trash/ITrashBackend.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ public function getTrashNodeById(IUser $user, int $fileId);
6868

6969
/**
7070
* Returns a non-exhaustive list of folder which can then be used to pre-fetch some metadata
71-
* * for the trash root.
71+
* for the trash root.
7272
*
7373
* @return Folder[]
74-
* @since 32.0.0
74+
* @since 34.0.0
7575
*/
7676
public function getCacheableRootsForUser(IUser $user): array;
7777
}

apps/files_trashbin/lib/Trash/LegacyTrashBackend.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
55
* SPDX-License-Identifier: AGPL-3.0-or-later
66
*/
7+
78
namespace OCA\Files_Trashbin\Trash;
89

910
use OC\Files\Filesystem;
11+
use OC\Files\Node\LazyFolder;
1012
use OC\Files\View;
1113
use OCA\Files_Trashbin\Helper;
1214
use OCA\Files_Trashbin\Storage;
@@ -16,8 +18,10 @@
1618
use OCP\Files\IRootFolder;
1719
use OCP\Files\NotFoundException;
1820
use OCP\Files\Storage\IStorage;
21+
use OCP\IDBConnection;
1922
use OCP\IUser;
2023
use OCP\IUserManager;
24+
use OCP\Server;
2125

2226
class LegacyTrashBackend implements ITrashBackend {
2327
/** @var array */
@@ -119,8 +123,29 @@ public function getTrashNodeById(IUser $user, int $fileId) {
119123
}
120124
}
121125

122-
public function getTrashRootsForUser(IUser $user): array {
126+
public function getCacheableRootsForUser(IUser $user): array {
123127
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
124-
return [$userFolder->getParent()->get('files_trashbin/files')];
128+
$connection = Server::get(IDBConnection::class);
129+
$qb = $connection->getQueryBuilder();
130+
$qb->select('fileid', 'storage')
131+
->from('filecache')
132+
->hintShardKey('storage', $userFolder->getMountPoint()->getNumericStorageId())
133+
->where($qb->expr()->eq('path_hash', $qb->createNamedParameter(md5('files_trashbin/files'))));
134+
$result = $qb->executeQuery()->fetchAll();
135+
136+
if (count($result) === 0) {
137+
return [];
138+
}
139+
140+
return [
141+
new LazyFolder(
142+
$this->rootFolder,
143+
fn () => $userFolder->getParent()->get('files_trashbin/files'),
144+
[
145+
'fileid' => $result[0]['fileid'],
146+
'mountpoint_numericStorageId' => $result[0]['storage'],
147+
]
148+
)
149+
];
125150
}
126151
}

lib/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,6 +1739,7 @@
17391739
'OC\\Files\\Lock\\LockManager' => $baseDir . '/lib/private/Files/Lock/LockManager.php',
17401740
'OC\\Files\\Mount\\CacheMountProvider' => $baseDir . '/lib/private/Files/Mount/CacheMountProvider.php',
17411741
'OC\\Files\\Mount\\HomeMountPoint' => $baseDir . '/lib/private/Files/Mount/HomeMountPoint.php',
1742+
'OC\\Files\\Mount\\LazyMountPoint' => $baseDir . '/lib/private/Files/Mount/LazyMountPoint.php',
17421743
'OC\\Files\\Mount\\LocalHomeMountProvider' => $baseDir . '/lib/private/Files/Mount/LocalHomeMountProvider.php',
17431744
'OC\\Files\\Mount\\Manager' => $baseDir . '/lib/private/Files/Mount/Manager.php',
17441745
'OC\\Files\\Mount\\MountPoint' => $baseDir . '/lib/private/Files/Mount/MountPoint.php',

lib/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,6 +1780,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
17801780
'OC\\Files\\Lock\\LockManager' => __DIR__ . '/../../..' . '/lib/private/Files/Lock/LockManager.php',
17811781
'OC\\Files\\Mount\\CacheMountProvider' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/CacheMountProvider.php',
17821782
'OC\\Files\\Mount\\HomeMountPoint' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/HomeMountPoint.php',
1783+
'OC\\Files\\Mount\\LazyMountPoint' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/LazyMountPoint.php',
17831784
'OC\\Files\\Mount\\LocalHomeMountProvider' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/LocalHomeMountProvider.php',
17841785
'OC\\Files\\Mount\\Manager' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/Manager.php',
17851786
'OC\\Files\\Mount\\MountPoint' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/MountPoint.php',
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
/**
4+
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
5+
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
6+
* SPDX-License-Identifier: AGPL-3.0-only
7+
*/
8+
namespace OC\Files\Mount;
9+
10+
use OCP\Files\Mount\IMountPoint;
11+
12+
class LazyMountPoint implements IMountPoint {
13+
private ?IMountPoint $mountPoint = null;
14+
15+
/**
16+
* @param \Closure(): IMountPoint $mountPointClosure
17+
*/
18+
public function __construct(
19+
private readonly \Closure $mountPointClosure,
20+
private readonly array $data,
21+
) {
22+
}
23+
24+
private function getRealMountPoint(): IMountPoint {
25+
if ($this->mountPoint === null) {
26+
$this->mountPoint = call_user_func($this->mountPointClosure);
27+
}
28+
return $this->mountPoint;
29+
}
30+
31+
public function __call($method, $args) {
32+
return call_user_func_array([$this->getRealMountPoint(), $method], $args);
33+
}
34+
35+
public function getMountPoint() {
36+
return $this->__call(__FUNCTION__, func_get_args());
37+
}
38+
39+
public function setMountPoint($mountPoint) {
40+
return $this->__call(__FUNCTION__, func_get_args());
41+
}
42+
43+
private function createStorage() {
44+
return $this->__call(__FUNCTION__, func_get_args());
45+
}
46+
47+
public function getStorage() {
48+
return $this->__call(__FUNCTION__, func_get_args());
49+
}
50+
51+
public function getStorageId(): ?string {
52+
return $this->__call(__FUNCTION__, func_get_args());
53+
}
54+
55+
public function getNumericStorageId(): int {
56+
if (isset($this->data['numericStorageId'])) {
57+
return $this->data['numericStorageId'];
58+
}
59+
return $this->__call(__FUNCTION__, func_get_args());
60+
}
61+
62+
public function getInternalPath($path) {
63+
return $this->__call(__FUNCTION__, func_get_args());
64+
}
65+
66+
public function wrapStorage($wrapper): void {
67+
$this->__call(__FUNCTION__, func_get_args());
68+
}
69+
70+
public function getOption($name, $default) {
71+
return $this->__call(__FUNCTION__, func_get_args());
72+
}
73+
74+
public function getOptions(): array {
75+
return $this->__call(__FUNCTION__, func_get_args());
76+
}
77+
78+
public function getStorageRootId(): int {
79+
return $this->__call(__FUNCTION__, func_get_args());
80+
}
81+
82+
public function getMountId() {
83+
return $this->__call(__FUNCTION__, func_get_args());
84+
}
85+
86+
public function getMountType() {
87+
return $this->__call(__FUNCTION__, func_get_args());
88+
}
89+
90+
public function getMountProvider(): string {
91+
return $this->__call(__FUNCTION__, func_get_args());
92+
}
93+
}

lib/private/Files/Node/LazyFolder.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace OC\Files\Node;
99

1010
use OC\Files\Filesystem;
11+
use OC\Files\Mount\LazyMountPoint;
1112
use OC\Files\Utils\PathHelper;
1213
use OCP\Constants;
1314
use OCP\Files\Folder;
@@ -373,7 +374,15 @@ public function isMounted() {
373374
* @inheritDoc
374375
*/
375376
public function getMountPoint() {
376-
return $this->__call(__FUNCTION__, func_get_args());
377+
if (array_any(array_keys($this->data), fn ($key) => str_starts_with($key, 'mountpoint_'))) {
378+
return new LazyMountPoint(function () {
379+
return $this->__call('getMountPoint', func_get_args());
380+
}, [
381+
'numericStorageId' => $this->data['mountpoint_numericStorageId'],
382+
]);
383+
} else {
384+
return $this->__call(__FUNCTION__, func_get_args());
385+
}
377386
}
378387

379388
/**

0 commit comments

Comments
 (0)