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

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