LMDBAL 0.6.0
LMDB (Lightning Memory-Mapped Database Manager) Abstraction Layer
Loading...
Searching...
No Matches
storage.h
1/*
2 * LMDB Abstraction Layer.
3 * Copyright (C) 2023 Yury Gubich <blue@macaw.me>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include <type_traits>
22#include <cstring>
23
24#include "base.h"
25#include "serializer.h"
26#include "cursor.h"
27#include "transaction.h"
28
29class BaseTest;
30class DuplicatesTest;
31class CacheCursorTest;
32class StorageCursorTest;
33
34namespace LMDBAL {
35
36class iStorage {
37 friend class Base;
38public:
39protected:
40 iStorage(Base* parent, const std::string& name, bool duplicates = false);
41 virtual ~iStorage();
42
49 virtual int open(MDB_txn * transaction) = 0;
50 virtual void close();
51 virtual void handleDrop();
52
53 bool isDBOpened() const;
54 const std::string& dbName() const;
55
56 void ensureOpened(const std::string& methodName) const;
57 void throwDuplicateOrUnknown(int rc, const std::string& key) const;
58 void throwDuplicateOrUnknown(int rc, TransactionID txn, const std::string& key) const;
59 void throwNotFoundOrUnknown(int rc, const std::string& key) const;
60 void throwNotFoundOrUnknown(int rc, TransactionID txn, const std::string& key) const;
61 void throwUnknown(int rc, TransactionID txn) const;
62 void throwUnknown(int rc) const;
63 void throwUnknown(const std::string& message) const;
64 void throwDuplicate(const std::string& key) const;
65 void throwNotFound(const std::string& key) const;
66 void throwCursorNotReady(const std::string& method) const;
67
68 TransactionID extractTransactionId(const Transaction& txn, const std::string& action = "") const;
69 TransactionID beginReadOnlyTransaction() const;
70 TransactionID beginTransaction() const;
71 void commitTransaction(TransactionID id);
72 void abortTransaction(TransactionID id) const;
73 virtual void transactionStarted(TransactionID txn, bool readOnly) const;
74 virtual void transactionCommited(TransactionID txn);
75 virtual void transactionAborted(TransactionID txn) const;
76 virtual int drop(TransactionID transaction);
77 virtual SizeType count(TransactionID txn) const;
78
79 int _mdbOpen(MDB_txn* txn, unsigned int flags = 0);
80
81 int _mdbPut(MDB_txn* txn, MDB_val& key, MDB_val& data, unsigned int flags = 0);
82 int _mdbGet(MDB_txn* txn, MDB_val& key, MDB_val& data) const;
83 int _mdbDel(MDB_txn* txn, MDB_val& key);
84 int _mdbDel(MDB_txn* txn, MDB_val& key, MDB_val& data);
85
86 int _mdbStat(MDB_txn* txn, MDB_stat& stat) const;
87 int _mdbFlags(MDB_txn* txn, uint32_t& flags) const;
88
89 int _mdbCursorOpen(MDB_txn* txn, MDB_cursor** cursor) const;
90 void _mdbCursorClose(MDB_cursor* cursor) const;
91 int _mdbCursorGet(MDB_cursor* cursor, MDB_val& key, MDB_val& data, MDB_cursor_op operation) const;
92 int _mdbCursorSet(MDB_cursor* cursor, MDB_val& key) const;
93 int _mdbCursorDel(MDB_cursor* cursor, unsigned int flags = 0);
94 int _mdbCursorPut(MDB_cursor* cursor, MDB_val& key, MDB_val& data, unsigned int flags = 0);
95
96 int _mdbCursorRenew(MDB_txn* txn, MDB_cursor* cursor) const;
97 MDB_txn* _mdbCursorTxn(MDB_cursor* cursor) const;
98
99public:
100 virtual void drop();
101 virtual int drop(const WriteTransaction& txn);
102 virtual SizeType count() const;
103 virtual SizeType count(const Transaction& txn) const;
104
105protected:
106 MDB_dbi dbi;
108 const std::string name;
109 const bool duplicates;
111 inline static const std::string dropMethodName = "drop";
112 inline static const std::string countMethodName = "count";
113 inline static const std::string flagsMethodName = "flags";
115 inline static const std::string addRecordMethodName = "addRecord";
116 inline static const std::string forceRecordMethodName = "forceRecord";
117 inline static const std::string changeRecordMethodName = "changeRecord";
118 inline static const std::string removeRecordMethodName = "removeRecord";
119 inline static const std::string checkRecordMethodName = "checkRecord";
120 inline static const std::string getRecordMethodName = "getRecord";
121 inline static const std::string readAllMethodName = "readAllRecord";
122 inline static const std::string replaceAllMethodName = "replaceAll";
123 inline static const std::string addRecordsMethodName = "addRecords";
125protected:
126 template <class K, class V>
127 int makeStorage(MDB_txn* transaction, bool duplicates = false);
128
129 template <class T>
130 static std::string toString(const T& value);
131};
132
133template <class K, class V>
134class Storage : public iStorage {
135 friend class ::BaseTest;
136 friend class ::DuplicatesTest;
137 friend class ::CacheCursorTest;
138 friend class ::StorageCursorTest;
139 friend class Base;
140 friend class Cursor<K, V>;
141protected:
142 Storage(Base* parent, const std::string& name, bool duplicates = false);
143 ~Storage() override;
144
145 virtual void discoveredRecord(const K& key, const V& value) const;
146 virtual void discoveredRecord(const K& key, const V& value, TransactionID txn) const;
147 uint32_t flags() const;
148
149 virtual void addRecord(const K& key, const V& value, TransactionID txn);
150 virtual bool forceRecord(const K& key, const V& value, TransactionID txn);
151 virtual void changeRecord(const K& key, const V& value, TransactionID txn);
152 virtual void removeRecord(const K& key, TransactionID txn);
153 virtual bool checkRecord(const K& key, TransactionID txn) const;
154 virtual void getRecord(const K& key, V& value, TransactionID txn) const;
155 virtual V getRecord(const K& key, TransactionID txn) const;
156 virtual std::map<K, V> readAll(TransactionID txn) const;
157 virtual void readAll(std::map<K, V>& result, TransactionID txn) const;
158 virtual void replaceAll(const std::map<K, V>& data, TransactionID txn);
159 virtual uint32_t addRecords(const std::map<K, V>& data, TransactionID txn, bool overwrite = false);
160
161public:
162 using iStorage::drop;
163 virtual void addRecord(const K& key, const V& value);
164 virtual void addRecord(const K& key, const V& value, const WriteTransaction& txn);
165 virtual bool forceRecord(const K& key, const V& value); //returns true if there was addition, false if change
166 virtual bool forceRecord(const K& key, const V& value, const WriteTransaction& txn);
167 virtual void changeRecord(const K& key, const V& value);
168 virtual void changeRecord(const K& key, const V& value, const WriteTransaction& txn);
169 virtual void removeRecord(const K& key);
170 virtual void removeRecord(const K& key, const WriteTransaction& txn);
171 virtual bool checkRecord(const K& key) const; //checks if there is a record with given key
172 virtual bool checkRecord(const K& key, const Transaction& txn) const;
173 virtual void getRecord(const K& key, V& value) const;
174 virtual void getRecord(const K& key, V& value, const Transaction& txn) const;
175 virtual V getRecord(const K& key) const;
176 virtual V getRecord(const K& key, const Transaction& txn) const;
177 virtual std::map<K, V> readAll() const;
178 virtual std::map<K, V> readAll(const Transaction& txn) const;
179 virtual void readAll(std::map<K, V>& result) const;
180 virtual void readAll(std::map<K, V>& result, const Transaction& txn) const;
181 virtual void replaceAll(const std::map<K, V>& data);
182 virtual void replaceAll(const std::map<K, V>& data, const WriteTransaction& txn);
183 virtual uint32_t addRecords(const std::map<K, V>& data, bool overwrite = false);
184 virtual uint32_t addRecords(const std::map<K, V>& data, const WriteTransaction& txn, bool overwrite = false);
185
187 void destroyCursor(Cursor<K, V>& cursor);
188
189protected:
192 std::map<uint32_t, Cursor<K, V>*> cursors;
194 int open(MDB_txn* transaction) override;
195 void close() override;
196};
197
198}
199
200#include "storage.hpp"
Database abstraction.
Definition base.h:53
An object to iterate storages.
Definition cursor.h:31
A class handling serialization/deserialization.
Definition serializer.h:33
This is a basic key value storage.
Definition storage.h:134
virtual bool checkRecord(const K &key, TransactionID txn) const
Chechs if storage has value (private transaction variant)
Definition storage.hpp:592
Serializer< V > valueSerializer
internal object that would serialize and deserialize values
Definition storage.h:191
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:107
virtual std::map< K, V > readAll() const
Reads whole storage into a map.
Definition storage.hpp:638
~Storage() override
Destroys a storage.
Definition storage.hpp:59
Serializer< K > keySerializer
internal object that would serialize and deserialize keys
Definition storage.h:190
std::map< uint32_t, Cursor< K, V > * > cursors
a set of cursors that has been created under this storage
Definition storage.h:192
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:1088
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:809
void destroyCursor(Cursor< K, V > &cursor)
Frees cursor.
Definition storage.hpp:1047
uint32_t flags() const
Reads current storage flags it was opened with.
Definition storage.hpp:1068
virtual void removeRecord(const K &key, TransactionID txn)
Removes one of the records (private transaction variant)
Definition storage.hpp:971
void close() override
A private virtual method I need to close each storage in the database.
Definition storage.hpp:1014
Cursor< K, V > createCursor()
Creates cursor.
Definition storage.hpp:1030
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:198
virtual void changeRecord(const K &key, const V &value, TransactionID txn)
Changes key-value record to the storage (private transaction variant)
Definition storage.hpp:314
virtual void getRecord(const K &key, V &value, TransactionID txn) const
Gets the record from the database (private transaction, reference variant)
Definition storage.hpp:515
Storage(Base *parent, const std::string &name, bool duplicates=false)
Creates a storage.
Definition storage.hpp:48
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:887
int open(MDB_txn *transaction) override
A private virtual method I need to open each storage in the database.
Definition storage.hpp:1006
Public read only transaction.
Definition transaction.h:26
Public writable transaction.
Definition transaction.h:50
Storage interface.
Definition storage.h:36
static const std::string readAllMethodName
member function name, just for exceptions
Definition storage.h:121
static const std::string getRecordMethodName
member function name, just for exceptions
Definition storage.h:120
static const std::string replaceAllMethodName
member function name, just for exceptions
Definition storage.h:122
static const std::string addRecordsMethodName
member function name, just for exceptions
Definition storage.h:123
void commitTransaction(TransactionID id)
Commits transaction.
Definition storage.cpp:394
void throwDuplicate(const std::string &key) const
Throws LMDBAL::Exist.
Definition storage.cpp:332
virtual void handleDrop()
A method where database additionally handles drop.
Definition storage.cpp:448
void throwNotFoundOrUnknown(int rc, const std::string &key) const
Throws LMDBAL::NotFound or LMDBAL::Unknown (transaction variant)
Definition storage.cpp:257
static const std::string countMethodName
member function name, just for exceptions
Definition storage.h:112
void throwUnknown(int rc, TransactionID txn) const
Throws LMDBAL::Unknown (transaction vairiant)
Definition storage.cpp:274
int makeStorage(MDB_txn *transaction, bool duplicates=false)
A functiion to actually open MDB_dbi storage.
Definition storage.hpp:1122
static const std::string removeRecordMethodName
member function name, just for exceptions
Definition storage.h:118
virtual int open(MDB_txn *transaction)=0
A private virtual function I need to open each storage in the database.
static const std::string checkRecordMethodName
member function name, just for exceptions
Definition storage.h:119
TransactionID extractTransactionId(const Transaction &txn, const std::string &action="") const
Checks if the transaction is still active, returns inner TransactionID.
Definition storage.cpp:70
void throwCursorNotReady(const std::string &method) const
Throws LMDBAL::CursorNotReady.
Definition storage.cpp:356
TransactionID beginTransaction() const
Begins writable transaction.
Definition storage.cpp:376
virtual void drop()
Drops content of a storage interface.
Definition storage.cpp:85
void abortTransaction(TransactionID id) const
Aborts transaction.
Definition storage.cpp:384
static const std::string changeRecordMethodName
member function name, just for exceptions
Definition storage.h:117
virtual SizeType count() const
Storage size.
Definition storage.cpp:146
void ensureOpened(const std::string &methodName) const
Helper function, thows exception if the database is not opened.
Definition storage.cpp:133
const std::string & dbName() const
Database name.
Definition storage.cpp:286
virtual void transactionCommited(TransactionID txn)
called on commitment of public transaction
Definition storage.cpp:425
iStorage(Base *parent, const std::string &name, bool duplicates=false)
Constructs a storage interface.
Definition storage.cpp:40
static const std::string addRecordMethodName
member function name, just for exceptions
Definition storage.h:115
Base * db
parent database pointer (borrowed)
Definition storage.h:107
TransactionID beginReadOnlyTransaction() const
Begins read-only transaction.
Definition storage.cpp:366
virtual void close()
A private virtual function I need to close each storage in the database.
Definition storage.cpp:55
virtual void transactionAborted(TransactionID txn) const
called on abortion of public transaction
Definition storage.cpp:439
static const std::string forceRecordMethodName
member function name, just for exceptions
Definition storage.h:116
virtual ~iStorage()
Destroys a storage interface.
Definition storage.cpp:50
const bool duplicates
true if storage supports duplicates
Definition storage.h:109
virtual void transactionStarted(TransactionID txn, bool readOnly) const
called on beginning of public transaction
Definition storage.cpp:409
MDB_dbi dbi
lmdb storage handle
Definition storage.h:106
static const std::string dropMethodName
member function name, just for exceptions
Definition storage.h:111
static std::string toString(const T &value)
A method to cast a value (which can be a value or a key) to string.
Definition storage.hpp:1155
static const std::string flagsMethodName
member function name, just for exceptions
Definition storage.h:113
void throwDuplicateOrUnknown(int rc, const std::string &key) const
Throws LMDBAL::Exist or LMDBAL::Unknown.
Definition storage.cpp:239
const std::string name
this storage name
Definition storage.h:108
void throwNotFound(const std::string &key) const
Throws LMDBAL::NotFound.
Definition storage.cpp:344
bool isDBOpened() const
Is database opened.
Definition storage.cpp:296