22#include "exceptions.h"
24#define UNUSED(x) (void)(x)
47template<
class K,
class V>
59template<
class K,
class V>
60Storage<K, V>::~Storage() {
61 for (
const std::pair<
const uint32_t,
Cursor<K, V>*>& pair : cursors)
62 pair.second->dropped();
80template<
class K,
class V>
108template<
class K,
class V>
113 unsigned int flags = 0;
115 flags |= MDB_NODUPDATA;
117 flags |= MDB_NOOVERWRITE;
119 int rc = _mdbPut(txn, lmdbKey, lmdbData,
flags);
120 if (rc != MDB_SUCCESS)
143template<
class K,
class V>
165template<
class K,
class V>
199template<
class K,
class V>
213 int rc = _mdbGet(txn, lmdbKey, lmdbData);
227 rc = _mdbPut(txn, lmdbKey, lmdbData);
228 if (rc != MDB_SUCCESS)
255template<
class K,
class V>
280template<
class K,
class V>
315template<
class K,
class V>
318 int rc = _mdbCursorOpen(txn, &cursor);
319 if (rc != MDB_SUCCESS)
324 rc = _mdbCursorGet(cursor, lmdbKey, lmdbData, MDB_SET);
325 if (rc != MDB_SUCCESS)
329 bool sameSize = lmdbData.mv_size == lmdbNewData.mv_size;
330 int firstDifferentByte = 0;
332 firstDifferentByte = memcmp(lmdbData.mv_data, lmdbNewData.mv_data, lmdbData.mv_size);
333 if (firstDifferentByte == 0) {
334 _mdbCursorClose(cursor);
339 unsigned int flags = MDB_CURRENT;
340 if (
duplicates && (!sameSize || firstDifferentByte < 0)) {
341 rc = _mdbCursorDel(cursor);
342 flags = MDB_NODUPDATA;
345 if (rc == MDB_SUCCESS)
346 rc = _mdbCursorPut(cursor, lmdbKey, lmdbNewData,
flags);
348 _mdbCursorClose(cursor);
349 if (rc != MDB_SUCCESS)
378template<
class K,
class V>
402template<
class K,
class V>
429template<
class K,
class V>
462template<
class K,
class V>
492template<
class K,
class V>
516template<
class K,
class V>
521 int rc = _mdbGet(txn, lmdbKey, lmdbData);
522 if (rc != MDB_SUCCESS)
552template<
class K,
class V>
567template<
class K,
class V>
593template<
class K,
class V>
598 int rc = _mdbGet(txn, lmdbKey, lmdbData);
599 if (rc == MDB_SUCCESS)
602 if (rc != MDB_NOTFOUND)
622template<
class K,
class V>
639template<
class K,
class V>
643 std::map<K, V> result;
661template<
class K,
class V>
687template<
class K,
class V>
689 std::map<K, V> result;
710template<
class K,
class V>
728template<
class K,
class V>
731 MDB_val lmdbKey, lmdbData;
733 int rc = _mdbCursorOpen(txn, &cursor);
734 if (rc != MDB_SUCCESS)
737 rc = _mdbCursorGet(cursor, lmdbKey, lmdbData, MDB_FIRST);
738 while (rc == MDB_SUCCESS) {
741 std::pair<typename std::map<K, V>::iterator,
bool> probe = result.emplace(key, V{});
745 rc = _mdbCursorGet(cursor, lmdbKey, lmdbData, MDB_NEXT);
747 _mdbCursorClose(cursor);
748 if (rc != MDB_NOTFOUND)
769template<
class K,
class V>
785template<
class K,
class V>
810template<
class K,
class V>
813 if (rc != MDB_SUCCESS)
816 MDB_val lmdbKey, lmdbData;
817 for (
const std::pair<const K, V>& pair : data) {
821 rc = _mdbPut(txn, lmdbKey, lmdbData, MDB_NOOVERWRITE);
822 if (rc != MDB_SUCCESS)
841template<
class K,
class V>
858template<
class K,
class V>
888template<
class K,
class V>
890 MDB_val lmdbKey, lmdbData;
892 for (
const std::pair<const K, V>& pair : data) {
896 rc = _mdbPut(txn, lmdbKey, lmdbData, overwrite ? 0 : MDB_NOOVERWRITE);
897 if (rc == MDB_KEYEXIST)
900 if (rc != MDB_SUCCESS)
905 rc = _mdbStat(txn, stat);
906 if (rc != MDB_SUCCESS)
909 if (stat.ms_entries > std::numeric_limits<SizeType>::max())
910 throw std::runtime_error(
"LMDBAL::Storage::addRecords() - storage is full");
912 return static_cast<SizeType>(stat.ms_entries);
931template<
class K,
class V>
948template<
class K,
class V>
975template<
class K,
class V>
978 int rc = _mdbDel(txn, lmdbKey);
979 if (rc != MDB_SUCCESS)
998template<
class K,
class V>
1010template<
class K,
class V>
1018template<
class K,
class V>
1021 pair.second->terminated();
1034template<
class K,
class V>
1051template<
class K,
class V>
1053 typename std::map<uint32_t, Cursor<K, V>*>::iterator itr =
cursors.find(cursor.id);
1055 throwUnknown(
"An attempt to destroy a cursor the storage doesn't own");
1072template<
class K,
class V>
1078 int res = _mdbFlags(txn, result);
1080 if (res != MDB_SUCCESS)
1092template<
class K,
class V>
1105template<
class K,
class V>
void reset()
A private method that turns cursor into an empty one.
Definition cursorcommon.cpp:113
void close()
Termiates a sequence of operations with the cursor.
Definition cursorcommon.cpp:161
An object to iterate storages.
Definition cursor.h:33
Thrown if there was a key conflict in one of the storages.
Definition exceptions.h:171
StorageCommon(Base *parent, const std::string &name, bool duplicates=false)
Constructs a storage interface.
Definition storagecommon.cpp:42
void commitTransaction(TransactionID id)
Commits transaction.
Definition storagecommon.cpp:456
static constexpr std::string_view forceRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:120
static constexpr std::string_view removeRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:122
TransactionID beginReadOnlyTransaction() const
Begins read-only transaction.
Definition storagecommon.cpp:428
int makeStorage(MDB_txn *transaction, bool duplicates=false)
A functiion to actually open MDB_dbi storage.
Definition storagecommon.hpp:38
void abortTransaction(TransactionID id) const
Aborts transaction.
Definition storagecommon.cpp:446
static std::string toString(const T &value)
A method to cast a value (which can be a value or a key) to string.
Definition storagecommon.hpp:71
static constexpr std::string_view addRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:119
void throwDuplicateOrUnknown(int rc, std::string_view key) const
Throws LMDBAL::Exist or LMDBAL::Unknown.
Definition storagecommon.cpp:301
virtual void close()
A private virtual function to close each storage in the database.
Definition storagecommon.cpp:57
static constexpr std::string_view getRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:124
static constexpr std::string_view changeRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:121
const std::string name
this storage name
Definition storagecommon.h:112
TransactionID extractTransactionId(const Transaction &txn, std::string_view action={}) const
Checks if the transaction is still active, returns inner TransactionID.
Definition storagecommon.cpp:72
static constexpr std::string_view readAllMethodName
member function name, just for exceptions
Definition storagecommon.h:125
static constexpr std::string_view checkRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:123
static constexpr std::string_view replaceAllMethodName
member function name, just for exceptions
Definition storagecommon.h:126
void ensureOpened(std::string_view methodName) const
Helper function; throws an exception if the database is not opened.
Definition storagecommon.cpp:135
void throwNotFoundOrUnknown(int rc, std::string_view key) const
Throws LMDBAL::NotFound or LMDBAL::Unknown (transaction variant).
Definition storagecommon.cpp:319
void throwUnknown(int rc, TransactionID txn) const
Throws LMDBAL::Unknown (transaction vairiant).
Definition storagecommon.cpp:336
TransactionID beginTransaction() const
Begins writable transaction.
Definition storagecommon.cpp:438
const bool duplicates
true if storage supports duplicates
Definition storagecommon.h:113
static constexpr std::string_view addRecordsMethodName
member function name, just for exceptions
Definition storagecommon.h:127
static constexpr std::string_view flagsMethodName
member function name, just for exceptions
Definition storagecommon.h:117
void throwDuplicate(std::string_view key) const
Throws LMDBAL::Exist.
Definition storagecommon.cpp:394
virtual bool checkRecord(const K &key, TransactionID txn) const
Chechs if storage has value (private transaction variant).
Definition storage.hpp:594
Serializer< V > valueSerializer
internal object that would serialize and deserialize values
Definition storage.h:95
virtual void addRecord(const K &key, const V &value, TransactionID txn)
Adds a key-value record to the storage (private transaction variant).
Definition storage.hpp:109
virtual std::map< K, V > readAll() const
Reads whole storage into a map.
Definition storage.hpp:640
virtual int drop(TransactionID transaction)
Drops content of a storage interface (transaction variant).
Definition storagecommon.cpp:109
Serializer< K > keySerializer
internal object that would serialize and deserialize keys
Definition storage.h:94
std::map< uint32_t, Cursor< K, V > * > cursors
a set of cursors that has been created under this storage
Definition storage.h:96
virtual void discoveredRecord(const K &key, const V &value) const
A private virtual method that cursor calls when he reads a record, does nothing here but populates th...
Definition storage.hpp:1093
virtual void replaceAll(const std::map< K, V > &data, TransactionID txn)
Replaces the content of the whole storage with the given (private transaction variant).
Definition storage.hpp:811
void destroyCursor(Cursor< K, V > &cursor)
Frees cursor.
Definition storage.hpp:1052
uint32_t flags() const
Reads current storage flags it was opened with.
Definition storage.hpp:1073
virtual void removeRecord(const K &key, TransactionID txn)
Removes one of the records (private transaction variant).
Definition storage.hpp:976
void close() override
A private virtual method I need to close each storage in the database.
Definition storage.hpp:1019
Cursor< K, V > createCursor()
Creates cursor.
Definition storage.hpp:1035
virtual uint32_t addRecords(const std::map< K, V > &data, TransactionID txn, bool overwrite=false)
Adds records in bulk (private transaction variant).
Definition storage.hpp:889
virtual std::map< K, V > readAll(TransactionID txn) const
Reads whole storage into a map (private transaction variant).
Definition storage.hpp:688
virtual bool forceRecord(const K &key, const V &value, TransactionID txn)
Adds a key-value record to the storage, overwrites if it already exists (private transaction variant)...
Definition storage.hpp:200
virtual void changeRecord(const K &key, const V &value, TransactionID txn)
Changes key-value record to the storage (private transaction variant).
Definition storage.hpp:316
virtual void getRecord(const K &key, V &value, TransactionID txn) const
Gets the record from the database (private transaction, reference variant).
Definition storage.hpp:517
Storage(Base *parent, const std::string &name, bool duplicates=false)
Creates a storage.
Definition storage.hpp:48
int open(MDB_txn *transaction) override
A private virtual method I need to open each storage in the database.
Definition storage.hpp:1011
Public read only transaction.
Definition transaction.h:27
Public writable transaction.
Definition transaction.h:54
Destroys a cache.
Definition base.h:36
MDB_txn * TransactionID
I'm going to use transaction pointers as transaction IDs.
Definition base.h:52
uint32_t SizeType
All LMDBAL sizes are uint32.
Definition base.h:53