Akonadi

collectiontreecache.h
1/*
2 SPDX-FileCopyrightText: 2017 Daniel Vrátil <dvratil@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#pragma once
8
9#include "akthread.h"
10#include "entities.h"
11
12#include "private/tristate_p.h"
13
14#include <QHash>
15#include <QList>
16#include <QReadWriteLock>
17
18namespace Akonadi
19{
20class Scope;
21
22namespace Server
23{
24class CommandContext;
25
26class CollectionTreeCache : public AkThread
27{
29
30protected:
31 class Node
32 {
33 public:
34 explicit Node();
35 explicit Node(const Collection &query);
36
37 ~Node();
38
39 void appendChild(Node *child);
40 void removeChild(Node *child);
41
42 Node *parent = nullptr;
43 QList<Node *> children;
44 QAtomicInt lruCounter;
45 qint64 id;
46
47 Collection collection;
48 };
49
50public:
51 explicit CollectionTreeCache();
52 ~CollectionTreeCache() override;
53
55 retrieveCollections(const Scope &scope, int depth, int ancestorDepth, const QString &resource = QString(), CommandContext *context = nullptr) const;
56
57public Q_SLOTS:
58 void collectionAdded(const Collection &col);
59 void collectionChanged(const Collection &col);
60 void collectionMoved(const Collection &col);
61 void collectionRemoved(const Collection &col);
62
63protected:
64 void init() override;
65 void quit() override;
66
67 Node *findNode(const QString &rid, const QString &resource) const;
68
69 template<typename Predicate>
70 Node *findNode(Node *root, Predicate pred) const;
71
72 QList<Collection> retrieveCollections(Node *root, int depth, int ancestorDepth) const;
73
74protected:
75 mutable QReadWriteLock mLock;
76
77 Node *mRoot = nullptr;
78
79 QHash<qint64 /* col ID */, Node *> mNodeLookup;
80};
81
82// Non-recursive depth-first tree traversal, looking for first Node matching the predicate
83template<typename Predicate>
84CollectionTreeCache::Node *CollectionTreeCache::findNode(Node *root, Predicate pred) const
85{
86 QList<Node *> toVisit = {root};
87 // We expect a single subtree to not contain more than 1/4 of all collections,
88 // which is an arbitrary guess, but should be good enough for most cases.
89 toVisit.reserve(mNodeLookup.size() / 4);
90 while (!toVisit.isEmpty()) {
91 auto node = toVisit.takeFirst();
92 if (pred(node)) {
93 return node;
94 }
95
96 for (auto child : std::as_const(node->children)) {
97 toVisit.prepend(child);
98 }
99 }
100
101 return nullptr;
102}
103
104} // namespace Server
105} // namespace Akonadi
Helper integration between Akonadi and Qt.
qsizetype size() const const
bool isEmpty() const const
void prepend(parameter_type value)
void reserve(qsizetype size)
value_type takeFirst()
Q_OBJECTQ_OBJECT
Q_SLOTSQ_SLOTS
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:31:59 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.