Skip to content

Commit 3938b32

Browse files
author
Carl Schwan
committed
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 <carl.schwan@nextclound.com>
1 parent 4d9b244 commit 3938b32

5 files changed

Lines changed: 143 additions & 3 deletions

File tree

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
@@ -1673,6 +1673,7 @@
16731673
'OC\\Files\\Lock\\LockManager' => $baseDir . '/lib/private/Files/Lock/LockManager.php',
16741674
'OC\\Files\\Mount\\CacheMountProvider' => $baseDir . '/lib/private/Files/Mount/CacheMountProvider.php',
16751675
'OC\\Files\\Mount\\HomeMountPoint' => $baseDir . '/lib/private/Files/Mount/HomeMountPoint.php',
1676+
'OC\\Files\\Mount\\LazyMountPoint' => $baseDir . '/lib/private/Files/Mount/LazyMountPoint.php',
16761677
'OC\\Files\\Mount\\LocalHomeMountProvider' => $baseDir . '/lib/private/Files/Mount/LocalHomeMountProvider.php',
16771678
'OC\\Files\\Mount\\Manager' => $baseDir . '/lib/private/Files/Mount/Manager.php',
16781679
'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
@@ -1714,6 +1714,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
17141714
'OC\\Files\\Lock\\LockManager' => __DIR__ . '/../../..' . '/lib/private/Files/Lock/LockManager.php',
17151715
'OC\\Files\\Mount\\CacheMountProvider' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/CacheMountProvider.php',
17161716
'OC\\Files\\Mount\\HomeMountPoint' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/HomeMountPoint.php',
1717+
'OC\\Files\\Mount\\LazyMountPoint' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/LazyMountPoint.php',
17171718
'OC\\Files\\Mount\\LocalHomeMountProvider' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/LocalHomeMountProvider.php',
17181719
'OC\\Files\\Mount\\Manager' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/Manager.php',
17191720
'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: 21 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;
@@ -366,11 +367,30 @@ public function isMounted() {
366367
return $this->__call(__FUNCTION__, func_get_args());
367368
}
368369

370+
// TODO remove when we can depend on php 8.4
371+
private static function _array_any(array $array, callable $callback): bool {
372+
foreach ($array as $key => $value) {
373+
if ($callback($value, $key)) {
374+
return true;
375+
}
376+
}
377+
378+
return false;
379+
}
380+
369381
/**
370382
* @inheritDoc
371383
*/
372384
public function getMountPoint() {
373-
return $this->__call(__FUNCTION__, func_get_args());
385+
if (self::_array_any(array_keys($this->data), fn ($key) => str_starts_with($key, 'mountpoint_'))) {
386+
return new LazyMountPoint(function () {
387+
return $this->__call('getMountPoint', func_get_args());
388+
}, [
389+
'numericStorageId' => $this->data['mountpoint_numericStorageId'],
390+
]);
391+
} else {
392+
return $this->__call(__FUNCTION__, func_get_args());
393+
}
374394
}
375395

376396
/**

0 commit comments

Comments
 (0)