Baloo

idtreedb.cpp
1/*
2 This file is part of the KDE Baloo project.
3 SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org>
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
14using namespace Baloo;
15
16IdTreeDB::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
24MDB_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
36MDB_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
48void 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
74QVector<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//
99class IdTreePostingIterator : public PostingIterator {
100public:
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
140private:
141 IdTreeDB m_db;
142 int m_pos;
143 QVector<quint64> m_idList;
144 QVector<quint64> m_resultList;
145};
146
147PostingIterator* IdTreeDB::iter(quint64 docId)
148{
149 Q_ASSERT(docId > 0);
150
151 QVector<quint64> list = {docId};
152 return new IdTreePostingIterator(*this, list);
153}
154
155QMap<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}
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
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QAction * next(const QObject *recvr, const char *slot, QObject *parent)
const_pointer constData() const const
bool contains(const AT &value) const const
pointer data()
bool empty() const const
qsizetype size() const const
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 26 2024 11:52:28 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.