diff options
Diffstat (limited to 'common/storage_lmdb.cpp')
-rw-r--r-- | common/storage_lmdb.cpp | 100 |
1 files changed, 51 insertions, 49 deletions
diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp index 6f11af3..e418472 100644 --- a/common/storage_lmdb.cpp +++ b/common/storage_lmdb.cpp | |||
@@ -39,6 +39,7 @@ SINK_DEBUG_AREA("storage") | |||
39 | // SINK_DEBUG_COMPONENT(d->storageRoot.toLatin1() + '/' + d->name.toLatin1()) | 39 | // SINK_DEBUG_COMPONENT(d->storageRoot.toLatin1() + '/' + d->name.toLatin1()) |
40 | 40 | ||
41 | namespace Sink { | 41 | namespace Sink { |
42 | namespace Storage { | ||
42 | 43 | ||
43 | QMutex sMutex; | 44 | QMutex sMutex; |
44 | QHash<QString, MDB_env *> sEnvironments; | 45 | QHash<QString, MDB_env *> sEnvironments; |
@@ -47,17 +48,17 @@ int getErrorCode(int e) | |||
47 | { | 48 | { |
48 | switch (e) { | 49 | switch (e) { |
49 | case MDB_NOTFOUND: | 50 | case MDB_NOTFOUND: |
50 | return Storage::ErrorCodes::NotFound; | 51 | return DataStore::ErrorCodes::NotFound; |
51 | default: | 52 | default: |
52 | break; | 53 | break; |
53 | } | 54 | } |
54 | return -1; | 55 | return -1; |
55 | } | 56 | } |
56 | 57 | ||
57 | class Storage::NamedDatabase::Private | 58 | class DataStore::NamedDatabase::Private |
58 | { | 59 | { |
59 | public: | 60 | public: |
60 | Private(const QByteArray &_db, bool _allowDuplicates, const std::function<void(const Storage::Error &error)> &_defaultErrorHandler, const QString &_name, MDB_txn *_txn) | 61 | Private(const QByteArray &_db, bool _allowDuplicates, const std::function<void(const DataStore::Error &error)> &_defaultErrorHandler, const QString &_name, MDB_txn *_txn) |
61 | : db(_db), transaction(_txn), allowDuplicates(_allowDuplicates), defaultErrorHandler(_defaultErrorHandler), name(_name) | 62 | : db(_db), transaction(_txn), allowDuplicates(_allowDuplicates), defaultErrorHandler(_defaultErrorHandler), name(_name) |
62 | { | 63 | { |
63 | } | 64 | } |
@@ -70,10 +71,10 @@ public: | |||
70 | MDB_txn *transaction; | 71 | MDB_txn *transaction; |
71 | MDB_dbi dbi; | 72 | MDB_dbi dbi; |
72 | bool allowDuplicates; | 73 | bool allowDuplicates; |
73 | std::function<void(const Storage::Error &error)> defaultErrorHandler; | 74 | std::function<void(const DataStore::Error &error)> defaultErrorHandler; |
74 | QString name; | 75 | QString name; |
75 | 76 | ||
76 | bool openDatabase(bool readOnly, std::function<void(const Storage::Error &error)> errorHandler) | 77 | bool openDatabase(bool readOnly, std::function<void(const DataStore::Error &error)> errorHandler) |
77 | { | 78 | { |
78 | unsigned int flags = 0; | 79 | unsigned int flags = 0; |
79 | if (!readOnly) { | 80 | if (!readOnly) { |
@@ -97,20 +98,20 @@ public: | |||
97 | } | 98 | } |
98 | }; | 99 | }; |
99 | 100 | ||
100 | Storage::NamedDatabase::NamedDatabase() : d(nullptr) | 101 | DataStore::NamedDatabase::NamedDatabase() : d(nullptr) |
101 | { | 102 | { |
102 | } | 103 | } |
103 | 104 | ||
104 | Storage::NamedDatabase::NamedDatabase(NamedDatabase::Private *prv) : d(prv) | 105 | DataStore::NamedDatabase::NamedDatabase(NamedDatabase::Private *prv) : d(prv) |
105 | { | 106 | { |
106 | } | 107 | } |
107 | 108 | ||
108 | Storage::NamedDatabase::NamedDatabase(NamedDatabase &&other) : d(nullptr) | 109 | DataStore::NamedDatabase::NamedDatabase(NamedDatabase &&other) : d(nullptr) |
109 | { | 110 | { |
110 | *this = std::move(other); | 111 | *this = std::move(other); |
111 | } | 112 | } |
112 | 113 | ||
113 | Storage::NamedDatabase &Storage::NamedDatabase::operator=(Storage::NamedDatabase &&other) | 114 | DataStore::NamedDatabase &DataStore::NamedDatabase::operator=(DataStore::NamedDatabase &&other) |
114 | { | 115 | { |
115 | if (&other != this) { | 116 | if (&other != this) { |
116 | delete d; | 117 | delete d; |
@@ -120,12 +121,12 @@ Storage::NamedDatabase &Storage::NamedDatabase::operator=(Storage::NamedDatabase | |||
120 | return *this; | 121 | return *this; |
121 | } | 122 | } |
122 | 123 | ||
123 | Storage::NamedDatabase::~NamedDatabase() | 124 | DataStore::NamedDatabase::~NamedDatabase() |
124 | { | 125 | { |
125 | delete d; | 126 | delete d; |
126 | } | 127 | } |
127 | 128 | ||
128 | bool Storage::NamedDatabase::write(const QByteArray &sKey, const QByteArray &sValue, const std::function<void(const Storage::Error &error)> &errorHandler) | 129 | bool DataStore::NamedDatabase::write(const QByteArray &sKey, const QByteArray &sValue, const std::function<void(const DataStore::Error &error)> &errorHandler) |
129 | { | 130 | { |
130 | if (!d || !d->transaction) { | 131 | if (!d || !d->transaction) { |
131 | Error error("", ErrorCodes::GenericError, "Not open"); | 132 | Error error("", ErrorCodes::GenericError, "Not open"); |
@@ -161,12 +162,12 @@ bool Storage::NamedDatabase::write(const QByteArray &sKey, const QByteArray &sVa | |||
161 | return !rc; | 162 | return !rc; |
162 | } | 163 | } |
163 | 164 | ||
164 | void Storage::NamedDatabase::remove(const QByteArray &k, const std::function<void(const Storage::Error &error)> &errorHandler) | 165 | void DataStore::NamedDatabase::remove(const QByteArray &k, const std::function<void(const DataStore::Error &error)> &errorHandler) |
165 | { | 166 | { |
166 | remove(k, QByteArray(), errorHandler); | 167 | remove(k, QByteArray(), errorHandler); |
167 | } | 168 | } |
168 | 169 | ||
169 | void Storage::NamedDatabase::remove(const QByteArray &k, const QByteArray &value, const std::function<void(const Storage::Error &error)> &errorHandler) | 170 | void DataStore::NamedDatabase::remove(const QByteArray &k, const QByteArray &value, const std::function<void(const DataStore::Error &error)> &errorHandler) |
170 | { | 171 | { |
171 | if (!d || !d->transaction) { | 172 | if (!d || !d->transaction) { |
172 | if (d) { | 173 | if (d) { |
@@ -195,8 +196,8 @@ void Storage::NamedDatabase::remove(const QByteArray &k, const QByteArray &value | |||
195 | } | 196 | } |
196 | } | 197 | } |
197 | 198 | ||
198 | int Storage::NamedDatabase::scan(const QByteArray &k, const std::function<bool(const QByteArray &key, const QByteArray &value)> &resultHandler, | 199 | int DataStore::NamedDatabase::scan(const QByteArray &k, const std::function<bool(const QByteArray &key, const QByteArray &value)> &resultHandler, |
199 | const std::function<void(const Storage::Error &error)> &errorHandler, bool findSubstringKeys, bool skipInternalKeys) const | 200 | const std::function<void(const DataStore::Error &error)> &errorHandler, bool findSubstringKeys, bool skipInternalKeys) const |
200 | { | 201 | { |
201 | if (!d || !d->transaction) { | 202 | if (!d || !d->transaction) { |
202 | // Not an error. We rely on this to read nothing from non-existing databases. | 203 | // Not an error. We rely on this to read nothing from non-existing databases. |
@@ -278,8 +279,8 @@ int Storage::NamedDatabase::scan(const QByteArray &k, const std::function<bool(c | |||
278 | return numberOfRetrievedValues; | 279 | return numberOfRetrievedValues; |
279 | } | 280 | } |
280 | 281 | ||
281 | void Storage::NamedDatabase::findLatest(const QByteArray &k, const std::function<void(const QByteArray &key, const QByteArray &value)> &resultHandler, | 282 | void DataStore::NamedDatabase::findLatest(const QByteArray &k, const std::function<void(const QByteArray &key, const QByteArray &value)> &resultHandler, |
282 | const std::function<void(const Storage::Error &error)> &errorHandler) const | 283 | const std::function<void(const DataStore::Error &error)> &errorHandler) const |
283 | { | 284 | { |
284 | if (!d || !d->transaction) { | 285 | if (!d || !d->transaction) { |
285 | // Not an error. We rely on this to read nothing from non-existing databases. | 286 | // Not an error. We rely on this to read nothing from non-existing databases. |
@@ -346,7 +347,7 @@ void Storage::NamedDatabase::findLatest(const QByteArray &k, const std::function | |||
346 | return; | 347 | return; |
347 | } | 348 | } |
348 | 349 | ||
349 | qint64 Storage::NamedDatabase::getSize() | 350 | qint64 DataStore::NamedDatabase::getSize() |
350 | { | 351 | { |
351 | if (!d || !d->transaction) { | 352 | if (!d || !d->transaction) { |
352 | return -1; | 353 | return -1; |
@@ -368,10 +369,10 @@ qint64 Storage::NamedDatabase::getSize() | |||
368 | } | 369 | } |
369 | 370 | ||
370 | 371 | ||
371 | class Storage::Transaction::Private | 372 | class DataStore::Transaction::Private |
372 | { | 373 | { |
373 | public: | 374 | public: |
374 | Private(bool _requestRead, const std::function<void(const Storage::Error &error)> &_defaultErrorHandler, const QString &_name, MDB_env *_env) | 375 | Private(bool _requestRead, const std::function<void(const DataStore::Error &error)> &_defaultErrorHandler, const QString &_name, MDB_env *_env) |
375 | : env(_env), transaction(nullptr), requestedRead(_requestRead), defaultErrorHandler(_defaultErrorHandler), name(_name), implicitCommit(false), error(false), modificationCounter(0) | 376 | : env(_env), transaction(nullptr), requestedRead(_requestRead), defaultErrorHandler(_defaultErrorHandler), name(_name), implicitCommit(false), error(false), modificationCounter(0) |
376 | { | 377 | { |
377 | } | 378 | } |
@@ -383,7 +384,7 @@ public: | |||
383 | MDB_txn *transaction; | 384 | MDB_txn *transaction; |
384 | MDB_dbi dbi; | 385 | MDB_dbi dbi; |
385 | bool requestedRead; | 386 | bool requestedRead; |
386 | std::function<void(const Storage::Error &error)> defaultErrorHandler; | 387 | std::function<void(const DataStore::Error &error)> defaultErrorHandler; |
387 | QString name; | 388 | QString name; |
388 | bool implicitCommit; | 389 | bool implicitCommit; |
389 | bool error; | 390 | bool error; |
@@ -406,21 +407,21 @@ public: | |||
406 | } | 407 | } |
407 | }; | 408 | }; |
408 | 409 | ||
409 | Storage::Transaction::Transaction() : d(nullptr) | 410 | DataStore::Transaction::Transaction() : d(nullptr) |
410 | { | 411 | { |
411 | } | 412 | } |
412 | 413 | ||
413 | Storage::Transaction::Transaction(Transaction::Private *prv) : d(prv) | 414 | DataStore::Transaction::Transaction(Transaction::Private *prv) : d(prv) |
414 | { | 415 | { |
415 | d->startTransaction(); | 416 | d->startTransaction(); |
416 | } | 417 | } |
417 | 418 | ||
418 | Storage::Transaction::Transaction(Transaction &&other) : d(nullptr) | 419 | DataStore::Transaction::Transaction(Transaction &&other) : d(nullptr) |
419 | { | 420 | { |
420 | *this = std::move(other); | 421 | *this = std::move(other); |
421 | } | 422 | } |
422 | 423 | ||
423 | Storage::Transaction &Storage::Transaction::operator=(Storage::Transaction &&other) | 424 | DataStore::Transaction &DataStore::Transaction::operator=(DataStore::Transaction &&other) |
424 | { | 425 | { |
425 | if (&other != this) { | 426 | if (&other != this) { |
426 | delete d; | 427 | delete d; |
@@ -430,7 +431,7 @@ Storage::Transaction &Storage::Transaction::operator=(Storage::Transaction &&oth | |||
430 | return *this; | 431 | return *this; |
431 | } | 432 | } |
432 | 433 | ||
433 | Storage::Transaction::~Transaction() | 434 | DataStore::Transaction::~Transaction() |
434 | { | 435 | { |
435 | if (d && d->transaction) { | 436 | if (d && d->transaction) { |
436 | if (d->implicitCommit && !d->error) { | 437 | if (d->implicitCommit && !d->error) { |
@@ -443,12 +444,12 @@ Storage::Transaction::~Transaction() | |||
443 | delete d; | 444 | delete d; |
444 | } | 445 | } |
445 | 446 | ||
446 | Storage::Transaction::operator bool() const | 447 | DataStore::Transaction::operator bool() const |
447 | { | 448 | { |
448 | return (d && d->transaction); | 449 | return (d && d->transaction); |
449 | } | 450 | } |
450 | 451 | ||
451 | bool Storage::Transaction::commit(const std::function<void(const Storage::Error &error)> &errorHandler) | 452 | bool DataStore::Transaction::commit(const std::function<void(const DataStore::Error &error)> &errorHandler) |
452 | { | 453 | { |
453 | if (!d || !d->transaction) { | 454 | if (!d || !d->transaction) { |
454 | return false; | 455 | return false; |
@@ -467,7 +468,7 @@ bool Storage::Transaction::commit(const std::function<void(const Storage::Error | |||
467 | return !rc; | 468 | return !rc; |
468 | } | 469 | } |
469 | 470 | ||
470 | void Storage::Transaction::abort() | 471 | void DataStore::Transaction::abort() |
471 | { | 472 | { |
472 | if (!d || !d->transaction) { | 473 | if (!d || !d->transaction) { |
473 | return; | 474 | return; |
@@ -481,7 +482,7 @@ void Storage::Transaction::abort() | |||
481 | 482 | ||
482 | //Ensure that we opened the correct database by comparing the expected identifier with the one | 483 | //Ensure that we opened the correct database by comparing the expected identifier with the one |
483 | //we write to the database on first open. | 484 | //we write to the database on first open. |
484 | static bool ensureCorrectDb(Storage::NamedDatabase &database, const QByteArray &db, bool readOnly) | 485 | static bool ensureCorrectDb(DataStore::NamedDatabase &database, const QByteArray &db, bool readOnly) |
485 | { | 486 | { |
486 | bool openedTheWrongDatabase = false; | 487 | bool openedTheWrongDatabase = false; |
487 | auto count = database.scan("__internal_dbname", [db, &openedTheWrongDatabase](const QByteArray &key, const QByteArray &value) ->bool { | 488 | auto count = database.scan("__internal_dbname", [db, &openedTheWrongDatabase](const QByteArray &key, const QByteArray &value) ->bool { |
@@ -491,7 +492,7 @@ static bool ensureCorrectDb(Storage::NamedDatabase &database, const QByteArray & | |||
491 | } | 492 | } |
492 | return false; | 493 | return false; |
493 | }, | 494 | }, |
494 | [](const Storage::Error &error) -> bool{ | 495 | [](const DataStore::Error &error) -> bool{ |
495 | return false; | 496 | return false; |
496 | }, false); | 497 | }, false); |
497 | //This is the first time we open this database in a write transaction, write the db name | 498 | //This is the first time we open this database in a write transaction, write the db name |
@@ -503,7 +504,7 @@ static bool ensureCorrectDb(Storage::NamedDatabase &database, const QByteArray & | |||
503 | return !openedTheWrongDatabase; | 504 | return !openedTheWrongDatabase; |
504 | } | 505 | } |
505 | 506 | ||
506 | bool Storage::Transaction::validateNamedDatabases() | 507 | bool DataStore::Transaction::validateNamedDatabases() |
507 | { | 508 | { |
508 | auto databases = getDatabaseNames(); | 509 | auto databases = getDatabaseNames(); |
509 | for (const auto &dbName : databases) { | 510 | for (const auto &dbName : databases) { |
@@ -516,28 +517,28 @@ bool Storage::Transaction::validateNamedDatabases() | |||
516 | return true; | 517 | return true; |
517 | } | 518 | } |
518 | 519 | ||
519 | Storage::NamedDatabase Storage::Transaction::openDatabase(const QByteArray &db, const std::function<void(const Storage::Error &error)> &errorHandler, bool allowDuplicates) const | 520 | DataStore::NamedDatabase DataStore::Transaction::openDatabase(const QByteArray &db, const std::function<void(const DataStore::Error &error)> &errorHandler, bool allowDuplicates) const |
520 | { | 521 | { |
521 | if (!d) { | 522 | if (!d) { |
522 | return Storage::NamedDatabase(); | 523 | return DataStore::NamedDatabase(); |
523 | } | 524 | } |
524 | Q_ASSERT(d->transaction); | 525 | Q_ASSERT(d->transaction); |
525 | // We don't now if anything changed | 526 | // We don't now if anything changed |
526 | d->implicitCommit = true; | 527 | d->implicitCommit = true; |
527 | auto p = new Storage::NamedDatabase::Private(db, allowDuplicates, d->defaultErrorHandler, d->name, d->transaction); | 528 | auto p = new DataStore::NamedDatabase::Private(db, allowDuplicates, d->defaultErrorHandler, d->name, d->transaction); |
528 | if (!p->openDatabase(d->requestedRead, errorHandler)) { | 529 | if (!p->openDatabase(d->requestedRead, errorHandler)) { |
529 | delete p; | 530 | delete p; |
530 | return Storage::NamedDatabase(); | 531 | return DataStore::NamedDatabase(); |
531 | } | 532 | } |
532 | auto database = Storage::NamedDatabase(p); | 533 | auto database = DataStore::NamedDatabase(p); |
533 | if (!ensureCorrectDb(database, db, d->requestedRead)) { | 534 | if (!ensureCorrectDb(database, db, d->requestedRead)) { |
534 | SinkWarning() << "Failed to open the database" << db; | 535 | SinkWarning() << "Failed to open the database" << db; |
535 | return Storage::NamedDatabase(); | 536 | return DataStore::NamedDatabase(); |
536 | } | 537 | } |
537 | return database; | 538 | return database; |
538 | } | 539 | } |
539 | 540 | ||
540 | QList<QByteArray> Storage::Transaction::getDatabaseNames() const | 541 | QList<QByteArray> DataStore::Transaction::getDatabaseNames() const |
541 | { | 542 | { |
542 | if (!d) { | 543 | if (!d) { |
543 | SinkWarning() << "Invalid transaction"; | 544 | SinkWarning() << "Invalid transaction"; |
@@ -574,7 +575,7 @@ QList<QByteArray> Storage::Transaction::getDatabaseNames() const | |||
574 | } | 575 | } |
575 | 576 | ||
576 | 577 | ||
577 | class Storage::Private | 578 | class DataStore::Private |
578 | { | 579 | { |
579 | public: | 580 | public: |
580 | Private(const QString &s, const QString &n, AccessMode m); | 581 | Private(const QString &s, const QString &n, AccessMode m); |
@@ -587,7 +588,7 @@ public: | |||
587 | AccessMode mode; | 588 | AccessMode mode; |
588 | }; | 589 | }; |
589 | 590 | ||
590 | Storage::Private::Private(const QString &s, const QString &n, AccessMode m) : storageRoot(s), name(n), env(0), mode(m) | 591 | DataStore::Private::Private(const QString &s, const QString &n, AccessMode m) : storageRoot(s), name(n), env(0), mode(m) |
591 | { | 592 | { |
592 | const QString fullPath(storageRoot + '/' + name); | 593 | const QString fullPath(storageRoot + '/' + name); |
593 | QFileInfo dirInfo(fullPath); | 594 | QFileInfo dirInfo(fullPath); |
@@ -639,27 +640,27 @@ Storage::Private::Private(const QString &s, const QString &n, AccessMode m) : st | |||
639 | } | 640 | } |
640 | } | 641 | } |
641 | 642 | ||
642 | Storage::Private::~Private() | 643 | DataStore::Private::~Private() |
643 | { | 644 | { |
644 | //We never close the environment (unless we remove the db), since we should only open the environment once per process (as per lmdb docs) | 645 | //We never close the environment (unless we remove the db), since we should only open the environment once per process (as per lmdb docs) |
645 | //and create storage instance from all over the place. Thus, we're not closing it here on purpose. | 646 | //and create storage instance from all over the place. Thus, we're not closing it here on purpose. |
646 | } | 647 | } |
647 | 648 | ||
648 | Storage::Storage(const QString &storageRoot, const QString &name, AccessMode mode) : d(new Private(storageRoot, name, mode)) | 649 | DataStore::DataStore(const QString &storageRoot, const QString &name, AccessMode mode) : d(new Private(storageRoot, name, mode)) |
649 | { | 650 | { |
650 | } | 651 | } |
651 | 652 | ||
652 | Storage::~Storage() | 653 | DataStore::~DataStore() |
653 | { | 654 | { |
654 | delete d; | 655 | delete d; |
655 | } | 656 | } |
656 | 657 | ||
657 | bool Storage::exists() const | 658 | bool DataStore::exists() const |
658 | { | 659 | { |
659 | return (d->env != 0); | 660 | return (d->env != 0); |
660 | } | 661 | } |
661 | 662 | ||
662 | Storage::Transaction Storage::createTransaction(AccessMode type, const std::function<void(const Storage::Error &error)> &errorHandlerArg) | 663 | DataStore::Transaction DataStore::createTransaction(AccessMode type, const std::function<void(const DataStore::Error &error)> &errorHandlerArg) |
663 | { | 664 | { |
664 | auto errorHandler = errorHandlerArg ? errorHandlerArg : defaultErrorHandler(); | 665 | auto errorHandler = errorHandlerArg ? errorHandlerArg : defaultErrorHandler(); |
665 | if (!d->env) { | 666 | if (!d->env) { |
@@ -677,7 +678,7 @@ Storage::Transaction Storage::createTransaction(AccessMode type, const std::func | |||
677 | return Transaction(new Transaction::Private(requestedRead, defaultErrorHandler(), d->name, d->env)); | 678 | return Transaction(new Transaction::Private(requestedRead, defaultErrorHandler(), d->name, d->env)); |
678 | } | 679 | } |
679 | 680 | ||
680 | qint64 Storage::diskUsage() const | 681 | qint64 DataStore::diskUsage() const |
681 | { | 682 | { |
682 | QFileInfo info(d->storageRoot + '/' + d->name + "/data.mdb"); | 683 | QFileInfo info(d->storageRoot + '/' + d->name + "/data.mdb"); |
683 | if (!info.exists()) { | 684 | if (!info.exists()) { |
@@ -686,7 +687,7 @@ qint64 Storage::diskUsage() const | |||
686 | return info.size(); | 687 | return info.size(); |
687 | } | 688 | } |
688 | 689 | ||
689 | void Storage::removeFromDisk() const | 690 | void DataStore::removeFromDisk() const |
690 | { | 691 | { |
691 | const QString fullPath(d->storageRoot + '/' + d->name); | 692 | const QString fullPath(d->storageRoot + '/' + d->name); |
692 | QMutexLocker locker(&sMutex); | 693 | QMutexLocker locker(&sMutex); |
@@ -701,7 +702,7 @@ void Storage::removeFromDisk() const | |||
701 | } | 702 | } |
702 | } | 703 | } |
703 | 704 | ||
704 | void Storage::clearEnv() | 705 | void DataStore::clearEnv() |
705 | { | 706 | { |
706 | for (auto env : sEnvironments) { | 707 | for (auto env : sEnvironments) { |
707 | mdb_env_close(env); | 708 | mdb_env_close(env); |
@@ -709,4 +710,5 @@ void Storage::clearEnv() | |||
709 | sEnvironments.clear(); | 710 | sEnvironments.clear(); |
710 | } | 711 | } |
711 | 712 | ||
713 | } | ||
712 | } // namespace Sink | 714 | } // namespace Sink |