Skip to content

Commit

Permalink
fix(TreeMapper#getChildren): Add more aggressive per-layer caching
Browse files Browse the repository at this point in the history
Signed-off-by: Marcel Klehr <[email protected]>
  • Loading branch information
marcelklehr committed Jan 3, 2024
1 parent c2213b9 commit 61d9750
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 18 deletions.
37 changes: 22 additions & 15 deletions lib/Db/TreeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -805,24 +805,31 @@ public function getChildren(int $folderId, int $layers = 0): array {
if ($children !== null) {
return $children;
}
$qb = $this->getChildrenQuery[self::TYPE_BOOKMARK];
$this->selectFromType(self::TYPE_BOOKMARK, ['t.index', 't.type'], $qb);
$qb->setParameter('parent_folder', $folderId);
$childBookmarks = $qb->execute()->fetchAll();

$qb = $this->getChildrenQuery[self::TYPE_FOLDER];
$this->selectFromType(self::TYPE_FOLDER, ['t.index', 't.type'], $qb);
$qb->setParameter('parent_folder', $folderId);
$childFolders = $qb->execute()->fetchAll();
$children = $this->treeCache->get(TreeCacheManager::CATEGORY_CHILDREN_LAYER, TreeMapper::TYPE_FOLDER, $folderId);

$qb = $this->getChildrenQuery[self::TYPE_SHARE];
$this->selectFromType(self::TYPE_SHARE, ['t.index', 't.type'], $qb);
$qb->setParameter('parent_folder', $folderId);
$childShares = $qb->execute()->fetchAll();
if ($children === null) {
$qb = $this->getChildrenQuery[self::TYPE_BOOKMARK];
$this->selectFromType(self::TYPE_BOOKMARK, ['t.index', 't.type'], $qb);
$qb->setParameter('parent_folder', $folderId);
$childBookmarks = $qb->execute()->fetchAll();

$children = array_merge($childBookmarks, $childFolders, $childShares);
$indices = array_column($children, 'index');
array_multisort($indices, $children);
$qb = $this->getChildrenQuery[self::TYPE_FOLDER];
$this->selectFromType(self::TYPE_FOLDER, ['t.index', 't.type'], $qb);
$qb->setParameter('parent_folder', $folderId);
$childFolders = $qb->execute()->fetchAll();

$qb = $this->getChildrenQuery[self::TYPE_SHARE];
$this->selectFromType(self::TYPE_SHARE, ['t.index', 't.type'], $qb);
$qb->setParameter('parent_folder', $folderId);
$childShares = $qb->execute()->fetchAll();

$children = array_merge($childBookmarks, $childFolders, $childShares);
$indices = array_column($children, 'index');
array_multisort($indices, $children);

$this->treeCache->set(TreeCacheManager::CATEGORY_CHILDREN_LAYER, TreeMapper::TYPE_FOLDER, $folderId, $children);
}

$children = array_map(function ($child) use ($layers) {
$item = ['type' => $child['type'], 'id' => (int)$child['id'], 'title' => $child['title'], 'userId' => $child['user_id']];
Expand Down
11 changes: 8 additions & 3 deletions lib/Service/TreeCacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class TreeCacheManager implements IEventListener {
public const CATEGORY_SUBFOLDERS = 'subFolders';
public const CATEGORY_FOLDERCOUNT = 'folderCount';
public const CATEGORY_CHILDREN = 'children';
public const CATEGORY_CHILDREN_LAYER = 'children_layer';
public const CATEGORY_CHILDORDER = 'childOrder';

/**
Expand Down Expand Up @@ -87,6 +88,7 @@ public function __construct(FolderMapper $folderMapper, BookmarkMapper $bookmark
$this->caches[self::CATEGORY_SUBFOLDERS] = $cacheFactory->createLocal('bookmarks:'.self::CATEGORY_SUBFOLDERS);
$this->caches[self::CATEGORY_FOLDERCOUNT] = $cacheFactory->createLocal('bookmarks:'.self::CATEGORY_FOLDERCOUNT);
$this->caches[self::CATEGORY_CHILDREN] = $cacheFactory->createLocal('bookmarks:'.self::CATEGORY_CHILDREN);
$this->caches[self::CATEGORY_CHILDREN_LAYER] = $cacheFactory->createLocal('bookmarks:'.self::CATEGORY_CHILDREN_LAYER);
$this->caches[self::CATEGORY_CHILDORDER] = $cacheFactory->createLocal('bookmarks:'.self::CATEGORY_CHILDORDER);
$this->appContainer = $appContainer;
$this->tagMapper = $tagMapper;
Expand Down Expand Up @@ -133,9 +135,12 @@ public function set(string $category, string $type, int $id, $data) {
* @param string $type
* @param int $id
*/
public function remove(string $type, int $id): void {
public function remove(string $type, int $id, array $previousFolders): void {
$key = $this->getCacheKey($type, $id);
foreach ($this->caches as $cache) {
foreach ($this->caches as $type => $cache) {
if (count($previousFolders) !== 0 && ($type === self::CATEGORY_CHILDORDER || $type === self::CATEGORY_CHILDREN_LAYER)) {
continue;
}
$cache->remove($key);
}
}
Expand All @@ -149,7 +154,7 @@ public function invalidateFolder(int $folderId, array $previousFolders = []): vo
// In case we have run into a folder loop
return;
}
$this->remove(TreeMapper::TYPE_FOLDER, $folderId);
$this->remove(TreeMapper::TYPE_FOLDER, $folderId, $previousFolders);
$previousFolders[] = $folderId;

// Invalidate parent
Expand Down

0 comments on commit 61d9750

Please sign in to comment.