From 94e2af0302185d7ec2660b120643bc7eb5a2466c Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Wed, 13 Aug 2025 16:15:31 +0200 Subject: [PATCH] perf(comments): Also cache the comments count Since we now have an easy way to fetch the comments count. Signed-off-by: Carl Schwan --- .../Sabre/CommentPropertiesPlugin.php | 47 +++++++++++++------ .../Sabre/CommentsPropertiesPluginTest.php | 4 +- lib/private/Comments/Manager.php | 4 +- lib/public/Comments/ICommentsManager.php | 2 +- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/apps/dav/lib/Connector/Sabre/CommentPropertiesPlugin.php b/apps/dav/lib/Connector/Sabre/CommentPropertiesPlugin.php index ef9bd1ae472..de0a4aa972d 100644 --- a/apps/dav/lib/Connector/Sabre/CommentPropertiesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/CommentPropertiesPlugin.php @@ -22,6 +22,7 @@ class CommentPropertiesPlugin extends ServerPlugin { protected ?Server $server = null; private array $cachedUnreadCount = []; + private array $cachedCount = []; private array $cachedDirectories = []; public function __construct( @@ -48,7 +49,11 @@ class CommentPropertiesPlugin extends ServerPlugin { $this->server->on('propFind', [$this, 'handleGetProperties']); } - private function cacheDirectory(Directory $directory): void { + private function cacheDirectory(Directory $directory, PropFind $propFind): void { + if (is_null($propFind->getStatus(self::PROPERTY_NAME_UNREAD)) && is_null($propFind->getStatus(self::PROPERTY_NAME_COUNT))) { + return; + } + $children = $directory->getChildren(); $ids = []; @@ -66,24 +71,39 @@ class CommentPropertiesPlugin extends ServerPlugin { } $ids[] = (string)$directory->getId(); - $unread = $this->commentsManager->getNumberOfUnreadCommentsForObjects('files', $ids, $this->userSession->getUser()); + if (!is_null($propFind->getStatus(self::PROPERTY_NAME_UNREAD))) { + $user = $this->userSession->getUser(); + if ($user) { + $unread = $this->commentsManager->getNumberOfUnreadCommentsForObjects('files', $ids, $user); + foreach ($unread as $id => $count) { + $this->cachedUnreadCount[(int)$id] = $count; + } + } else { + foreach ($ids as $id) { + $this->cachedUnreadCount[(int)$id] = null; + } + } + } - foreach ($unread as $id => $count) { - $this->cachedUnreadCount[(int)$id] = $count; + if (!is_null($propFind->getStatus(self::PROPERTY_NAME_COUNT))) { + $commentCounts = $this->commentsManager->getNumberOfCommentsForObjects('files', $ids); + foreach ($commentCounts as $id => $count) { + $this->cachedCount[(int)$id] = $count; + } } + } - private function preloadCollection(PropFind $propFind, ICollection $collection): - void { + private function preloadCollection(PropFind $propFind, ICollection $collection): void { if (!($collection instanceof Directory)) { return; } $collectionPath = $collection->getPath(); - if (!isset($this->cachedDirectories[$collectionPath]) && $propFind->getStatus( - self::PROPERTY_NAME_UNREAD - ) !== null) { - $this->cacheDirectory($collection); + if (!isset($this->cachedDirectories[$collectionPath]) && ( + $propFind->getStatus(self::PROPERTY_NAME_UNREAD) !== null + || $propFind->getStatus(self::PROPERTY_NAME_COUNT) !== null)) { + $this->cacheDirectory($collection, $propFind); $this->cachedDirectories[$collectionPath] = true; } } @@ -105,7 +125,7 @@ class CommentPropertiesPlugin extends ServerPlugin { } $propFind->handle(self::PROPERTY_NAME_COUNT, function () use ($node): int { - return $this->commentsManager->getNumberOfCommentsForObject('files', (string)$node->getId()); + return $this->cachedCount[$node->getId()] ?? $this->commentsManager->getNumberOfCommentsForObject('files', (string)$node->getId()); }); $propFind->handle(self::PROPERTY_NAME_HREF, function () use ($node): ?string { @@ -141,8 +161,7 @@ class CommentPropertiesPlugin extends ServerPlugin { return null; } - $lastRead = $this->commentsManager->getReadMark('files', (string)$node->getId(), $user); - - return $this->commentsManager->getNumberOfCommentsForObject('files', (string)$node->getId(), $lastRead); + $objectId = (string)$node->getId(); + return $this->commentsManager->getNumberOfUnreadCommentsForObjects('files', [$objectId], $user)[$objectId]; } } diff --git a/apps/dav/tests/unit/Connector/Sabre/CommentsPropertiesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/CommentsPropertiesPluginTest.php index a934d6401c2..9bec46019b9 100644 --- a/apps/dav/tests/unit/Connector/Sabre/CommentsPropertiesPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/CommentsPropertiesPluginTest.php @@ -104,8 +104,8 @@ class CommentsPropertiesPluginTest extends \Test\TestCase { ->willReturn($user); $this->commentsManager->expects($this->any()) - ->method('getNumberOfCommentsForObject') - ->willReturn(42); + ->method('getNumberOfUnreadCommentsForObjects') + ->willReturn(['4567' => 42]); $unread = $this->plugin->getUnreadCount($node); if (is_null($user)) { diff --git a/lib/private/Comments/Manager.php b/lib/private/Comments/Manager.php index e307d1c7322..8a4fc4183b9 100644 --- a/lib/private/Comments/Manager.php +++ b/lib/private/Comments/Manager.php @@ -632,7 +632,7 @@ class Manager implements ICommentsManager { /** @inheritDoc */ public function getNumberOfCommentsForObjects(string $objectType, array $objectIds, ?\DateTime $notOlderThan = null, string $verb = ''): array { $qb = $this->dbConn->getQueryBuilder(); - $query = $qb->select($qb->func()->count('id'), 'object_id') + $query = $qb->select($qb->func()->count('id', 'num_comments'), 'object_id') ->from('comments') ->where($qb->expr()->eq('object_type', $qb->createNamedParameter($objectType, IQueryBuilder::PARAM_STR))) ->andWhere($qb->expr()->in('object_id', $qb->createNamedParameter($objectIds, IQueryBuilder::PARAM_STR_ARRAY))); @@ -651,7 +651,7 @@ class Manager implements ICommentsManager { $comments = array_fill_keys($objectIds, 0); $resultStatement = $query->execute(); while ($data = $resultStatement->fetch()) { - $comments[$data[1]] = (int)$data[0]; + $comments[$data['object_id']] = (int)$data['num_comments']; } $resultStatement->closeCursor(); diff --git a/lib/public/Comments/ICommentsManager.php b/lib/public/Comments/ICommentsManager.php index fd0465380a0..43402414c57 100644 --- a/lib/public/Comments/ICommentsManager.php +++ b/lib/public/Comments/ICommentsManager.php @@ -191,7 +191,7 @@ interface ICommentsManager { * @param $objectIds string[] the ids of the object * @param \DateTime|null $notOlderThan optional, timestamp of the oldest comments * that may be returned - * @param string $verb Limit the verb of the comment - Added in 14.0.0 + * @param string $verb Limit the verb of the comment * @return array * @since 32.0.0 */