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 "enginedebug.h" |
9 | #include "positiondb.h" |
10 | #include "positioncodec.h" |
11 | #include "positioninfo.h" |
12 | #include "postingiterator.h" |
13 | #include "vectorpositioninfoiterator.h" |
14 | |
15 | using namespace Baloo; |
16 | |
17 | PositionDB::PositionDB(MDB_dbi dbi, MDB_txn* txn) |
18 | : m_txn(txn) |
19 | , m_dbi(dbi) |
20 | { |
21 | Q_ASSERT(txn != nullptr); |
22 | Q_ASSERT(dbi != 0); |
23 | } |
24 | |
25 | PositionDB::~PositionDB() |
26 | { |
27 | } |
28 | |
29 | MDB_dbi PositionDB::create(MDB_txn* txn) |
30 | { |
31 | MDB_dbi dbi = 0; |
32 | int rc = mdb_dbi_open(txn, name: "positiondb" , MDB_CREATE, dbi: &dbi); |
33 | if (rc) { |
34 | qCWarning(ENGINE) << "PositionDB::create" << mdb_strerror(err: rc); |
35 | return 0; |
36 | } |
37 | |
38 | return dbi; |
39 | } |
40 | |
41 | MDB_dbi PositionDB::open(MDB_txn* txn) |
42 | { |
43 | MDB_dbi dbi = 0; |
44 | int rc = mdb_dbi_open(txn, name: "positiondb" , flags: 0, dbi: &dbi); |
45 | if (rc) { |
46 | qCWarning(ENGINE) << "PositionDB::open" << mdb_strerror(err: rc); |
47 | return 0; |
48 | } |
49 | |
50 | return dbi; |
51 | } |
52 | |
53 | void PositionDB::put(const QByteArray& term, const QVector<PositionInfo>& list) |
54 | { |
55 | Q_ASSERT(!term.isEmpty()); |
56 | Q_ASSERT(!list.isEmpty()); |
57 | |
58 | MDB_val key; |
59 | key.mv_size = term.size(); |
60 | key.mv_data = static_cast<void*>(const_cast<char*>(term.constData())); |
61 | |
62 | QByteArray data = PositionCodec::encode(list); |
63 | |
64 | MDB_val val; |
65 | val.mv_size = data.size(); |
66 | val.mv_data = static_cast<void*>(data.data()); |
67 | |
68 | int rc = mdb_put(txn: m_txn, dbi: m_dbi, key: &key, data: &val, flags: 0); |
69 | if (rc) { |
70 | qCWarning(ENGINE) << "PositionDB::put" << mdb_strerror(err: rc); |
71 | } |
72 | } |
73 | |
74 | QVector<PositionInfo> PositionDB::get(const QByteArray& term) |
75 | { |
76 | Q_ASSERT(!term.isEmpty()); |
77 | |
78 | MDB_val key; |
79 | key.mv_size = term.size(); |
80 | key.mv_data = static_cast<void*>(const_cast<char*>(term.constData())); |
81 | |
82 | MDB_val val{.mv_size: 0, .mv_data: nullptr}; |
83 | int rc = mdb_get(txn: m_txn, dbi: m_dbi, key: &key, data: &val); |
84 | if (rc) { |
85 | if (rc != MDB_NOTFOUND) { |
86 | qCDebug(ENGINE) << "PositionDB::get" << term << mdb_strerror(err: rc); |
87 | } |
88 | return QVector<PositionInfo>(); |
89 | } |
90 | |
91 | QByteArray data = QByteArray::fromRawData(data: static_cast<char*>(val.mv_data), size: val.mv_size); |
92 | |
93 | return PositionCodec::decode(arr: data); |
94 | } |
95 | |
96 | void PositionDB::del(const QByteArray& term) |
97 | { |
98 | Q_ASSERT(!term.isEmpty()); |
99 | |
100 | MDB_val key; |
101 | key.mv_size = term.size(); |
102 | key.mv_data = static_cast<void*>(const_cast<char*>(term.constData())); |
103 | |
104 | int rc = mdb_del(txn: m_txn, dbi: m_dbi, key: &key, data: nullptr); |
105 | if (rc != 0 && rc != MDB_NOTFOUND) { |
106 | qCDebug(ENGINE) << "PositionDB::del" << term << mdb_strerror(err: rc); |
107 | } |
108 | } |
109 | |
110 | // |
111 | // Query |
112 | // |
113 | |
114 | VectorPositionInfoIterator* PositionDB::iter(const QByteArray& term) |
115 | { |
116 | Q_ASSERT(!term.isEmpty()); |
117 | |
118 | MDB_val key; |
119 | key.mv_size = term.size(); |
120 | key.mv_data = static_cast<void*>(const_cast<char*>(term.constData())); |
121 | |
122 | MDB_val val{.mv_size: 0, .mv_data: nullptr}; |
123 | int rc = mdb_get(txn: m_txn, dbi: m_dbi, key: &key, data: &val); |
124 | if (rc) { |
125 | qCDebug(ENGINE) << "PositionDB::iter" << term << mdb_strerror(err: rc); |
126 | return nullptr; |
127 | } |
128 | |
129 | QByteArray ba(static_cast<char*>(val.mv_data), val.mv_size); |
130 | return new VectorPositionInfoIterator(PositionCodec::decode(arr: ba)); |
131 | } |
132 | |
133 | QMap<QByteArray, QVector<PositionInfo>> PositionDB::toTestMap() const |
134 | { |
135 | MDB_cursor* cursor; |
136 | mdb_cursor_open(txn: m_txn, dbi: m_dbi, cursor: &cursor); |
137 | |
138 | MDB_val key = {.mv_size: 0, .mv_data: nullptr}; |
139 | MDB_val val; |
140 | |
141 | QMap<QByteArray, QVector<PositionInfo>> map; |
142 | while (1) { |
143 | int rc = mdb_cursor_get(cursor, key: &key, data: &val, op: MDB_NEXT); |
144 | if (rc == MDB_NOTFOUND) { |
145 | break; |
146 | } |
147 | if (rc) { |
148 | qCDebug(ENGINE) << "PositionDB::toTestMap" << mdb_strerror(err: rc); |
149 | break; |
150 | } |
151 | |
152 | const QByteArray ba(static_cast<char*>(key.mv_data), key.mv_size); |
153 | const QByteArray data(static_cast<char*>(val.mv_data), val.mv_size); |
154 | const QVector<PositionInfo> vinfo = PositionCodec().decode(arr: data); |
155 | map.insert(key: ba, value: vinfo); |
156 | } |
157 | |
158 | mdb_cursor_close(cursor); |
159 | return map; |
160 | } |
161 | |