summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2024-02-08 21:27:49 +0100
committerJoas Schilling <coding@schilljs.com>2024-02-08 21:28:14 +0100
commit5739513b2d7aa7bb05fc00e55fb3dee0d31bb660 (patch)
treec68d1021dc1a8822fecdf492a23de7550d83d2cb
parent6657f044b120b17954c138021aa5931d1a2a2280 (diff)
perf(sharing): Cache if a user has no talk shares to save 2 queriesperf/noid/cache-if-a-user-has-no-talk-shares
… every time the filesystem is set up Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r--lib/Share/RoomShareProvider.php42
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php
index 802b5f24b..7ddf49936 100644
--- a/lib/Share/RoomShareProvider.php
+++ b/lib/Share/RoomShareProvider.php
@@ -44,6 +44,7 @@ use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Folder;
use OCP\Files\IMimeTypeLoader;
use OCP\Files\Node;
+use OCP\ICacheFactory;
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\Security\ISecureRandom;
@@ -83,6 +84,7 @@ class RoomShareProvider implements IShareProvider {
protected ITimeFactory $timeFactory,
protected IL10N $l,
protected IMimeTypeLoader $mimeTypeLoader,
+ protected ICacheFactory $cacheFactory,
) {
$this->sharesByIdCache = new CappedMemoryCache();
}
@@ -215,6 +217,9 @@ class RoomShareProvider implements IShareProvider {
$insert->executeStatement();
$id = $insert->getLastInsertId();
+ $genCache = $this->cacheFactory->createDistributed('talk/shares');
+ $genCache->set('generationId', $id);
+
return $id;
}
@@ -805,6 +810,35 @@ class RoomShareProvider implements IShareProvider {
public function getSharedWith($userId, $shareType, $node, $limit, $offset): array {
$allRooms = $this->manager->getRoomTokensForUser($userId);
+ $cacheKey = null;
+ $cacheKeySuffix = $node === null && $limit === -1 && $offset === 0 ? sha1(json_encode($allRooms)) : null;
+ if ($cacheKeySuffix) {
+ $genCache = $this->cacheFactory->createDistributed('talk/shares');
+ $generationId = $genCache->get('generationId');
+ if ($generationId !== null) {
+ $localCache = $this->cacheFactory->createLocal('talk/shares');
+ $cacheKey = $generationId . '$' . $cacheKeySuffix;
+ $cachedData = $localCache->get($cacheKey);
+ if ($cachedData === 'empty') {
+ return [];
+ }
+ } else {
+ // To warm up the cache, we query the maximum ID from oc_share
+ // and store it as generationId in the distributed cache.
+ $query = $this->dbConnection->getQueryBuilder();
+ $query->select('id')
+ ->from('share')
+ ->orderBy('id', 'DESC')
+ ->setMaxResults(1);
+ $result = $query->executeQuery();
+ $generationId = (int) $result->fetchOne();
+ $result->closeCursor();
+
+ $genCache->set('generationId', $generationId);
+ $cacheKey = $generationId . '$' . $cacheKeySuffix;
+ }
+ }
+
$query = $this->dbConnection->getQueryBuilder();
$query->select('s.*')
->from('share', 's')
@@ -842,6 +876,14 @@ class RoomShareProvider implements IShareProvider {
$result->closeCursor();
}
+ if (empty($shareRows) && $cacheKey) {
+ if (!isset($localCache)) {
+ $localCache = $this->cacheFactory->createLocal('talk/shares');
+ }
+ $localCache->set($cacheKey, 'empty', 300);
+ return [];
+ }
+
$queryFileCache = $this->dbConnection->getQueryBuilder();
$queryFileCache->select('f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',