external transaction methods for storage

This commit is contained in:
Blue 2023-03-28 23:45:35 +03:00
parent f39d44890a
commit e2dbea21d1
Signed by: blue
GPG Key ID: 9B203B252A63EE38
19 changed files with 273 additions and 58 deletions

View File

@ -10,7 +10,7 @@ depends=( 'lmdb' 'qt5-base')
makedepends=('cmake>=3.16') makedepends=('cmake>=3.16')
optdepends=() optdepends=()
source=("$pkgname-$pkgver.tar.gz") source=("$pkgname-$pkgver.tar.gz::https://git.macaw.me/blue/lmdbal/archive/$pkgver.tar.gz")
sha256sums=('SKIP') sha256sums=('SKIP')
build() { build() {
cd "$srcdir/$pkgname" cd "$srcdir/$pkgname"

View File

@ -37,6 +37,7 @@ public:
~Serializer(); ~Serializer();
T deserialize(const MDB_val& value); T deserialize(const MDB_val& value);
void deserialize(const MDB_val& value, T& result);
MDB_val setData(const T& value); MDB_val setData(const T& value);
MDB_val getData(); MDB_val getData();
void clear(); void clear();

View File

@ -54,14 +54,19 @@ MDB_val LMDBAL::Serializer<T>::setData(const T& value) {
template<class T> template<class T>
T LMDBAL::Serializer<T>::deserialize(const MDB_val& value) { T LMDBAL::Serializer<T>::deserialize(const MDB_val& value) {
clear();
bytes.setRawData((char*)value.mv_data, value.mv_size);
T result; T result;
stream >> result; deserialize(value, result);
return result; return result;
} }
template<class T>
void LMDBAL::Serializer<T>::deserialize(const MDB_val& value, T& result) {
clear();
bytes.setRawData((char*)value.mv_data, value.mv_size);
stream >> result;
}
template<class T> template<class T>
void LMDBAL::Serializer<T>::_setData(const T& value) { void LMDBAL::Serializer<T>::_setData(const T& value) {
stream << value; stream << value;

View File

@ -29,9 +29,12 @@ public:
~Serializer() {}; ~Serializer() {};
double deserialize(const MDB_val& data) { double deserialize(const MDB_val& data) {
std::memcpy(&value, data.mv_data, 8); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, double& result) {
std::memcpy(&result, data.mv_data, 8);
}
MDB_val setData(const double& data) { MDB_val setData(const double& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -29,9 +29,12 @@ public:
~Serializer() {}; ~Serializer() {};
float deserialize(const MDB_val& data) { float deserialize(const MDB_val& data) {
std::memcpy(&value, data.mv_data, 4); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, float& result) {
std::memcpy(&result, data.mv_data, 4);
}
MDB_val setData(const float& data) { MDB_val setData(const float& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -31,9 +31,12 @@ public:
~Serializer() {}; ~Serializer() {};
int16_t deserialize(const MDB_val& data) { int16_t deserialize(const MDB_val& data) {
std::memcpy(&value, data.mv_data, 2); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, int16_t& result) {
std::memcpy(&result, data.mv_data, 2);
}
MDB_val setData(const int16_t& data) { MDB_val setData(const int16_t& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -31,9 +31,12 @@ public:
~Serializer() {}; ~Serializer() {};
int32_t deserialize(const MDB_val& data) { int32_t deserialize(const MDB_val& data) {
std::memcpy(&value, data.mv_data, 4); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, int32_t& result) {
std::memcpy(&result, data.mv_data, 4);
}
MDB_val setData(const int32_t& data) { MDB_val setData(const int32_t& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -31,9 +31,12 @@ public:
~Serializer() {}; ~Serializer() {};
int64_t deserialize(const MDB_val& data) { int64_t deserialize(const MDB_val& data) {
std::memcpy(&value, data.mv_data, 8); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, int64_t& result) {
std::memcpy(&result, data.mv_data, 8);
}
MDB_val setData(const int64_t& data) { MDB_val setData(const int64_t& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -31,9 +31,12 @@ public:
~Serializer() {}; ~Serializer() {};
int8_t deserialize(const MDB_val& data) { int8_t deserialize(const MDB_val& data) {
std::memcpy(&value, data.mv_data, 1); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, int8_t& result) {
std::memcpy(&result, data.mv_data, 1);
}
MDB_val setData(const int8_t& data) { MDB_val setData(const int8_t& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -31,9 +31,12 @@ public:
~Serializer() {}; ~Serializer() {};
QByteArray deserialize(const MDB_val& data) { QByteArray deserialize(const MDB_val& data) {
value.setRawData((char*)data.mv_data, data.mv_size); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, QByteArray& result) {
result.setRawData((char*)data.mv_data, data.mv_size);
}
MDB_val setData(const QByteArray& data) { MDB_val setData(const QByteArray& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -35,6 +35,10 @@ public:
value = QByteArray((char*)data.mv_data, data.mv_size); value = QByteArray((char*)data.mv_data, data.mv_size);
return QString::fromUtf8(value); return QString::fromUtf8(value);
}; };
void deserialize(const MDB_val& data, QString& result) {
value = QByteArray((char*)data.mv_data, data.mv_size);
result = QString::fromUtf8(value);
}
MDB_val setData(const QString& data) { MDB_val setData(const QString& data) {
value = data.toUtf8(); value = data.toUtf8();
return getData(); return getData();

View File

@ -31,9 +31,12 @@ public:
~Serializer() {}; ~Serializer() {};
std::string deserialize(const MDB_val& data) { std::string deserialize(const MDB_val& data) {
value = std::string((char*)data.mv_data, data.mv_size); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, std::string& result) {
result.assign((char*)data.mv_data, data.mv_size);
}
MDB_val setData(const std::string& data) { MDB_val setData(const std::string& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -31,9 +31,12 @@ public:
~Serializer() {}; ~Serializer() {};
uint16_t deserialize(const MDB_val& data) { uint16_t deserialize(const MDB_val& data) {
std::memcpy(&value, data.mv_data, 2); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, uint16_t& result) {
std::memcpy(&result, data.mv_data, 2);
}
MDB_val setData(const uint16_t& data) { MDB_val setData(const uint16_t& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -31,9 +31,12 @@ public:
~Serializer() {}; ~Serializer() {};
uint32_t deserialize(const MDB_val& data) { uint32_t deserialize(const MDB_val& data) {
std::memcpy(&value, data.mv_data, 4); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, uint32_t& result) {
std::memcpy(&result, data.mv_data, 4);
}
MDB_val setData(const uint32_t& data) { MDB_val setData(const uint32_t& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -31,9 +31,12 @@ public:
~Serializer() {}; ~Serializer() {};
uint64_t deserialize(const MDB_val& data) { uint64_t deserialize(const MDB_val& data) {
std::memcpy(&value, data.mv_data, 8); deserialize(data, value);
return value; return value;
}; };
void deserialize(const MDB_val& data, uint64_t& result) {
std::memcpy(&result, data.mv_data, 8);
}
MDB_val setData(const uint64_t& data) { MDB_val setData(const uint64_t& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -31,9 +31,12 @@ public:
~Serializer() {}; ~Serializer() {};
uint8_t deserialize(const MDB_val& data) { uint8_t deserialize(const MDB_val& data) {
std::memcpy(&value, data.mv_data, 1); deserialzie(data, value);
return value; return value;
}; };
void deserialzie(const MDB_val& data, uint8_t& result) {
std::memcpy(&result, data.mv_data, 1);
}
MDB_val setData(const uint8_t& data) { MDB_val setData(const uint8_t& data) {
value = data; value = data;
return getData(); return getData();

View File

@ -82,14 +82,22 @@ uint32_t LMDBAL::iStorage::count() const {
void LMDBAL::iStorage::throwDuplicateOrUnknown(int rc, TransactionID txn, const std::string& key) const { void LMDBAL::iStorage::throwDuplicateOrUnknown(int rc, TransactionID txn, const std::string& key) const {
abortTransaction(txn); abortTransaction(txn);
throwDuplicateOrUnknown(rc, key);
}
void LMDBAL::iStorage::throwNotFoundOrUnknown(int rc, LMDBAL::TransactionID txn, const std::string& key) const {
abortTransaction(txn);
throwNotFoundOrUnknown(rc, key);
}
void LMDBAL::iStorage::throwDuplicateOrUnknown(int rc, const std::string& key) const {
if (rc == MDB_KEYEXIST) if (rc == MDB_KEYEXIST)
throwDuplicate(key); throwDuplicate(key);
else else
throwUnknown(rc); throwUnknown(rc);
} }
void LMDBAL::iStorage::throwNotFoundOrUnknown(int rc, LMDBAL::TransactionID txn, const std::string& key) const { void LMDBAL::iStorage::throwNotFoundOrUnknown(int rc, const std::string& key) const {
abortTransaction(txn);
if (rc == MDB_NOTFOUND) if (rc == MDB_NOTFOUND)
throwNotFound(key); throwNotFound(key);
else else

View File

@ -37,7 +37,9 @@ protected:
const std::string& dbName() const; const std::string& dbName() const;
void ensureOpened(const std::string& methodName) const; void ensureOpened(const std::string& methodName) const;
void throwDuplicateOrUnknown(int rc, const std::string& key) const;
void throwDuplicateOrUnknown(int rc, TransactionID txn, const std::string& key) const; void throwDuplicateOrUnknown(int rc, TransactionID txn, const std::string& key) const;
void throwNotFoundOrUnknown(int rc, const std::string& key) const;
void throwNotFoundOrUnknown(int rc, TransactionID txn, const std::string& key) const; void throwNotFoundOrUnknown(int rc, TransactionID txn, const std::string& key) const;
void throwUnknown(int rc, TransactionID txn) const; void throwUnknown(int rc, TransactionID txn) const;
void throwUnknown(int rc) const; void throwUnknown(int rc) const;
@ -89,14 +91,27 @@ protected:
public: public:
using iStorage::drop; using iStorage::drop;
virtual void addRecord(const K& key, const V& value); virtual void addRecord(const K& key, const V& value);
virtual void addRecord(const K& key, const V& value, TransactionID txn);
virtual bool forceRecord(const K& key, const V& value); //returns true if there was addition, false if change virtual bool forceRecord(const K& key, const V& value); //returns true if there was addition, false if change
virtual bool forceRecord(const K& key, const V& value, TransactionID txn);
virtual void changeRecord(const K& key, const V& value); virtual void changeRecord(const K& key, const V& value);
virtual void changeRecord(const K& key, const V& value, TransactionID txn);
virtual void removeRecord(const K& key); virtual void removeRecord(const K& key);
virtual void removeRecord(const K& key, TransactionID txn);
virtual bool checkRecord(const K& key) const; //checks if there is a record with given key virtual bool checkRecord(const K& key) const; //checks if there is a record with given key
virtual bool checkRecord(const K& key, TransactionID txn) const;
virtual void getRecord(const K& key, V& value) const;
virtual void getRecord(const K& key, V& value, TransactionID txn) const;
virtual V getRecord(const K& key) const; virtual V getRecord(const K& key) const;
virtual V getRecord(const K& key, TransactionID txn) const;
virtual std::map<K, V> readAll() const; virtual std::map<K, V> readAll() const;
virtual std::map<K, V> readAll(TransactionID txn) const;
virtual void readAll(std::map<K, V>& result) const;
virtual void readAll(std::map<K, V>& result, TransactionID txn) const;
virtual void replaceAll(const std::map<K, V>& data); virtual void replaceAll(const std::map<K, V>& data);
virtual void replaceAll(const std::map<K, V>& data, TransactionID txn);
virtual uint32_t addRecords(const std::map<K, V>& data, bool overwrite = false); virtual uint32_t addRecords(const std::map<K, V>& data, bool overwrite = false);
virtual uint32_t addRecords(const std::map<K, V>& data, TransactionID txn, bool overwrite = false);
protected: protected:
Serializer<K>* keySerializer; Serializer<K>* keySerializer;

View File

@ -38,24 +38,51 @@ LMDBAL::Storage<K, V>::~Storage() {
template<class K, class V> template<class K, class V>
void LMDBAL::Storage<K, V>::addRecord(const K& key, const V& value) { void LMDBAL::Storage<K, V>::addRecord(const K& key, const V& value) {
ensureOpened(addRecordMethodName); ensureOpened(addRecordMethodName);
TransactionID txn = beginTransaction(); TransactionID txn = beginTransaction();
try {
addRecord(key, value, txn);
} catch (...) {
abortTransaction(txn);
throw;
}
commitTransaction(txn);
}
template<class K, class V>
void LMDBAL::Storage<K, V>::addRecord(const K& key, const V& value, TransactionID txn) {
ensureOpened(addRecordMethodName);
MDB_val lmdbKey = keySerializer->setData(key); MDB_val lmdbKey = keySerializer->setData(key);
MDB_val lmdbData = valueSerializer->setData(value); MDB_val lmdbData = valueSerializer->setData(value);
int rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, MDB_NOOVERWRITE); int rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, MDB_NOOVERWRITE);
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
throwDuplicateOrUnknown(rc, txn, toString(key)); throwDuplicateOrUnknown(rc, toString(key));
commitTransaction(txn);
} }
template<class K, class V> template<class K, class V>
bool LMDBAL::Storage<K, V>::forceRecord(const K& key, const V& value) { bool LMDBAL::Storage<K, V>::forceRecord(const K& key, const V& value) {
ensureOpened(forceRecordMethodName); ensureOpened(forceRecordMethodName);
bool added;
TransactionID txn = beginTransaction(); TransactionID txn = beginTransaction();
bool added;
try {
added = forceRecord(key, value, txn);
} catch (...) {
abortTransaction(txn);
throw;
}
commitTransaction(txn);
return added;
}
template<class K, class V>
bool LMDBAL::Storage<K, V>::forceRecord(const K& key, const V& value, TransactionID txn) {
ensureOpened(forceRecordMethodName);
bool added;
MDB_val lmdbKey = keySerializer->setData(key); MDB_val lmdbKey = keySerializer->setData(key);
MDB_val lmdbData; MDB_val lmdbData;
@ -69,15 +96,13 @@ bool LMDBAL::Storage<K, V>::forceRecord(const K& key, const V& value) {
break; break;
default: default:
added = false; added = false;
throwUnknown(rc, txn); throwUnknown(rc);
} }
lmdbData = valueSerializer->setData(value); lmdbData = valueSerializer->setData(value);
rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, 0); rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, 0);
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
throwUnknown(rc, txn); throwUnknown(rc);
commitTransaction(txn);
return added; return added;
} }
@ -87,32 +112,73 @@ void LMDBAL::Storage<K, V>::changeRecord(const K& key, const V& value) {
ensureOpened(changeRecordMethodName); ensureOpened(changeRecordMethodName);
TransactionID txn = beginTransaction(); TransactionID txn = beginTransaction();
try {
changeRecord(key, value, txn);
} catch (...) {
abortTransaction(txn);
throw;
}
commitTransaction(txn);
}
template<class K, class V>
void LMDBAL::Storage<K, V>::changeRecord(const K& key, const V& value, TransactionID txn) {
ensureOpened(changeRecordMethodName);
MDB_val lmdbKey = keySerializer->setData(key); MDB_val lmdbKey = keySerializer->setData(key);
MDB_val lmdbData = valueSerializer->setData(value); MDB_val lmdbData = valueSerializer->setData(value);
int rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, 0); int rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, 0);
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
throwUnknown(rc, txn); throwUnknown(rc);
commitTransaction(txn);
} }
template<class K, class V> template<class K, class V>
V LMDBAL::Storage<K, V>::getRecord(const K& key) const { V LMDBAL::Storage<K, V>::getRecord(const K& key) const {
ensureOpened(getRecordMethodName); ensureOpened(getRecordMethodName);
V value;
getRecord(key, value);
return value;
}
template<class K, class V>
void LMDBAL::Storage<K, V>::getRecord(const K& key, V& value) const {
ensureOpened(getRecordMethodName);
TransactionID txn = beginReadOnlyTransaction(); TransactionID txn = beginReadOnlyTransaction();
try {
getRecord(key, value, txn);
} catch (...) {
abortTransaction(txn);
throw;
}
abortTransaction(txn);
}
template<class K, class V>
V LMDBAL::Storage<K, V>::getRecord(const K& key, TransactionID txn) const {
ensureOpened(getRecordMethodName);
V value;
getRecord(key, value, txn);
return value;
}
template<class K, class V>
void LMDBAL::Storage<K, V>::getRecord(const K& key, V& value, TransactionID txn) const {
ensureOpened(getRecordMethodName);
MDB_val lmdbKey = keySerializer->setData(key); MDB_val lmdbKey = keySerializer->setData(key);
MDB_val lmdbData; MDB_val lmdbData;
int rc = mdb_get(txn, dbi, &lmdbKey, &lmdbData); int rc = mdb_get(txn, dbi, &lmdbKey, &lmdbData);
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
throwNotFoundOrUnknown(rc, txn, toString(key)); throwNotFoundOrUnknown(rc, toString(key));
V value = valueSerializer->deserialize(lmdbData); valueSerializer->deserialize(lmdbData, value);
abortTransaction(txn);
return value;
} }
template<class K, class V> template<class K, class V>
@ -120,12 +186,26 @@ bool LMDBAL::Storage<K, V>::checkRecord(const K& key) const {
ensureOpened(checkRecordMethodName); ensureOpened(checkRecordMethodName);
TransactionID txn = beginReadOnlyTransaction(); TransactionID txn = beginReadOnlyTransaction();
bool result;
try {
result = checkRecord(key, txn);
} catch (...) {
abortTransaction(txn);
throw;
}
abortTransaction(txn);
return result;
}
template<class K, class V>
bool LMDBAL::Storage<K, V>::checkRecord(const K& key, TransactionID txn) const {
ensureOpened(checkRecordMethodName);
MDB_val lmdbKey = keySerializer->setData(key); MDB_val lmdbKey = keySerializer->setData(key);
MDB_val lmdbData; MDB_val lmdbData;
int rc = mdb_get(txn, dbi, &lmdbKey, &lmdbData); int rc = mdb_get(txn, dbi, &lmdbKey, &lmdbData);
abortTransaction(txn);
if (rc == MDB_SUCCESS) if (rc == MDB_SUCCESS)
return true; return true;
@ -139,28 +219,57 @@ template<class K, class V>
std::map<K, V> LMDBAL::Storage<K, V>::readAll() const { std::map<K, V> LMDBAL::Storage<K, V>::readAll() const {
ensureOpened(readAllMethodName); ensureOpened(readAllMethodName);
TransactionID txn = beginReadOnlyTransaction();
std::map<K, V> result; std::map<K, V> result;
readAll(result);
return result;
}
template<class K, class V>
void LMDBAL::Storage<K, V>::readAll(std::map<K, V>& result) const {
ensureOpened(readAllMethodName);
TransactionID txn = beginReadOnlyTransaction();
try {
readAll(result, txn);
} catch (...) {
abortTransaction(txn);
throw;
}
abortTransaction(txn);
}
template<class K, class V>
std::map<K, V> LMDBAL::Storage<K, V>::readAll(TransactionID txn) const {
ensureOpened(readAllMethodName);
std::map<K, V> result;
readAll(result, txn);
return result;
}
template<class K, class V>
void LMDBAL::Storage<K, V>::readAll(std::map<K, V>& result, TransactionID txn) const {
ensureOpened(readAllMethodName);
MDB_cursor* cursor; MDB_cursor* cursor;
MDB_val lmdbKey, lmdbData; MDB_val lmdbKey, lmdbData;
int rc = mdb_cursor_open(txn, dbi, &cursor); int rc = mdb_cursor_open(txn, dbi, &cursor);
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
throwUnknown(rc, txn); throwUnknown(rc);
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_FIRST); rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_FIRST);
while (rc == MDB_SUCCESS) { while (rc == MDB_SUCCESS) {
K key = keySerializer->deserialize(lmdbKey); K key;
V value = valueSerializer->deserialize(lmdbData); keySerializer->deserialize(lmdbKey, key);
result.insert(std::make_pair(key, value)); V& value = result[key];
valueSerializer->deserialize(lmdbData, value);
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_NEXT); rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_NEXT);
} }
abortTransaction(txn);
if (rc != MDB_NOTFOUND) if (rc != MDB_NOTFOUND)
throwUnknown(rc); throwUnknown(rc);
return result;
} }
template<class K, class V> template<class K, class V>
@ -168,9 +277,23 @@ void LMDBAL::Storage<K, V>::replaceAll(const std::map<K, V>& data) {
ensureOpened(replaceAllMethodName); ensureOpened(replaceAllMethodName);
TransactionID txn = beginTransaction(); TransactionID txn = beginTransaction();
try {
replaceAll(data, txn);
} catch (...) {
abortTransaction(txn);
throw;
}
commitTransaction(txn);
}
template<class K, class V>
void LMDBAL::Storage<K, V>::replaceAll(const std::map<K, V>& data, TransactionID txn) {
ensureOpened(replaceAllMethodName);
int rc = drop(txn); int rc = drop(txn);
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
throwUnknown(rc, txn); throwUnknown(rc);
MDB_val lmdbKey, lmdbData; MDB_val lmdbKey, lmdbData;
for (const std::pair<const K, V>& pair : data) { for (const std::pair<const K, V>& pair : data) {
@ -179,9 +302,8 @@ void LMDBAL::Storage<K, V>::replaceAll(const std::map<K, V>& data) {
rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, MDB_NOOVERWRITE); rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, MDB_NOOVERWRITE);
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
throwUnknown(rc, txn); throwUnknown(rc);
} }
commitTransaction(txn);
} }
template<class K, class V> template<class K, class V>
@ -189,27 +311,39 @@ uint32_t LMDBAL::Storage<K, V>::addRecords(const std::map<K, V>& data, bool over
ensureOpened(addRecordsMethodName); ensureOpened(addRecordsMethodName);
TransactionID txn = beginTransaction(); TransactionID txn = beginTransaction();
uint32_t amount;
try {
amount = addRecords(data, txn, overwrite);
} catch (...) {
abortTransaction(txn);
throw;
}
commitTransaction(txn);
return amount;
}
template<class K, class V>
uint32_t LMDBAL::Storage<K, V>::addRecords(const std::map<K, V>& data, TransactionID txn, bool overwrite) {
ensureOpened(addRecordsMethodName);
MDB_val lmdbKey, lmdbData; MDB_val lmdbKey, lmdbData;
int rc; int rc;
for (const std::pair<const K, V>& pair : data) { for (const std::pair<const K, V>& pair : data) {
lmdbKey = keySerializer->setData(pair.first); lmdbKey = keySerializer->setData(pair.first);
lmdbData = valueSerializer->setData(pair.second); lmdbData = valueSerializer->setData(pair.second);
rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, overwrite ? 0 : MDB_NOOVERWRITE); rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, overwrite ? 0 : MDB_NOOVERWRITE);
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
throwUnknown(rc, txn); throwUnknown(rc);
} }
MDB_stat stat; MDB_stat stat;
rc = mdb_stat(txn, dbi, &stat); rc = mdb_stat(txn, dbi, &stat);
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
throwUnknown(rc, txn); throwUnknown(rc);
uint32_t amount = stat.ms_entries; return stat.ms_entries;
commitTransaction(txn);
return amount;
} }
template<class K, class V> template<class K, class V>
@ -217,12 +351,24 @@ void LMDBAL::Storage<K, V>::removeRecord(const K& key) {
ensureOpened(removeRecordMethodName); ensureOpened(removeRecordMethodName);
TransactionID txn = beginTransaction(); TransactionID txn = beginTransaction();
try {
removeRecord(key, txn);
} catch (...) {
abortTransaction(txn);
throw;
}
commitTransaction(txn);
}
template<class K, class V>
void LMDBAL::Storage<K, V>::removeRecord(const K& key, TransactionID txn) {
ensureOpened(removeRecordMethodName);
MDB_val lmdbKey = keySerializer->setData(key); MDB_val lmdbKey = keySerializer->setData(key);
int rc = mdb_del(txn, dbi, &lmdbKey, NULL); int rc = mdb_del(txn, dbi, &lmdbKey, NULL);
if (rc != MDB_SUCCESS) if (rc != MDB_SUCCESS)
throwNotFoundOrUnknown(rc, txn, toString(key)); throwNotFoundOrUnknown(rc, toString(key));
commitTransaction(txn);
} }
template<class K, class V> template<class K, class V>