only fetch the data for mounts inside a folder when needed

for most operations we don't actually care about any mounts inside a folder, only for metadata that needs to propagate across storage boundaries (size, etag, mtime) do we need all the submount info.

By only loading this data when needed we can save a bunch of storage setup in a number of cases

Signed-off-by: Robin Appelman <robin@icewind.nl>
pull/36610/head
Robin Appelman 3 years ago
parent 7341d339eb
commit 5bcf37b7ff
  1. 2
      lib/private/Files/Node/File.php
  2. 8
      lib/private/Files/Node/Folder.php
  3. 56
      lib/private/Files/Node/Node.php
  4. 4
      lib/private/Files/Node/Root.php
  5. 17
      lib/private/Files/View.php

@ -37,7 +37,7 @@ class File extends Node implements \OCP\Files\File {
* Creates a Folder that represents a non-existing path
*
* @param string $path path
* @return string non-existing node class
* @return NonExistingFile non-existing node
*/
protected function createNonExistingNode($path) {
return new NonExistingFile($this->root, $this->view, $path);

@ -54,7 +54,7 @@ class Folder extends Node implements \OCP\Files\Folder {
* Creates a Folder that represents a non-existing path
*
* @param string $path path
* @return string non-existing node class
* @return NonExistingFolder non-existing node
*/
protected function createNonExistingNode($path) {
return new NonExistingFolder($this->root, $this->view, $path);
@ -98,7 +98,7 @@ class Folder extends Node implements \OCP\Files\Folder {
* @throws \OCP\Files\NotFoundException
*/
public function getDirectoryListing() {
$folderContent = $this->view->getDirectoryContent($this->path, '', $this->getFileInfo());
$folderContent = $this->view->getDirectoryContent($this->path, '', $this->getFileInfo(false));
return array_map(function (FileInfo $info) {
if ($info->getMimetype() === FileInfo::MIMETYPE_FOLDER) {
@ -114,7 +114,7 @@ class Folder extends Node implements \OCP\Files\Folder {
* @param FileInfo $info
* @return File|Folder
*/
protected function createNode($path, FileInfo $info = null) {
protected function createNode($path, FileInfo $info = null, bool $infoHasSubMountsIncluded = true) {
if (is_null($info)) {
$isDir = $this->view->is_dir($path);
} else {
@ -122,7 +122,7 @@ class Folder extends Node implements \OCP\Files\Folder {
}
$parent = dirname($path) === $this->getPath() ? $this : null;
if ($isDir) {
return new Folder($this->root, $this->view, $path, $info, $parent);
return new Folder($this->root, $this->view, $path, $info, $parent, $infoHasSubMountsIncluded);
} else {
return new File($this->root, $this->view, $path, $info, $parent);
}

@ -56,35 +56,35 @@ class Node implements \OCP\Files\Node {
*/
protected $path;
/**
* @var \OCP\Files\FileInfo
*/
protected $fileInfo;
protected ?FileInfo $fileInfo;
/**
* @var Node|null
*/
protected $parent;
private bool $infoHasSubMountsIncluded;
/**
* @param \OC\Files\View $view
* @param \OCP\Files\IRootFolder $root
* @param string $path
* @param FileInfo $fileInfo
*/
public function __construct($root, $view, $path, $fileInfo = null, ?Node $parent = null) {
public function __construct($root, $view, $path, $fileInfo = null, ?Node $parent = null, bool $infoHasSubMountsIncluded = true) {
$this->view = $view;
$this->root = $root;
$this->path = $path;
$this->fileInfo = $fileInfo;
$this->parent = $parent;
$this->infoHasSubMountsIncluded = $infoHasSubMountsIncluded;
}
/**
* Creates a Node of the same type that represents a non-existing path
*
* @param string $path path
* @return string non-existing node class
* @return Node non-existing node
* @throws \Exception
*/
protected function createNonExistingNode($path) {
@ -98,17 +98,23 @@ class Node implements \OCP\Files\Node {
* @throws InvalidPathException
* @throws NotFoundException
*/
public function getFileInfo() {
public function getFileInfo(bool $includeMountPoint = true) {
if (!$this->fileInfo) {
if (!Filesystem::isValidPath($this->path)) {
throw new InvalidPathException();
}
$fileInfo = $this->view->getFileInfo($this->path);
$fileInfo = $this->view->getFileInfo($this->path, $includeMountPoint);
$this->infoHasSubMountsIncluded = $includeMountPoint;
if ($fileInfo instanceof FileInfo) {
$this->fileInfo = $fileInfo;
} else {
throw new NotFoundException();
}
} elseif ($includeMountPoint && !$this->infoHasSubMountsIncluded && $this instanceof Folder) {
if ($this->fileInfo instanceof \OC\Files\FileInfo) {
$this->view->addSubMounts($this->fileInfo);
}
$this->infoHasSubMountsIncluded = true;
}
return $this->fileInfo;
}
@ -179,7 +185,7 @@ class Node implements \OCP\Files\Node {
* @return string
*/
public function getInternalPath() {
return $this->getFileInfo()->getInternalPath();
return $this->getFileInfo(false)->getInternalPath();
}
/**
@ -188,7 +194,7 @@ class Node implements \OCP\Files\Node {
* @throws NotFoundException
*/
public function getId() {
return $this->getFileInfo()->getId();
return $this->getFileInfo(false)->getId() ?? -1;
}
/**
@ -232,7 +238,7 @@ class Node implements \OCP\Files\Node {
* @throws NotFoundException
*/
public function getPermissions() {
return $this->getFileInfo()->getPermissions();
return $this->getFileInfo(false)->getPermissions();
}
/**
@ -241,7 +247,7 @@ class Node implements \OCP\Files\Node {
* @throws NotFoundException
*/
public function isReadable() {
return $this->getFileInfo()->isReadable();
return $this->getFileInfo(false)->isReadable();
}
/**
@ -250,7 +256,7 @@ class Node implements \OCP\Files\Node {
* @throws NotFoundException
*/
public function isUpdateable() {
return $this->getFileInfo()->isUpdateable();
return $this->getFileInfo(false)->isUpdateable();
}
/**
@ -259,7 +265,7 @@ class Node implements \OCP\Files\Node {
* @throws NotFoundException
*/
public function isDeletable() {
return $this->getFileInfo()->isDeletable();
return $this->getFileInfo(false)->isDeletable();
}
/**
@ -268,7 +274,7 @@ class Node implements \OCP\Files\Node {
* @throws NotFoundException
*/
public function isShareable() {
return $this->getFileInfo()->isShareable();
return $this->getFileInfo(false)->isShareable();
}
/**
@ -277,7 +283,7 @@ class Node implements \OCP\Files\Node {
* @throws NotFoundException
*/
public function isCreatable() {
return $this->getFileInfo()->isCreatable();
return $this->getFileInfo(false)->isCreatable();
}
/**
@ -328,42 +334,42 @@ class Node implements \OCP\Files\Node {
}
public function isMounted() {
return $this->getFileInfo()->isMounted();
return $this->getFileInfo(false)->isMounted();
}
public function isShared() {
return $this->getFileInfo()->isShared();
return $this->getFileInfo(false)->isShared();
}
public function getMimeType() {
return $this->getFileInfo()->getMimetype();
return $this->getFileInfo(false)->getMimetype();
}
public function getMimePart() {
return $this->getFileInfo()->getMimePart();
return $this->getFileInfo(false)->getMimePart();
}
public function getType() {
return $this->getFileInfo()->getType();
return $this->getFileInfo(false)->getType();
}
public function isEncrypted() {
return $this->getFileInfo()->isEncrypted();
return $this->getFileInfo(false)->isEncrypted();
}
public function getMountPoint() {
return $this->getFileInfo()->getMountPoint();
return $this->getFileInfo(false)->getMountPoint();
}
public function getOwner() {
return $this->getFileInfo()->getOwner();
return $this->getFileInfo(false)->getOwner();
}
public function getChecksum() {
}
public function getExtension(): string {
return $this->getFileInfo()->getExtension();
return $this->getFileInfo(false)->getExtension();
}
/**

@ -202,9 +202,9 @@ class Root extends Folder implements IRootFolder {
$path = $this->normalizePath($path);
if ($this->isValidPath($path)) {
$fullPath = $this->getFullPath($path);
$fileInfo = $this->view->getFileInfo($fullPath);
$fileInfo = $this->view->getFileInfo($fullPath, false);
if ($fileInfo) {
return $this->createNode($fullPath, $fileInfo);
return $this->createNode($fullPath, $fileInfo, false);
} else {
throw new NotFoundException($path);
}

@ -1412,11 +1412,7 @@ class View {
if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') {
//add the sizes of other mount points to the folder
$extOnly = ($includeMountPoints === 'ext');
$mounts = Filesystem::getMountManager()->findIn($path);
$info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) {
$subStorage = $mount->getStorage();
return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage);
}));
$this->addSubMounts($info, $extOnly);
}
}
@ -1428,6 +1424,17 @@ class View {
return false;
}
/**
* Extend a FileInfo that was previously requested with `$includeMountPoints = false` to include the sub mounts
*/
public function addSubMounts(FileInfo $info, $extOnly = false): void {
$mounts = Filesystem::getMountManager()->findIn($info->getPath());
$info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) {
$subStorage = $mount->getStorage();
return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage);
}));
}
/**
* get the content of a directory
*

Loading…
Cancel
Save