Baloo

idtreedb.cpp
1 /*
2  This file is part of the KDE Baloo project.
3  SPDX-FileCopyrightText: 2015 Vishesh Handa <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7 
8 #include "idtreedb.h"
9 #include "enginedebug.h"
10 #include "postingiterator.h"
11 
12 #include <algorithm>
13 
14 using namespace Baloo;
15 
16 IdTreeDB::IdTreeDB(MDB_dbi dbi, MDB_txn* txn)
17  : m_txn(txn)
18  , m_dbi(dbi)
19 {
20  Q_ASSERT(txn != nullptr);
21  Q_ASSERT(dbi != 0);
22 }
23 
24 MDB_dbi IdTreeDB::create(MDB_txn* txn)
25 {
26  MDB_dbi dbi = 0;
27  int rc = mdb_dbi_open(txn, "idtree", MDB_CREATE | MDB_INTEGERKEY, &dbi);
28  if (rc) {
29  qCWarning(ENGINE) << "IdTreeDB::create" << mdb_strerror(rc);
30  return 0;
31  }
32 
33  return dbi;
34 }
35 
36 MDB_dbi IdTreeDB::open(MDB_txn* txn)
37 {
38  MDB_dbi dbi = 0;
39  int rc = mdb_dbi_open(txn, "idtree", MDB_INTEGERKEY, &dbi);
40  if (rc) {
41  qCWarning(ENGINE) << "IdTreeDB::open" << mdb_strerror(rc);
42  return 0;
43  }
44 
45  return dbi;
46 }
47 
48 void IdTreeDB::set(quint64 docId, const QVector<quint64> &subDocIds)
49 {
50  Q_ASSERT(!subDocIds.contains(0));
51 
52  MDB_val key;
53  key.mv_size = sizeof(quint64);
54  key.mv_data = static_cast<void*>(&docId);
55 
56  int rc;
57  if (subDocIds.empty()) {
58  rc = mdb_del(m_txn, m_dbi, &key, nullptr);
59  if (rc == MDB_NOTFOUND) {
60  rc = 0;
61  }
62  } else {
63  MDB_val val;
64  val.mv_size = subDocIds.size() * sizeof(quint64);
65  val.mv_data = static_cast<void*>(const_cast<quint64*>(subDocIds.constData()));
66 
67  rc = mdb_put(m_txn, m_dbi, &key, &val, 0);
68  }
69  if (rc) {
70  qCWarning(ENGINE) << "IdTreeDB::set" << mdb_strerror(rc);
71  }
72 }
73 
74 QVector<quint64> IdTreeDB::get(quint64 docId)
75 {
76  MDB_val key;
77  key.mv_size = sizeof(quint64);
78  key.mv_data = static_cast<void*>(&docId);
79 
80  MDB_val val{0, nullptr};
81  int rc = mdb_get(m_txn, m_dbi, &key, &val);
82  if (rc) {
83  if (rc != MDB_NOTFOUND) {
84  qCDebug(ENGINE) << "IdTreeDB::get" << docId << mdb_strerror(rc);
85  }
86  return QVector<quint64>();
87  }
88 
89  // FIXME: This still makes a copy of the data. Perhaps we can avoid that?
90  QVector<quint64> list(val.mv_size / sizeof(quint64));
91  memcpy(list.data(), val.mv_data, val.mv_size);
92 
93  return list;
94 }
95 
96 //
97 // Iter
98 //
99 class IdTreePostingIterator : public PostingIterator {
100 public:
101  IdTreePostingIterator(const IdTreeDB& db, const QVector<quint64> &list)
102  : m_db(db), m_pos(-1), m_idList(list) {}
103 
104  quint64 docId() const override {
105  if (m_pos >= 0 && m_pos < m_resultList.size()) {
106  return m_resultList[m_pos];
107  }
108  return 0;
109  }
110 
111  quint64 next() override {
112  if (m_resultList.isEmpty() && m_idList.isEmpty()) {
113  return 0;
114  }
115 
116  if (m_resultList.isEmpty()) {
117  while (!m_idList.isEmpty()) {
118  quint64 id = m_idList.takeLast();
119  m_idList << m_db.get(id);
120  m_resultList << id;
121  }
122  std::sort(m_resultList.begin(), m_resultList.end());
123  m_pos = 0;
124  }
125  else {
126  if (m_pos < m_resultList.size()) {
127  m_pos++;
128  } else {
129  m_resultList.clear();
130  }
131  }
132 
133  if (m_pos < m_resultList.size()) {
134  return m_resultList[m_pos];
135  } else {
136  return 0;
137  }
138  }
139 
140 private:
141  IdTreeDB m_db;
142  int m_pos;
143  QVector<quint64> m_idList;
144  QVector<quint64> m_resultList;
145 };
146 
147 PostingIterator* IdTreeDB::iter(quint64 docId)
148 {
149  Q_ASSERT(docId > 0);
150 
151  QVector<quint64> list = {docId};
152  return new IdTreePostingIterator(*this, list);
153 }
154 
155 QMap<quint64, QVector<quint64>> IdTreeDB::toTestMap() const
156 {
157  MDB_cursor* cursor;
158  mdb_cursor_open(m_txn, m_dbi, &cursor);
159 
160  MDB_val key = {0, nullptr};
161  MDB_val val;
162 
164  while (1) {
165  int rc = mdb_cursor_get(cursor, &key, &val, MDB_NEXT);
166  if (rc == MDB_NOTFOUND) {
167  break;
168  }
169  if (rc) {
170  qCDebug(ENGINE) << "IdTreeDB::toTestMap" << mdb_strerror(rc);
171  break;
172  }
173 
174  const quint64 id = *(static_cast<quint64*>(key.mv_data));
175 
176  QVector<quint64> list(val.mv_size / sizeof(quint64));
177  memcpy(list.data(), val.mv_data, val.mv_size);
178 
179  map.insert(id, list);
180  }
181 
182  mdb_cursor_close(cursor);
183  return map;
184 }
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
const T * constData() const const
A PostingIterator is an abstract base class which can be used to iterate over all the "postings" or "...
Implements storage for docIds without any associated data Instantiated for:
Definition: coding.cpp:11
bool contains(const T &value) const const
int size() const const
QFuture< void > map(Sequence &sequence, MapFunctor function)
QAction * next(const QObject *recvr, const char *slot, QObject *parent)
bool empty() const const
virtual QVariant get(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Nov 29 2023 03:56:26 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.