forked from blue/lmdbal
external transaction methods for storage
This commit is contained in:
parent
f39d44890a
commit
e2dbea21d1
@ -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"
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
226
src/storage.hpp
226
src/storage.hpp
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user