Skip to content

Commit c5d79b1

Browse files
authored
Merge pull request #445 from nextcloud/enh/performance
Build parent path without queries
2 parents f9abab3 + 7ae853d commit c5d79b1

File tree

5 files changed

+36
-16
lines changed

5 files changed

+36
-16
lines changed

lib/Model/PageInfo.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,18 @@ public function jsonSerialize(): array {
8787
public function fromFile(File $file, int $parentId, ?string $lastUserId = null, ?string $lastUserDisplayName = null, ?string $emoji = null, ?string $subpageOrder = null): void {
8888
$this->setId($file->getId());
8989
// Set folder name as title for all index pages except the collective landing page
90+
$dirName = dirname($file->getInternalPath());
91+
$dirName = $dirName === '.' ? '' : $dirName;
9092
if ($parentId !== 0 && 0 === strcmp($file->getName(), self::INDEX_PAGE_TITLE . self::SUFFIX)) {
91-
$this->setTitle($file->getParent()->getName());
93+
$this->setTitle(basename($dirName));
9294
} else {
9395
$this->setTitle(basename($file->getName(), self::SUFFIX));
9496
}
97+
$this->setFilePath($dirName);
9598
$this->setTimestamp($file->getMTime());
9699
$this->setSize($file->getSize());
97100
$this->setFileName($file->getName());
98101
$this->setCollectivePath(rtrim(explode('/', $file->getMountPoint()->getMountPoint(), 4)[3], '/'));
99-
$this->setFilePath($file->getParent()->getInternalPath());
100102
if (null !== $lastUserId) {
101103
$this->setLastUserId($lastUserId);
102104
}

lib/Mount/CollectiveFolderManager.php

+13-6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class CollectiveFolderManager {
3232
private IRequest $request;
3333
private ?string $rootPath = null;
3434

35+
/** @var int|null */
36+
private $rootFolderStorageId = null;
37+
3538
/**
3639
* CollectiveFolderManager constructor.
3740
*
@@ -185,14 +188,18 @@ private function getJailPath(int $folderId): string {
185188
* @throws NotFoundException
186189
*/
187190
private function getRootFolderStorageId(): int {
188-
$qb = $this->connection->getQueryBuilder();
191+
if ($this->rootFolderStorageId === null) {
192+
$qb = $this->connection->getQueryBuilder();
189193

190-
$qb->select('fileid')
191-
->from('filecache')
192-
->where($qb->expr()->eq('storage', $qb->createNamedParameter($this->getRootFolder()->getStorage()->getCache()->getNumericStorageId())))
193-
->andWhere($qb->expr()->eq('path_hash', $qb->createNamedParameter(md5($this->getRootPath()))));
194+
$qb->select('fileid')
195+
->from('filecache')
196+
->where($qb->expr()->eq('storage', $qb->createNamedParameter($this->getRootFolder()->getStorage()->getCache()->getNumericStorageId())))
197+
->andWhere($qb->expr()->eq('path_hash', $qb->createNamedParameter(md5($this->getRootPath()))));
198+
199+
$this->rootFolderStorageId = (int)$qb->execute()->fetchColumn();
200+
}
194201

195-
return (int)$qb->execute()->fetchColumn();
202+
return $this->rootFolderStorageId;
196203
}
197204

198205
/**

lib/Service/PageService.php

+12-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use OCP\Files\File;
1212
use OCP\Files\Folder;
1313
use OCP\Files\InvalidPathException;
14+
use OCP\Files\Node;
1415
use OCP\Files\NotPermittedException as FilesNotPermittedException;
1516
use OCP\Files\NotFoundException as FilesNotFoundException;
1617
use OCP\IConfig;
@@ -136,35 +137,38 @@ public function getFolder(int $collectiveId, int $fileId, string $userId): Folde
136137

137138
/**
138139
* @param File $file
140+
* @param Node|null $parent
139141
*
140142
* @return int
141143
* @throws NotFoundException
142144
*/
143-
public function getParentPageId(File $file): int {
145+
private function getParentPageId(File $file, ?Node $parent = null): int {
144146
try {
145147
if (self::isLandingPage($file)) {
146148
// Return `0` for landing page
147149
return 0;
148150
}
149151

152+
$parent = $parent ?? $file->getParent();
153+
150154
if (self::isIndexPage($file)) {
151155
// Go down two levels if index page but not landing page
152-
return $this->getIndexPageFile($file->getParent()->getParent())->getId();
156+
return $this->getIndexPageFile($parent->getParent())->getId();
153157
}
154158

155-
return $this->getIndexPageFile($file->getParent())->getId();
159+
return $this->getIndexPageFile($parent)->getId();
156160
} catch (InvalidPathException | FilesNotFoundException $e) {
157161
throw new NotFoundException($e->getMessage(), 0, $e);
158162
}
159163
}
160164

161165
/**
162166
* @param File $file
163-
*
167+
* @param Node|null $parent
164168
* @return PageInfo
165169
* @throws NotFoundException
166170
*/
167-
private function getPageByFile(File $file): PageInfo {
171+
private function getPageByFile(File $file, ?Node $parent = null): PageInfo {
168172
$pageInfo = new PageInfo();
169173
try {
170174
$page = $this->pageMapper->findByFileId($file->getId());
@@ -176,7 +180,7 @@ private function getPageByFile(File $file): PageInfo {
176180
$subpageOrder = ($page !== null) ? $page->getSubpageOrder() : null;
177181
try {
178182
$pageInfo->fromFile($file,
179-
$this->getParentPageId($file),
183+
$this->getParentPageId($file, $parent),
180184
$lastUserId,
181185
$lastUserId ? $this->userManager->get($lastUserId)->getDisplayName() : null,
182186
$emoji,
@@ -439,7 +443,7 @@ public static function folderHasSubPage(Folder $folder, string $title): int {
439443
public function recurseFolder(Folder $folder, string $userId): array {
440444
// Find index page or create it if we have subpages, but it doesn't exist
441445
try {
442-
$indexPage = $this->getPageByFile($this->getIndexPageFile($folder));
446+
$indexPage = $this->getPageByFile($this->getIndexPageFile($folder), $folder);
443447
} catch (NotFoundException $e) {
444448
if (!self::folderHasSubPages($folder)) {
445449
return [];
@@ -451,7 +455,7 @@ public function recurseFolder(Folder $folder, string $userId): array {
451455
// Add subpages and recurse over subfolders
452456
foreach ($folder->getDirectoryListing() as $node) {
453457
if ($node instanceof File && self::isPage($node) && !self::isIndexPage($node)) {
454-
$pageInfos[] = $this->getPageByFile($node);
458+
$pageInfos[] = $this->getPageByFile($node, $folder);
455459
} elseif ($node instanceof Folder) {
456460
array_push($pageInfos, ...$this->recurseFolder($node, $userId));
457461
}

tests/Unit/Model/PageInfoTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public function testFromFile(): void {
1818
$fileMountPoint = '/files/user/Collectives/collective/';
1919
$fileCollectivePath = 'Collectives/collective';
2020
$parentInternalPath = 'path/to/file';
21+
$internalPath = $parentInternalPath . '/' . $fileName;
2122
$userId = 'jane';
2223

2324
$mountPoint = $this->getMockBuilder(MountPoint::class)
@@ -39,6 +40,7 @@ public function testFromFile(): void {
3940
$file->method('getName')->willReturn($fileName);
4041
$file->method('getMountPoint')->willReturn($mountPoint);
4142
$file->method('getParent')->willReturn($parent);
43+
$file->method('getInternalPath')->willReturn($internalPath);
4244

4345
$pageInfo = new PageInfo();
4446
$pageInfo->fromFile($file, 1, $userId);

tests/Unit/Service/PageServiceTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ public function testRecurseFolder(): void {
242242
->willReturn($folder);
243243
$indexFile->method('getMountPoint')
244244
->willReturn($mountPoint);
245+
$indexFile->method('getInternalPath')
246+
->willReturn('Collectives/testfolder/Readme.md');
245247
$indexPage = new Page();
246248
$this->pageMapper->method('findByFileId')
247249
->willReturn($indexPage);
@@ -268,6 +270,9 @@ public function testRecurseFolder(): void {
268270
->willReturn($folder);
269271
$file->method('getMountPoint')
270272
->willReturn($mountPoint);
273+
$file->method('getInternalPath')
274+
->willReturn('Collectives/testfolder/Readme.md');
275+
271276
$filesNotJustMd[] = $file;
272277

273278
// Only add markdown files to $filesJustMd

0 commit comments

Comments
 (0)