diff options
Diffstat (limited to 'common/storage_lmdb.cpp')
-rw-r--r-- | common/storage_lmdb.cpp | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp index a048a71..3073d37 100644 --- a/common/storage_lmdb.cpp +++ b/common/storage_lmdb.cpp | |||
@@ -169,7 +169,8 @@ void Storage::NamedDatabase::remove(const QByteArray &k, | |||
169 | 169 | ||
170 | int Storage::NamedDatabase::scan(const QByteArray &k, | 170 | int Storage::NamedDatabase::scan(const QByteArray &k, |
171 | const std::function<bool(const QByteArray &key, const QByteArray &value)> &resultHandler, | 171 | const std::function<bool(const QByteArray &key, const QByteArray &value)> &resultHandler, |
172 | const std::function<void(const Storage::Error &error)> &errorHandler) const | 172 | const std::function<void(const Storage::Error &error)> &errorHandler, |
173 | bool findSubstringKeys) const | ||
173 | { | 174 | { |
174 | if (!d || !d->transaction) { | 175 | if (!d || !d->transaction) { |
175 | //Not an error. We rely on this to read nothing from non-existing databases. | 176 | //Not an error. We rely on this to read nothing from non-existing databases. |
@@ -193,14 +194,25 @@ int Storage::NamedDatabase::scan(const QByteArray &k, | |||
193 | 194 | ||
194 | int numberOfRetrievedValues = 0; | 195 | int numberOfRetrievedValues = 0; |
195 | 196 | ||
196 | if (k.isEmpty() || d->allowDuplicates) { | 197 | if (k.isEmpty() || d->allowDuplicates || findSubstringKeys) { |
197 | if ((rc = mdb_cursor_get(cursor, &key, &data, d->allowDuplicates ? MDB_SET : MDB_FIRST)) == 0) { | 198 | MDB_cursor_op op = d->allowDuplicates ? MDB_SET : MDB_FIRST; |
198 | numberOfRetrievedValues++; | 199 | if (findSubstringKeys) { |
199 | if (resultHandler(QByteArray::fromRawData((char*)key.mv_data, key.mv_size), QByteArray::fromRawData((char*)data.mv_data, data.mv_size))) { | 200 | op = MDB_SET_RANGE; |
200 | while ((rc = mdb_cursor_get(cursor, &key, &data, d->allowDuplicates ? MDB_NEXT_DUP : MDB_NEXT)) == 0) { | 201 | } |
201 | numberOfRetrievedValues++; | 202 | if ((rc = mdb_cursor_get(cursor, &key, &data, op)) == 0) { |
202 | if (!resultHandler(QByteArray::fromRawData((char*)key.mv_data, key.mv_size), QByteArray::fromRawData((char*)data.mv_data, data.mv_size))) { | 203 | //The first lookup will find a key that is equal or greather than our key |
203 | break; | 204 | if (QByteArray::fromRawData((char*)key.mv_data, key.mv_size).startsWith(k)) { |
205 | numberOfRetrievedValues++; | ||
206 | if (resultHandler(QByteArray::fromRawData((char*)key.mv_data, key.mv_size), QByteArray::fromRawData((char*)data.mv_data, data.mv_size))) { | ||
207 | MDB_cursor_op nextOp = d->allowDuplicates ? MDB_NEXT_DUP : MDB_NEXT; | ||
208 | while ((rc = mdb_cursor_get(cursor, &key, &data, nextOp)) == 0) { | ||
209 | //Every consequent lookup simply iterates through the list | ||
210 | if (QByteArray::fromRawData((char*)key.mv_data, key.mv_size).startsWith(k)) { | ||
211 | numberOfRetrievedValues++; | ||
212 | if (!resultHandler(QByteArray::fromRawData((char*)key.mv_data, key.mv_size), QByteArray::fromRawData((char*)data.mv_data, data.mv_size))) { | ||
213 | break; | ||
214 | } | ||
215 | } | ||
204 | } | 216 | } |
205 | } | 217 | } |
206 | } | 218 | } |
@@ -226,6 +238,23 @@ int Storage::NamedDatabase::scan(const QByteArray &k, | |||
226 | 238 | ||
227 | return numberOfRetrievedValues; | 239 | return numberOfRetrievedValues; |
228 | } | 240 | } |
241 | void Storage::NamedDatabase::findLatest(const QByteArray &uid, | ||
242 | const std::function<void(const QByteArray &key, const QByteArray &value)> &resultHandler, | ||
243 | const std::function<void(const Storage::Error &error)> &errorHandler) const | ||
244 | { | ||
245 | QByteArray latestKey; | ||
246 | scan(uid, [&](const QByteArray &key, const QByteArray &value) -> bool { | ||
247 | latestKey = key; | ||
248 | return true; | ||
249 | }, | ||
250 | errorHandler, true); | ||
251 | |||
252 | scan(latestKey, [=](const QByteArray &key, const QByteArray &value) -> bool { | ||
253 | resultHandler(key, value); | ||
254 | return false; | ||
255 | }, | ||
256 | errorHandler); | ||
257 | } | ||
229 | 258 | ||
230 | 259 | ||
231 | 260 | ||