Akonadi

collectiontreecache.h
1 /*
2  SPDX-FileCopyrightText: 2017 Daniel Vr├ítil <[email protected]>
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 <QReadWriteLock>
16 #include <QVector>
17 
18 namespace Akonadi
19 {
20 class Scope;
21 
22 namespace Server
23 {
24 class CommandContext;
25 
26 class CollectionTreeCache : public AkThread
27 {
28  Q_OBJECT
29 
30 protected:
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  QVector<Node *> children;
44  QAtomicInt lruCounter;
45  qint64 id;
46 
47  Collection collection;
48  };
49 
50 public:
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 
57 public 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 
63 protected:
64  void init() override;
65  void quit() override;
66 
67  Node *findNode(const QString &rid, const QString &resource) const;
68 
69  template<typename Predicate> Node *findNode(Node *root, Predicate pred) const;
70 
71  QVector<Collection> retrieveCollections(Node *root, int depth, int ancestorDepth) const;
72 
73 protected:
74  mutable QReadWriteLock mLock;
75 
76  Node *mRoot = nullptr;
77 
78  QHash<qint64 /* col ID */, Node *> mNodeLookup;
79 };
80 
81 // Non-recursive depth-first tree traversal, looking for first Node matching the predicate
82 template<typename Predicate> CollectionTreeCache::Node *CollectionTreeCache::findNode(Node *root, Predicate pred) const
83 {
84  QList<Node *> toVisit = {root};
85  // We expect a single subtree to not contain more than 1/4 of all collections,
86  // which is an arbitrary guess, but should be good enough for most cases.
87  toVisit.reserve(mNodeLookup.size() / 4);
88  while (!toVisit.isEmpty()) {
89  auto node = toVisit.takeFirst();
90  if (pred(node)) {
91  return node;
92  }
93 
94  for (auto child : std::as_const(node->children)) {
95  toVisit.prepend(child);
96  }
97  }
98 
99  return nullptr;
100 }
101 
102 } // namespace Server
103 } // namespace Akonadi
Q_OBJECTQ_OBJECT
Q_SLOTSQ_SLOTS
QCA_EXPORT void init()
Definition: item.h:32
void reserve(int alloc)
void prepend(const T &value)
T takeFirst()
bool isEmpty() const const
Definition: nodetree.h:12
const QList< QKeySequence > & quit()
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Jul 2 2022 06:41:47 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.