Akonadi

collectiontreecache.h
1 /*
2  Copyright (c) 2017 Daniel Vrátil <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #ifndef COLLECTIONTREECACHE_H
21 #define COLLECTIONTREECACHE_H
22 
23 #include "akthread.h"
24 #include "entities.h"
25 
26 #include <private/tristate_p.h>
27 
28 #include <QReadWriteLock>
29 #include <QVector>
30 #include <QHash>
31 
32 
33 namespace Akonadi {
34 
35 class Scope;
36 
37 namespace Server {
38 
39 class CommandContext;
40 
41 class CollectionTreeCache : public AkThread
42 {
43  Q_OBJECT
44 
45 protected:
46  class Node
47  {
48  public:
49  explicit Node();
50  explicit Node(const Collection &query);
51 
52  ~Node();
53 
54  void appendChild(Node *child);
55  void removeChild(Node *child);
56 
57  Node *parent = nullptr;
58  QVector<Node *> children;
59  QAtomicInt lruCounter;
60  qint64 id;
61 
62  Collection collection;
63  };
64 
65 public:
66  explicit CollectionTreeCache();
67  ~CollectionTreeCache() override;
68 
69  QVector<Collection> retrieveCollections(const Scope &scope,
70  int depth, int ancestorDepth,
71  const QString &resource = QString(),
72  CommandContext *context = nullptr) const;
73 
74 public Q_SLOTS:
75  void collectionAdded(const Collection &col);
76  void collectionChanged(const Collection &col);
77  void collectionMoved(const Collection &col);
78  void collectionRemoved(const Collection &col);
79 
80 protected:
81  void init() override;
82  void quit() override;
83 
84  Node *findNode(const QString &rid, const QString &resource) const;
85 
86  template<typename Predicate>
87  Node *findNode(Node *root, Predicate pred) const;
88 
89  QVector<Collection> retrieveCollections(Node *root, int depth, int ancestorDepth) const;
90 
91 protected:
92  mutable QReadWriteLock mLock;
93 
94  Node *mRoot = nullptr;
95 
96  QHash<qint64 /* col ID */, Node *> mNodeLookup;
97 };
98 
99 
100 // Non-recursive depth-first tree traversal, looking for first Node matching the predicate
101 template<typename Predicate>
102 CollectionTreeCache::Node *CollectionTreeCache::findNode(Node *root, Predicate pred) const
103 {
104  QList<Node *> toVisit = { root };
105  // We expect a single subtree to not contain more than 1/4 of all collections,
106  // which is an arbitrary guess, but should be good enough for most cases.
107  toVisit.reserve(mNodeLookup.size() / 4);
108  while (!toVisit.isEmpty()) {
109  auto node = toVisit.takeFirst();
110  if (pred(node)) {
111  return node;
112  }
113 
114  for (auto child : qAsConst(node->children)) {
115  toVisit.prepend(child);
116  }
117  }
118 
119  return nullptr;
120 }
121 
122 } // namespace Server
123 } // namespace Akonadi
124 #endif // COLLECTIONTREECACHE
void reserve(int alloc)
QUICKADDONS_EXPORT void init()
Q_OBJECTQ_OBJECT
bool isEmpty() const const
T takeFirst()
Helper integration between Akonadi and Qt.
void prepend(const T &value)
const QList< QKeySequence > & quit()
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon May 25 2020 22:46:08 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.