diff options
author | Joas Schilling <coding@schilljs.com> | 2024-02-08 21:27:49 +0100 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2024-02-08 21:28:14 +0100 |
commit | 5739513b2d7aa7bb05fc00e55fb3dee0d31bb660 (patch) | |
tree | c68d1021dc1a8822fecdf492a23de7550d83d2cb | |
parent | 6657f044b120b17954c138021aa5931d1a2a2280 (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.php | 42 |
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', |