optimize getting share types for recent files

Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
Robin Appelman 2021-03-26 17:34:49 +01:00
parent e8221303e9
commit 907e997c99
No known key found for this signature in database
GPG Key ID: 42B69D8A64526EFB
1 changed files with 54 additions and 38 deletions

View File

@ -177,9 +177,9 @@ class ApiController extends Controller {
* @return array * @return array
*/ */
private function formatNodes(array $nodes) { private function formatNodes(array $nodes) {
return array_values(array_map(function (Node $node) { $shareTypesForNodes = $this->getShareTypesForNodes($nodes);
/** @var \OC\Files\Node\Node $shareTypes */ return array_values(array_map(function (Node $node) use ($shareTypesForNodes) {
$shareTypes = $this->getShareTypes($node); $shareTypes = $shareTypesForNodes[$node->getId()] ?? [];
$file = \OCA\Files\Helper::formatFileInfo($node->getFileInfo()); $file = \OCA\Files\Helper::formatFileInfo($node->getFileInfo());
$file['hasPreview'] = $this->previewManager->isAvailable($node); $file['hasPreview'] = $this->previewManager->isAvailable($node);
$parts = explode('/', dirname($node->getPath()), 4); $parts = explode('/', dirname($node->getPath()), 4);
@ -195,6 +195,57 @@ class ApiController extends Controller {
}, $nodes)); }, $nodes));
} }
/**
* Get the share types for each node
*
* @param \OCP\Files\Node[] $nodes
* @return array<int, int[]> list of share types for each fileid
*/
private function getShareTypesForNodes(array $nodes): array {
$userId = $this->userSession->getUser()->getUID();
$requestedShareTypes = [
IShare::TYPE_USER,
IShare::TYPE_GROUP,
IShare::TYPE_LINK,
IShare::TYPE_REMOTE,
IShare::TYPE_EMAIL,
IShare::TYPE_ROOM,
IShare::TYPE_DECK,
];
$shareTypes = [];
$nodeIds = array_map(function (Node $node) {
return $node->getId();
}, $nodes);
foreach ($requestedShareTypes as $shareType) {
$nodesLeft = array_combine($nodeIds, array_fill(0, count($nodeIds), true));
$offset = 0;
// fetch shares until we've either found shares for all nodes or there are no more shares left
while (count($nodesLeft) > 0) {
$shares = $this->shareManager->getSharesBy($userId, $shareType, null, false, 100, $offset);
foreach ($shares as $share) {
$fileId = $share->getNodeId();
if (isset($nodesLeft[$fileId])) {
if (!isset($shareTypes[$fileId])) {
$shareTypes[$fileId] = [];
}
$shareTypes[$fileId][] = $shareType;
unset($nodesLeft[$fileId]);
}
}
if (count($shares) < 100) {
break;
} else {
$offset += count($shares);
}
}
}
return $shareTypes;
}
/** /**
* Returns a list of recently modifed files. * Returns a list of recently modifed files.
* *
@ -208,41 +259,6 @@ class ApiController extends Controller {
return new DataResponse(['files' => $files]); return new DataResponse(['files' => $files]);
} }
/**
* Return a list of share types for outgoing shares
*
* @param Node $node file node
*
* @return int[] array of share types
*/
private function getShareTypes(Node $node) {
$userId = $this->userSession->getUser()->getUID();
$shareTypes = [];
$requestedShareTypes = [
IShare::TYPE_USER,
IShare::TYPE_GROUP,
IShare::TYPE_LINK,
IShare::TYPE_REMOTE,
IShare::TYPE_EMAIL,
IShare::TYPE_ROOM,
IShare::TYPE_DECK,
];
foreach ($requestedShareTypes as $requestedShareType) {
// one of each type is enough to find out about the types
$shares = $this->shareManager->getSharesBy(
$userId,
$requestedShareType,
$node,
false,
1
);
if (!empty($shares)) {
$shareTypes[] = $requestedShareType;
}
}
return $shareTypes;
}
/** /**
* Change the default sort mode * Change the default sort mode
* *