external transaction methods for storage
This commit is contained in:
parent
f39d44890a
commit
e2dbea21d1
19 changed files with 273 additions and 58 deletions
226
src/storage.hpp
226
src/storage.hpp
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue