forked from blue/lmdbal
some more transaction thought on cache
This commit is contained in:
parent
f0779ae2aa
commit
8be63d7551
18
src/base.cpp
18
src/base.cpp
@ -120,13 +120,15 @@ void LMDBAL::Base::drop() {
|
|||||||
if (!opened)
|
if (!opened)
|
||||||
throw Closed("drop", name);
|
throw Closed("drop", name);
|
||||||
|
|
||||||
TransactionID txn = beginPrivateTransaction(emptyName);
|
TransactionID txn = beginTransaction();
|
||||||
for (const std::pair<const std::string, iStorage*>& pair : storages) {
|
for (const std::pair<const std::string, iStorage*>& pair : storages) {
|
||||||
int rc = pair.second->drop(txn);
|
int rc = pair.second->drop(txn);
|
||||||
if (rc)
|
if (rc != MDB_SUCCESS) {
|
||||||
|
abortTransaction(txn);
|
||||||
throw Unknown(name, mdb_strerror(rc), pair.first);
|
throw Unknown(name, mdb_strerror(rc), pair.first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
commitPrivateTransaction(txn, emptyName);
|
commitTransaction(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
LMDBAL::TransactionID LMDBAL::Base::beginReadOnlyTransaction() const {
|
LMDBAL::TransactionID LMDBAL::Base::beginReadOnlyTransaction() const {
|
||||||
@ -138,7 +140,7 @@ LMDBAL::TransactionID LMDBAL::Base::beginTransaction() const {
|
|||||||
void LMDBAL::Base::abortTransaction(LMDBAL::TransactionID id) const {
|
void LMDBAL::Base::abortTransaction(LMDBAL::TransactionID id) const {
|
||||||
return abortTransaction(id, emptyName);}
|
return abortTransaction(id, emptyName);}
|
||||||
|
|
||||||
void LMDBAL::Base::commitTransaction(LMDBAL::TransactionID id) const {
|
void LMDBAL::Base::commitTransaction(LMDBAL::TransactionID id) {
|
||||||
return commitTransaction(id, emptyName);}
|
return commitTransaction(id, emptyName);}
|
||||||
|
|
||||||
LMDBAL::TransactionID LMDBAL::Base::beginReadOnlyTransaction(const std::string& storageName) const {
|
LMDBAL::TransactionID LMDBAL::Base::beginReadOnlyTransaction(const std::string& storageName) const {
|
||||||
@ -180,7 +182,7 @@ void LMDBAL::Base::abortTransaction(LMDBAL::TransactionID id, const std::string&
|
|||||||
transactions->erase(itr);
|
transactions->erase(itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LMDBAL::Base::commitTransaction(LMDBAL::TransactionID id, const std::string& storageName) const {
|
void LMDBAL::Base::commitTransaction(LMDBAL::TransactionID id, const std::string& storageName) {
|
||||||
if (!opened)
|
if (!opened)
|
||||||
throw Closed("abortTransaction", name, storageName);
|
throw Closed("abortTransaction", name, storageName);
|
||||||
|
|
||||||
@ -198,7 +200,7 @@ void LMDBAL::Base::commitTransaction(LMDBAL::TransactionID id, const std::string
|
|||||||
LMDBAL::TransactionID LMDBAL::Base::beginPrivateReadOnlyTransaction(const std::string& storageName) const {
|
LMDBAL::TransactionID LMDBAL::Base::beginPrivateReadOnlyTransaction(const std::string& storageName) const {
|
||||||
MDB_txn* txn;
|
MDB_txn* txn;
|
||||||
int rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
|
int rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
|
||||||
if (rc) {
|
if (rc != MDB_SUCCESS) {
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
throw Unknown(name, mdb_strerror(rc), storageName);
|
throw Unknown(name, mdb_strerror(rc), storageName);
|
||||||
}
|
}
|
||||||
@ -208,7 +210,7 @@ LMDBAL::TransactionID LMDBAL::Base::beginPrivateReadOnlyTransaction(const std::s
|
|||||||
LMDBAL::TransactionID LMDBAL::Base::beginPrivateTransaction(const std::string& storageName) const {
|
LMDBAL::TransactionID LMDBAL::Base::beginPrivateTransaction(const std::string& storageName) const {
|
||||||
MDB_txn* txn;
|
MDB_txn* txn;
|
||||||
int rc = mdb_txn_begin(environment, NULL, 0, &txn);
|
int rc = mdb_txn_begin(environment, NULL, 0, &txn);
|
||||||
if (rc) {
|
if (rc != MDB_SUCCESS) {
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
throw Unknown(name, mdb_strerror(rc), storageName);
|
throw Unknown(name, mdb_strerror(rc), storageName);
|
||||||
}
|
}
|
||||||
@ -220,7 +222,7 @@ void LMDBAL::Base::abortPrivateTransaction(LMDBAL::TransactionID id, const std::
|
|||||||
mdb_txn_abort(id);
|
mdb_txn_abort(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LMDBAL::Base::commitPrivateTransaction(LMDBAL::TransactionID id, const std::string& storageName) const {
|
void LMDBAL::Base::commitPrivateTransaction(LMDBAL::TransactionID id, const std::string& storageName) {
|
||||||
int rc = mdb_txn_commit(id);
|
int rc = mdb_txn_commit(id);
|
||||||
if (rc != MDB_SUCCESS)
|
if (rc != MDB_SUCCESS)
|
||||||
throw Unknown(name, mdb_strerror(rc), storageName);
|
throw Unknown(name, mdb_strerror(rc), storageName);
|
||||||
|
@ -65,7 +65,7 @@ public:
|
|||||||
|
|
||||||
TransactionID beginReadOnlyTransaction() const;
|
TransactionID beginReadOnlyTransaction() const;
|
||||||
TransactionID beginTransaction() const;
|
TransactionID beginTransaction() const;
|
||||||
void commitTransaction(TransactionID id) const;
|
void commitTransaction(TransactionID id);
|
||||||
void abortTransaction(TransactionID id) const;
|
void abortTransaction(TransactionID id) const;
|
||||||
|
|
||||||
template <class K, class V>
|
template <class K, class V>
|
||||||
@ -86,12 +86,12 @@ private:
|
|||||||
|
|
||||||
TransactionID beginReadOnlyTransaction(const std::string& storageName) const;
|
TransactionID beginReadOnlyTransaction(const std::string& storageName) const;
|
||||||
TransactionID beginTransaction(const std::string& storageName) const;
|
TransactionID beginTransaction(const std::string& storageName) const;
|
||||||
void commitTransaction(TransactionID id, const std::string& storageName) const;
|
void commitTransaction(TransactionID id, const std::string& storageName);
|
||||||
void abortTransaction(TransactionID id, const std::string& storageName) const;
|
void abortTransaction(TransactionID id, const std::string& storageName) const;
|
||||||
|
|
||||||
TransactionID beginPrivateReadOnlyTransaction(const std::string& storageName) const;
|
TransactionID beginPrivateReadOnlyTransaction(const std::string& storageName) const;
|
||||||
TransactionID beginPrivateTransaction(const std::string& storageName) const;
|
TransactionID beginPrivateTransaction(const std::string& storageName) const;
|
||||||
void commitPrivateTransaction(TransactionID id, const std::string& storageName) const;
|
void commitPrivateTransaction(TransactionID id, const std::string& storageName);
|
||||||
void abortPrivateTransaction(TransactionID id, const std::string& storageName) const;
|
void abortPrivateTransaction(TransactionID id, const std::string& storageName) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
41
src/cache.h
41
src/cache.h
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
|
||||||
@ -34,33 +35,63 @@ class Cache : public Storage<K, V> {
|
|||||||
size, // - know just an amount of records
|
size, // - know just an amount of records
|
||||||
full // - shure that our cache is equal to the database on disk
|
full // - shure that our cache is equal to the database on disk
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Operation {
|
||||||
|
add,
|
||||||
|
remove,
|
||||||
|
change,
|
||||||
|
force,
|
||||||
|
drop,
|
||||||
|
replace,
|
||||||
|
addMany
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::pair<Operation, void*> Entry;
|
||||||
|
typedef std::list<Entry> Queue;
|
||||||
|
typedef std::map<TransactionID, Queue> TransactionCache;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Cache(const std::string& name, Base* parent);
|
Cache(const std::string& name, Base* parent);
|
||||||
~Cache() override;
|
~Cache() override;
|
||||||
|
|
||||||
|
virtual void transactionStarted(TransactionID txn, bool readOnly) const override;
|
||||||
|
virtual void transactionCommited(TransactionID txn) override;
|
||||||
|
virtual void transactionAborted(TransactionID txn) const override;
|
||||||
private:
|
private:
|
||||||
void handleMode() const;
|
void handleMode() const;
|
||||||
|
|
||||||
|
void handleTransactionEntry(const Entry& entry);
|
||||||
|
void destroyTransactionEntry(const Entry& entry) const;
|
||||||
|
|
||||||
|
void handleAddRecord(const K& key, const V& value);
|
||||||
|
void handleRemoveRecord(const K& key);
|
||||||
|
void handleChangeRecord(const K& key, const V& value);
|
||||||
|
void handleForceRecord(const K& key, const V& value, bool added);
|
||||||
|
void handleReplaceAll(std::map<K, V>* data);
|
||||||
|
void handleAddRecords(const std::map<K, V>& data, bool overwrite, SizeType newSize);
|
||||||
|
void handleDrop();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using Storage<K, V>::drop;
|
||||||
|
virtual int drop(TransactionID transaction) override;
|
||||||
virtual void addRecord(const K& key, const V& value) override;
|
virtual void addRecord(const K& key, const V& value) override;
|
||||||
virtual bool forceRecord(const K& key, const V& value) override;
|
virtual bool forceRecord(const K& key, const V& value) override;
|
||||||
virtual void changeRecord(const K& key, const V& value) override;
|
virtual void changeRecord(const K& key, const V& value) override;
|
||||||
virtual void removeRecord(const K& key) override;
|
virtual void removeRecord(const K& key) override;
|
||||||
virtual bool checkRecord(const K& key) const override;
|
virtual bool checkRecord(const K& key) const override;
|
||||||
virtual V getRecord(const K& key) const override;
|
virtual V getRecord(const K& key) const override;
|
||||||
virtual uint32_t count() const override;
|
virtual SizeType count() const override;
|
||||||
|
|
||||||
using Storage<K, V>::drop;
|
|
||||||
virtual int drop(MDB_txn * transaction) override;
|
|
||||||
virtual std::map<K, V> readAll() const override;
|
virtual std::map<K, V> readAll() const override;
|
||||||
virtual void replaceAll(const std::map<K, V>& data) override;
|
virtual void replaceAll(const std::map<K, V>& data) override;
|
||||||
virtual uint32_t addRecords(const std::map<K, V>& data, bool overwrite = false) override;
|
virtual SizeType addRecords(const std::map<K, V>& data, bool overwrite = false) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Mode* mode;
|
Mode* mode;
|
||||||
std::map<K, V>* cache;
|
std::map<K, V>* cache;
|
||||||
std::set<K>* abscent;
|
std::set<K>* abscent;
|
||||||
uint32_t* sizeDifference;
|
SizeType* sizeDifference;
|
||||||
|
TransactionCache* transactionCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
180
src/cache.hpp
180
src/cache.hpp
@ -28,7 +28,8 @@ LMDBAL::Cache<K, V>::Cache(const std::string& p_name, Base* parent):
|
|||||||
mode(new Mode),
|
mode(new Mode),
|
||||||
cache(new std::map<K, V>()),
|
cache(new std::map<K, V>()),
|
||||||
abscent(new std::set<K>()),
|
abscent(new std::set<K>()),
|
||||||
sizeDifference(new uint32_t)
|
sizeDifference(new uint32_t),
|
||||||
|
transactionCache(new TransactionCache)
|
||||||
{
|
{
|
||||||
*mode = Mode::nothing;
|
*mode = Mode::nothing;
|
||||||
*sizeDifference = 0;
|
*sizeDifference = 0;
|
||||||
@ -36,6 +37,7 @@ LMDBAL::Cache<K, V>::Cache(const std::string& p_name, Base* parent):
|
|||||||
|
|
||||||
template<class K, class V>
|
template<class K, class V>
|
||||||
LMDBAL::Cache<K, V>::~Cache() {
|
LMDBAL::Cache<K, V>::~Cache() {
|
||||||
|
delete transactionCache;
|
||||||
delete sizeDifference;
|
delete sizeDifference;
|
||||||
delete mode;
|
delete mode;
|
||||||
delete cache;
|
delete cache;
|
||||||
@ -50,6 +52,11 @@ void LMDBAL::Cache<K, V>::addRecord(const K& key, const V& value) {
|
|||||||
iStorage::throwDuplicate(iStorage::toString(key));
|
iStorage::throwDuplicate(iStorage::toString(key));
|
||||||
|
|
||||||
Storage<K, V>::addRecord(key, value);
|
Storage<K, V>::addRecord(key, value);
|
||||||
|
handleAddRecord(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::handleAddRecord(const K& key, const V& value) {
|
||||||
cache->insert(std::make_pair(key, value));
|
cache->insert(std::make_pair(key, value));
|
||||||
|
|
||||||
if (*mode != Mode::full)
|
if (*mode != Mode::full)
|
||||||
@ -61,6 +68,13 @@ bool LMDBAL::Cache<K, V>::forceRecord(const K& key, const V& value) {
|
|||||||
iStorage::ensureOpened(iStorage::forceRecordMethodName);
|
iStorage::ensureOpened(iStorage::forceRecordMethodName);
|
||||||
|
|
||||||
bool added = Storage<K, V>::forceRecord(key, value);
|
bool added = Storage<K, V>::forceRecord(key, value);
|
||||||
|
handleForceRecord(key, value, added);
|
||||||
|
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::handleForceRecord(const K& key, const V& value, bool added) {
|
||||||
if (*mode == Mode::full) {
|
if (*mode == Mode::full) {
|
||||||
(*cache)[key] = value;
|
(*cache)[key] = value;
|
||||||
} else {
|
} else {
|
||||||
@ -73,8 +87,6 @@ bool LMDBAL::Cache<K, V>::forceRecord(const K& key, const V& value) {
|
|||||||
else if (!added) //this way database had value but cache didn't, so, need to decrease sizeDifference
|
else if (!added) //this way database had value but cache didn't, so, need to decrease sizeDifference
|
||||||
handleMode();
|
handleMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
return added;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class K, class V>
|
template<class K, class V>
|
||||||
@ -106,6 +118,19 @@ void LMDBAL::Cache<K, V>::changeRecord(const K& key, const V& value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::handleChangeRecord(const K& key, const V& value) {
|
||||||
|
if (*mode == Mode::full) {
|
||||||
|
cache->at(key) = value;
|
||||||
|
} else {
|
||||||
|
typename std::pair<typename std::map<K, V>::iterator, bool> res = cache->insert(std::make_pair(key, value));
|
||||||
|
if (!res.second)
|
||||||
|
res.first->second = value;
|
||||||
|
else
|
||||||
|
handleMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<class K, class V>
|
template<class K, class V>
|
||||||
V LMDBAL::Cache<K, V>::getRecord(const K& key) const {
|
V LMDBAL::Cache<K, V>::getRecord(const K& key) const {
|
||||||
iStorage::ensureOpened(iStorage::getRecordMethodName);
|
iStorage::ensureOpened(iStorage::getRecordMethodName);
|
||||||
@ -181,9 +206,27 @@ void LMDBAL::Cache<K, V>::replaceAll(const std::map<K, V>& data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class K, class V>
|
template<class K, class V>
|
||||||
uint32_t LMDBAL::Cache<K, V>::addRecords(const std::map<K, V>& data, bool overwrite) {
|
void LMDBAL::Cache<K, V>::handleReplaceAll(std::map<K, V>* data) {
|
||||||
uint32_t newSize = Storage<K, V>::addRecords(data, overwrite);
|
delete cache;
|
||||||
|
cache = data;
|
||||||
|
|
||||||
|
if (*mode != Mode::full) {
|
||||||
|
*mode = Mode::full;
|
||||||
|
abscent->clear();
|
||||||
|
*sizeDifference = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
LMDBAL::SizeType LMDBAL::Cache<K, V>::addRecords(const std::map<K, V>& data, bool overwrite) {
|
||||||
|
SizeType newSize = Storage<K, V>::addRecords(data, overwrite);
|
||||||
|
handleAddRecords(data, overwrite, newSize);
|
||||||
|
|
||||||
|
return newSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::handleAddRecords(const std::map<K, V>& data, bool overwrite, SizeType newSize) {
|
||||||
Mode& m = *mode;
|
Mode& m = *mode;
|
||||||
if (m == Mode::nothing)
|
if (m == Mode::nothing)
|
||||||
m = Mode::size;
|
m = Mode::size;
|
||||||
@ -207,19 +250,27 @@ uint32_t LMDBAL::Cache<K, V>::addRecords(const std::map<K, V>& data, bool overwr
|
|||||||
abscent->clear();
|
abscent->clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class K, class V>
|
template<class K, class V>
|
||||||
void LMDBAL::Cache<K, V>::removeRecord(const K& key) {
|
void LMDBAL::Cache<K, V>::removeRecord(const K& key) {
|
||||||
iStorage::ensureOpened(iStorage::removeRecordMethodName);
|
iStorage::ensureOpened(iStorage::removeRecordMethodName);
|
||||||
|
|
||||||
typename std::pair<typename std::set<K>::const_iterator, bool> pair = abscent->insert(key);
|
bool noKey = false;
|
||||||
if (!pair.second)
|
if (*mode != Mode::full)
|
||||||
|
noKey = cache->count(key) == 0;
|
||||||
|
else
|
||||||
|
noKey = abscent->count(key) > 0;
|
||||||
|
|
||||||
|
if (noKey)
|
||||||
iStorage::throwNotFound(iStorage::toString(key));
|
iStorage::throwNotFound(iStorage::toString(key));
|
||||||
|
|
||||||
Storage<K, V>::removeRecord(key);
|
Storage<K, V>::removeRecord(key);
|
||||||
|
handleRemoveRecord(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::handleRemoveRecord(const K& key) {
|
||||||
if (cache->erase(key) == 0) //if it was not cached and we are now in size mode then the sizeDifference would decrease
|
if (cache->erase(key) == 0) //if it was not cached and we are now in size mode then the sizeDifference would decrease
|
||||||
handleMode();
|
handleMode();
|
||||||
|
|
||||||
@ -263,13 +314,120 @@ void LMDBAL::Cache<K, V>::handleMode() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class K, class V>
|
template<class K, class V>
|
||||||
int LMDBAL::Cache<K, V>::drop(MDB_txn * transaction) {
|
int LMDBAL::Cache<K, V>::drop(TransactionID transaction) {
|
||||||
int res = Storage<K, V>::drop(transaction);
|
int res = Storage<K, V>::drop(transaction);
|
||||||
|
|
||||||
|
transactionCache->at(transaction).emplace_back(Operation::drop, nullptr);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::handleDrop() {
|
||||||
cache->clear();
|
cache->clear();
|
||||||
abscent->clear();
|
abscent->clear();
|
||||||
*mode = Mode::full;
|
*mode = Mode::full;
|
||||||
*sizeDifference = 0;
|
*sizeDifference = 0;
|
||||||
return res;
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::transactionStarted(TransactionID txn, bool readOnly) const {
|
||||||
|
if (!readOnly)
|
||||||
|
transactionCache->emplace(txn, Queue());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::transactionCommited(TransactionID txn) {
|
||||||
|
typename TransactionCache::iterator itr = transactionCache->find(txn);
|
||||||
|
if (itr != transactionCache->end()) {
|
||||||
|
Queue& queue = itr->second;
|
||||||
|
for (const Entry& entry : queue)
|
||||||
|
handleTransactionEntry(entry);
|
||||||
|
|
||||||
|
transactionCache->erase(itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::transactionAborted(TransactionID txn) const {
|
||||||
|
typename TransactionCache::iterator itr = transactionCache->find(txn);
|
||||||
|
if (itr != transactionCache->end()) {
|
||||||
|
Queue& queue = itr->second;
|
||||||
|
for (const Entry& entry : queue)
|
||||||
|
destroyTransactionEntry(entry);
|
||||||
|
|
||||||
|
transactionCache->erase(itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::handleTransactionEntry(const Entry& entry) {
|
||||||
|
switch (entry.first) {
|
||||||
|
case Operation::add: {
|
||||||
|
std::pair<K, V>* pair = static_cast<std::pair<K, V>*>(entry.second);
|
||||||
|
handleAddRecord(pair->first, pair->second);
|
||||||
|
delete pair;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Operation::remove: {
|
||||||
|
K* key = static_cast<K*>(entry.second);
|
||||||
|
handleRemoveRecord(*key);
|
||||||
|
delete key;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case Operation::change: {
|
||||||
|
std::pair<K, V>* pair = static_cast<std::pair<K, V>*>(entry.second);
|
||||||
|
handleChangeRecord(pair->first, pair->second);
|
||||||
|
delete pair;
|
||||||
|
}
|
||||||
|
case Operation::force: {
|
||||||
|
std::tuple<bool, K, V>* tuple = static_cast<std::tuple<bool, K, V>*>(entry.second);
|
||||||
|
const std::tuple<bool, K, V>& t = *tuple;
|
||||||
|
handleForceRecord(std::get<1>(t), std::get<2>(t), std::get<0>(t));
|
||||||
|
delete tuple;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Operation::drop:
|
||||||
|
handleDrop();
|
||||||
|
break;
|
||||||
|
case Operation::replace:
|
||||||
|
handleReplaceAll(static_cast<std::map<K, V>*>(entry.second)); //I take ownership, no need to delete
|
||||||
|
break;
|
||||||
|
case Operation::addMany: {
|
||||||
|
std::tuple<bool, SizeType, std::map<K, V>>* tuple = static_cast<std::tuple<bool, SizeType, std::map<K, V>>*>(entry.second);
|
||||||
|
const std::tuple<bool, SizeType, std::map<K, V>>& t = * tuple;
|
||||||
|
handleAddRecords(std::get<2>(t), std::get<0>(t), std::get<1>(t));
|
||||||
|
delete tuple;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class K, class V>
|
||||||
|
void LMDBAL::Cache<K, V>::destroyTransactionEntry(const Entry& entry) const {
|
||||||
|
switch (entry.first) {
|
||||||
|
case Operation::add:
|
||||||
|
delete static_cast<std::pair<K, V>*>(entry.second);
|
||||||
|
break;
|
||||||
|
case Operation::remove:
|
||||||
|
delete static_cast<K*>(entry.second);
|
||||||
|
break;
|
||||||
|
case Operation::change:
|
||||||
|
delete static_cast<std::pair<K, V>*>(entry.second);
|
||||||
|
break;
|
||||||
|
case Operation::force:
|
||||||
|
delete static_cast<std::tuple<bool, K, V>*>(entry.second);
|
||||||
|
break;
|
||||||
|
case Operation::drop:
|
||||||
|
break;
|
||||||
|
case Operation::replace:
|
||||||
|
delete static_cast<std::map<K, V>*>(entry.second);
|
||||||
|
break;
|
||||||
|
case Operation::addMany:
|
||||||
|
delete static_cast<std::tuple<bool, SizeType, std::map<K, V>>*>(entry.second);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //LMDBAL_CACHE_HPP
|
#endif //LMDBAL_CACHE_HPP
|
||||||
|
@ -31,31 +31,20 @@ LMDBAL::iStorage::~iStorage() {}
|
|||||||
void LMDBAL::iStorage::drop() {
|
void LMDBAL::iStorage::drop() {
|
||||||
ensureOpened(dropMethodName);
|
ensureOpened(dropMethodName);
|
||||||
|
|
||||||
MDB_txn *txn;
|
TransactionID txn = db->beginTransaction();
|
||||||
int rc = mdb_txn_begin(db->environment, NULL, 0, &txn);
|
int rc = drop(txn);
|
||||||
if (rc) {
|
if (rc != MDB_SUCCESS) {
|
||||||
mdb_txn_abort(txn);
|
abortTransaction(txn);
|
||||||
throw Unknown(db->name, mdb_strerror(rc), name);
|
|
||||||
}
|
|
||||||
rc = drop(txn);
|
|
||||||
if (rc) {
|
|
||||||
mdb_txn_abort(txn);
|
|
||||||
throw Unknown(db->name, mdb_strerror(rc), name);
|
throw Unknown(db->name, mdb_strerror(rc), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
mdb_txn_commit(txn);
|
db->commitTransaction(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int LMDBAL::iStorage::drop(MDB_txn* transaction) {
|
int LMDBAL::iStorage::drop(TransactionID transaction) {
|
||||||
return mdb_drop(transaction, dbi, 0);
|
return mdb_drop(transaction, dbi, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & LMDBAL::iStorage::dbName() const {
|
|
||||||
return db->name;}
|
|
||||||
|
|
||||||
bool LMDBAL::iStorage::isDBOpened() const {
|
|
||||||
return db->opened;}
|
|
||||||
|
|
||||||
void LMDBAL::iStorage::ensureOpened(const std::string& methodName) const {
|
void LMDBAL::iStorage::ensureOpened(const std::string& methodName) const {
|
||||||
if (!db->opened)
|
if (!db->opened)
|
||||||
throw Closed(methodName, db->name, name);
|
throw Closed(methodName, db->name, name);
|
||||||
@ -80,10 +69,8 @@ LMDBAL::SizeType LMDBAL::iStorage::count() const {
|
|||||||
LMDBAL::SizeType LMDBAL::iStorage::count(TransactionID txn) const {
|
LMDBAL::SizeType LMDBAL::iStorage::count(TransactionID txn) const {
|
||||||
MDB_stat stat;
|
MDB_stat stat;
|
||||||
int rc = mdb_stat(txn, dbi, &stat);
|
int rc = mdb_stat(txn, dbi, &stat);
|
||||||
if (rc) {
|
if (rc != MDB_SUCCESS)
|
||||||
mdb_txn_abort(txn);
|
|
||||||
throw Unknown(db->name, mdb_strerror(rc), name);
|
throw Unknown(db->name, mdb_strerror(rc), name);
|
||||||
}
|
|
||||||
|
|
||||||
return stat.ms_entries;
|
return stat.ms_entries;
|
||||||
}
|
}
|
||||||
@ -117,6 +104,12 @@ void LMDBAL::iStorage::throwUnknown(int rc, LMDBAL::TransactionID txn) const {
|
|||||||
throwUnknown(rc);
|
throwUnknown(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string & LMDBAL::iStorage::dbName() const {
|
||||||
|
return db->name;}
|
||||||
|
|
||||||
|
bool LMDBAL::iStorage::isDBOpened() const {
|
||||||
|
return db->opened;}
|
||||||
|
|
||||||
void LMDBAL::iStorage::throwUnknown(int rc) const {
|
void LMDBAL::iStorage::throwUnknown(int rc) const {
|
||||||
throw Unknown(db->name, mdb_strerror(rc), name);}
|
throw Unknown(db->name, mdb_strerror(rc), name);}
|
||||||
|
|
||||||
@ -135,19 +128,18 @@ LMDBAL::TransactionID LMDBAL::iStorage::beginTransaction() const {
|
|||||||
void LMDBAL::iStorage::abortTransaction(LMDBAL::TransactionID id) const {
|
void LMDBAL::iStorage::abortTransaction(LMDBAL::TransactionID id) const {
|
||||||
db->abortPrivateTransaction(id, name);}
|
db->abortPrivateTransaction(id, name);}
|
||||||
|
|
||||||
void LMDBAL::iStorage::commitTransaction(LMDBAL::TransactionID id) const {
|
void LMDBAL::iStorage::commitTransaction(LMDBAL::TransactionID id) {
|
||||||
db->commitPrivateTransaction(id, name);}
|
db->commitPrivateTransaction(id, name);}
|
||||||
|
|
||||||
void LMDBAL::iStorage::transactionStarted(LMDBAL::TransactionID txn, bool readOnly) const {
|
void LMDBAL::iStorage::transactionStarted(LMDBAL::TransactionID txn, bool readOnly) const {
|
||||||
UNUSED(txn);
|
UNUSED(txn);
|
||||||
UNUSED(readOnly);
|
UNUSED(readOnly);
|
||||||
}
|
}
|
||||||
void LMDBAL::iStorage::transactionCommited(LMDBAL::TransactionID txn) const {
|
void LMDBAL::iStorage::transactionCommited(LMDBAL::TransactionID txn) {
|
||||||
UNUSED(txn);
|
UNUSED(txn);}
|
||||||
}
|
|
||||||
void LMDBAL::iStorage::transactionAborted(LMDBAL::TransactionID txn) const {
|
void LMDBAL::iStorage::transactionAborted(LMDBAL::TransactionID txn) const {
|
||||||
UNUSED(txn);
|
UNUSED(txn);}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ protected:
|
|||||||
virtual ~iStorage();
|
virtual ~iStorage();
|
||||||
|
|
||||||
virtual int createStorage(MDB_txn * transaction) = 0;
|
virtual int createStorage(MDB_txn * transaction) = 0;
|
||||||
virtual int drop(MDB_txn * transaction);
|
|
||||||
|
|
||||||
bool isDBOpened() const;
|
bool isDBOpened() const;
|
||||||
const std::string& dbName() const;
|
const std::string& dbName() const;
|
||||||
@ -52,14 +51,15 @@ protected:
|
|||||||
|
|
||||||
TransactionID beginReadOnlyTransaction() const;
|
TransactionID beginReadOnlyTransaction() const;
|
||||||
TransactionID beginTransaction() const;
|
TransactionID beginTransaction() const;
|
||||||
void commitTransaction(TransactionID id) const;
|
void commitTransaction(TransactionID id);
|
||||||
void abortTransaction(TransactionID id) const;
|
void abortTransaction(TransactionID id) const;
|
||||||
void transactionStarted(TransactionID txn, bool readOnly) const;
|
virtual void transactionStarted(TransactionID txn, bool readOnly) const;
|
||||||
void transactionCommited(TransactionID txn) const;
|
virtual void transactionCommited(TransactionID txn);
|
||||||
void transactionAborted(TransactionID txn) const;
|
virtual void transactionAborted(TransactionID txn) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void drop();
|
virtual void drop();
|
||||||
|
virtual int drop(TransactionID transaction);
|
||||||
virtual SizeType count() const;
|
virtual SizeType count() const;
|
||||||
virtual SizeType count(TransactionID txn) const;
|
virtual SizeType count(TransactionID txn) const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user