This commit is contained in:
Blue 2023-04-12 12:36:33 -03:00
parent 66df0da5f6
commit 2b4763b575
Signed by: blue
GPG Key ID: 9B203B252A63EE38
9 changed files with 141 additions and 49 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.16)
project(LMDBAL
VERSION 0.2.0
VERSION 0.3.0
DESCRIPTION "LMDB (Lightning Memory-Mapped Database Manager) Abstraction Layer"
LANGUAGES CXX
)

View File

@ -3,7 +3,7 @@
[![AUR license](https://img.shields.io/aur/license/lmdbal?style=flat-square)](https://git.macaw.me/blue/lmdbal/raw/branch/master/LICENSE.md)
[![AUR version](https://img.shields.io/aur/version/lmdbal?style=flat-square)](https://aur.archlinux.org/packages/lmdbal/)
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/macaw.me?logo=liberapay&style=flat-square)](https://liberapay.com/macaw.me)
[![Documentation](https://img.shields.io/badge/Documentation-HTLM-green)](https://macaw.me/lmdbal/doc/html)
[![Documentation](https://img.shields.io/badge/Documentation-HTML-green)](https://macaw.me/lmdbal/doc/html)
### Prerequisites

View File

@ -1,6 +1,6 @@
# Maintainer: Yury Gubich <blue@macaw.me>
pkgname=lmdbal
pkgver=0.2.0
pkgver=0.3.0
pkgrel=1
pkgdesc="LMDB Abstraction Layer, qt5 version"
arch=('i686' 'x86_64')
@ -19,5 +19,5 @@ build() {
}
package() {
cd "$srcdir/$pkgname"
DESTDIR="$pkgdir/" cmake --install .
cmake --install . --prefix $pkgdir/
}

View File

@ -34,7 +34,7 @@
* \brief Creates the database
*
* \param[in] _name - name of the database, it is going to affect folder name that is created to store data
* \param[in] _mapSize - LMDB map size (MBi), multiplied by 1024^2 and passed to <a class="el" href="http://www.lmdb.tech/doc/group__mdb.html#gaa2506ec8dab3d969b0e609cd82e619e5">mdb_env_set_mapsize</a> during the call of LMDBAL::Base::open()
* \param[in] _mapSize - LMDB map size (MiB), multiplied by 1024^2 and passed to <a class="el" href="http://www.lmdb.tech/doc/group__mdb.html#gaa2506ec8dab3d969b0e609cd82e619e5">mdb_env_set_mapsize</a> during the call of LMDBAL::Base::open()
*/
LMDBAL::Base::Base(const QString& _name, uint16_t _mapSize):
name(_name.toStdString()),

View File

@ -46,7 +46,7 @@ class Storage;
template <class K, class V>
class Cache;
typedef MDB_txn* TransactionID;
typedef MDB_txn* TransactionID; /**<I'm going to use transaction pointers as transaction IDs*/
class Base {
friend class iStorage;
@ -81,8 +81,8 @@ public:
LMDBAL::Cache<K, V>* getCache(const std::string& name);
private:
typedef std::map<std::string, LMDBAL::iStorage*> Storages;
typedef std::set<TransactionID> Transactions;
typedef std::map<std::string, LMDBAL::iStorage*> Storages; /**<Storage and Cache pointers are saved in the std::map*/
typedef std::set<TransactionID> Transactions; /**<Piblic transaction IDs are saved in the std::set*/
TransactionID beginReadOnlyTransaction(const std::string& storageName) const;
TransactionID beginTransaction(const std::string& storageName) const;
@ -95,14 +95,14 @@ private:
void abortPrivateTransaction(TransactionID id, const std::string& storageName) const;
private:
std::string name;
bool opened;
uint16_t size;
MDB_env* environment;
Storages storages;
Transactions* transactions;
std::string name; /**<\brief Name of this database*/
bool opened; /**<\brief State of this database*/
uint16_t size; /**<\brief lmdb map size in MiB*/
MDB_env* environment; /**<\brief lmdb environment handle*/
Storages storages; /**<\brief Registered storages and caches*/
Transactions* transactions; /**<\brief Active public transactions*/
inline static const std::string emptyName = "";
inline static const std::string emptyName = ""; /**<\brief Empty string for general fallback purposes*/
};
}

View File

@ -30,13 +30,13 @@ namespace LMDBAL {
template <class K, class V>
class Cache : public Storage<K, V> {
friend class Base;
enum class Mode { //it's a cache state when we:
nothing, // - know nothing about records in database on disk
size, // - know just an amount of records
full // - shure that our cache is equal to the database on disk
enum class Mode { /**<it's a cache state when we:*/
nothing, /**< - know nothing about records in database on disk*/
size, /**< - know just an amount of records*/
full /**< - shure that our cache is equal to the database on disk*/
};
enum class Operation {
enum class Operation { /**<Operation type, used in pcrocessing cache modification after writable transaction is commited*/
add,
remove,
change,
@ -101,11 +101,20 @@ public:
virtual SizeType addRecords(const std::map<K, V>& data, TransactionID txn, bool overwrite = false) override;
protected:
/**
* \brief Cache mode
*
* Sometimes we have a complete information about the content of the database,
* and we don't even need to refer to lmdb to fetch or check for data.
* This member actually shows what is the current state, more about them you can read in Enum descriptions
*
* It's done with pointer to comply some of the const method limitations which would modify this state eventually
*/
Mode* mode;
std::map<K, V>* cache;
std::set<K>* abscent;
SizeType* sizeDifference;
TransactionCache* transactionCache;
std::map<K, V>* cache; /**<\brief Cached data*/
std::set<K>* abscent; /**<\brief Set of keys that are definitely not in the cache*/
SizeType* sizeDifference; /**<\brief Difference of size between cached data and amount of records in the lmdb storage*/
TransactionCache* transactionCache; /**<\brief All changes made under under uncommited transactions*/
};
}

View File

@ -22,9 +22,29 @@
#include "cache.h"
#include "exceptions.h"
/**
* \class LMDBAL::Cache
* \brief Storage with additional caching in std::map
*
* \tparam K type of the keys of the cache
* \tparam V type of the values of the cache
*
* You can receive an instance of this class calling LMDBAL::Base::addCache(const std::string&)
* if the database is yet closed and you're defining the storages you're going to need.
* Or you can call LMDBAL::Base::getCache(const std::string&) if you didn't save a pointer to the cache at first
*
* You are not supposed to instantiate or destory instances of this class yourself!
*/
/**
* \brief Creates a cache
*
* \param[in] _name - name of the new cache
* \param[in] parent - parent database pointed (borrowed)
*/
template<class K, class V>
LMDBAL::Cache<K, V>::Cache(const std::string& p_name, Base* parent):
Storage<K, V>(p_name, parent),
LMDBAL::Cache<K, V>::Cache(const std::string& _name, Base* parent):
Storage<K, V>(_name, parent),
mode(new Mode),
cache(new std::map<K, V>()),
abscent(new std::set<K>()),
@ -35,6 +55,9 @@ LMDBAL::Cache<K, V>::Cache(const std::string& p_name, Base* parent):
*sizeDifference = 0;
}
/**
* \brief Destroys a cache
*/
template<class K, class V>
LMDBAL::Cache<K, V>::~Cache() {
delete transactionCache;

View File

@ -64,22 +64,22 @@ public:
virtual SizeType count(TransactionID txn) const;
protected:
MDB_dbi dbi;
Base* db;
const std::string name;
MDB_dbi dbi; /**<\brief lmdb storage handle*/
Base* db; /**<\brief parent database pointer (borrowed)*/
const std::string name; /**<\brief this storage name*/
inline static const std::string dropMethodName = "drop";
inline static const std::string countMethodName = "count";
inline static const std::string dropMethodName = "drop"; /**<\brief member function name, just for exceptions*/
inline static const std::string countMethodName = "count"; /**<\brief member function name, just for exceptions*/
inline static const std::string addRecordMethodName = "addRecord";
inline static const std::string forceRecordMethodName = "forceRecord";
inline static const std::string changeRecordMethodName = "changeRecord";
inline static const std::string removeRecordMethodName = "removeRecord";
inline static const std::string checkRecordMethodName = "checkRecord";
inline static const std::string getRecordMethodName = "getRecord";
inline static const std::string readAllMethodName = "readAllRecord";
inline static const std::string replaceAllMethodName = "replaceAll";
inline static const std::string addRecordsMethodName = "addRecords";
inline static const std::string addRecordMethodName = "addRecord"; /**<\brief member function name, just for exceptions*/
inline static const std::string forceRecordMethodName = "forceRecord"; /**<\brief member function name, just for exceptions*/
inline static const std::string changeRecordMethodName = "changeRecord"; /**<\brief member function name, just for exceptions*/
inline static const std::string removeRecordMethodName = "removeRecord"; /**<\brief member function name, just for exceptions*/
inline static const std::string checkRecordMethodName = "checkRecord"; /**<\brief member function name, just for exceptions*/
inline static const std::string getRecordMethodName = "getRecord"; /**<\brief member function name, just for exceptions*/
inline static const std::string readAllMethodName = "readAllRecord"; /**<\brief member function name, just for exceptions*/
inline static const std::string replaceAllMethodName = "replaceAll"; /**<\brief member function name, just for exceptions*/
inline static const std::string addRecordsMethodName = "addRecords"; /**<\brief member function name, just for exceptions*/
protected:
template <class T>
@ -122,8 +122,8 @@ public:
virtual uint32_t addRecords(const std::map<K, V>& data, TransactionID txn, bool overwrite = false);
protected:
Serializer<K>* keySerializer;
Serializer<V>* valueSerializer;
Serializer<K>* keySerializer; /**<\brief internal object that would serialize and deserialize keys*/
Serializer<V>* valueSerializer; /**<\brief internal object that would serialize and deserialize values*/
int createStorage(MDB_txn* transaction) override;
};

View File

@ -31,18 +31,27 @@
*
* You can receive an instance of this class calling LMDBAL::Base::addStorage(const std::string&)
* if the database is yet closed and you're defining the storages you're going to need.
* Or you can call LMDBAL::Base::getStorage(const std::string&) if the database is opened and you didn't save a pointer to the storage
* Or you can call LMDBAL::Base::getStorage(const std::string&) if you didn't save a pointer to the storage at first
*
* You are not supposed to instantiate or destory instances of this class yourself!
*/
/**
* \brief Creates a storage
*
* \param[in] _name - name of the new storage
* \param[in] parent - parent database pointed (borrowed)
*/
template<class K, class V>
LMDBAL::Storage<K, V>::Storage(const std::string& p_name, Base* parent):
iStorage(p_name, parent),
LMDBAL::Storage<K, V>::Storage(const std::string& _name, Base* parent):
iStorage(_name, parent),
keySerializer(new Serializer<K>()),
valueSerializer(new Serializer<V>())
{}
/**
* \brief Destroys a storage
*/
template<class K, class V>
LMDBAL::Storage<K, V>::~Storage() {
delete valueSerializer;
@ -673,57 +682,92 @@ void LMDBAL::Storage<K, V>::removeRecord(const K& key, TransactionID txn) {
}
/**
* \brief A private virtual function I need to open database
* \brief A private virtual function I need to open each storage in the database
*
* This and the following collection of specializations are a way to optimise database using
* MDB_INTEGERKEY flag, when the key is actually kind of an integer
* This infrastructure also allowes us to customize mdb_dbi_open call in the future
* \param[in] transaction - lmdb transaction to call <a class="el" href="http://www.lmdb.tech/doc/group__mdb.html#gac08cad5b096925642ca359a6d6f0562a">mdb_dbi_open</a>
* \returns MDB_SUCCESS if everything went smooth or MDB_<error> -like error code
*/
template<class K, class V>
int LMDBAL::Storage<K, V>::createStorage(MDB_txn* transaction) {
return makeStorage<K>(transaction);
}
/**
* \brief A functiion to actually open <a class="el" href="http://www.lmdb.tech/doc/group__mdb.html#gadbe68a06c448dfb62da16443d251a78b">MDB_dbi</a> storage
*
* \tparam K type of keys in opening storage
*
* \param[in] transaction - lmdb transaction to call <a class="el" href="http://www.lmdb.tech/doc/group__mdb.html#gac08cad5b096925642ca359a6d6f0562a">mdb_dbi_open</a>, must be a writable transaction!
* \returns MDB_SUCCESS if everything went smooth or MDB_<error> -like error code
*
* This and the following collection of specializations are a way to optimise database using
* MDB_INTEGERKEY flag, when the key is actually kind of an integer
* This infrastructure also allowes us to customize mdb_dbi_open call in the future
*/
template<class K>
inline int LMDBAL::iStorage::makeStorage(MDB_txn* transaction) {
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE, &dbi);
}
/**
* \brief Opening database function specialization for uint64_t
*/
template<>
inline int LMDBAL::iStorage::makeStorage<uint64_t>(MDB_txn* transaction) {
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
}
/**
* \brief Opening database function specialization for uint32_t
*/
template<>
inline int LMDBAL::iStorage::makeStorage<uint32_t>(MDB_txn* transaction) {
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
}
/**
* \brief Opening database function specialization for uint16_t
*/
template<>
inline int LMDBAL::iStorage::makeStorage<uint16_t>(MDB_txn* transaction) {
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
}
/**
* \brief Opening database function specialization for uint8_t
*/
template<>
inline int LMDBAL::iStorage::makeStorage<uint8_t>(MDB_txn* transaction) {
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
}
/**
* \brief Opening database function specialization for int64_t
*/
template<>
inline int LMDBAL::iStorage::makeStorage<int64_t>(MDB_txn* transaction) {
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
}
/**
* \brief Opening database function specialization for int32_t
*/
template<>
inline int LMDBAL::iStorage::makeStorage<int32_t>(MDB_txn* transaction) {
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
}
/**
* \brief Opening database function specialization for int16_t
*/
template<>
inline int LMDBAL::iStorage::makeStorage<int16_t>(MDB_txn* transaction) {
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
}
/**
* \brief Opening database function specialization for int8_t
*/
template<>
inline int LMDBAL::iStorage::makeStorage<int8_t>(MDB_txn* transaction) {
return mdb_dbi_open(transaction, name.c_str(), MDB_CREATE | MDB_INTEGERKEY, &dbi);
@ -743,11 +787,27 @@ inline std::string LMDBAL::iStorage::toString(const T& value) {
return std::to_string(value);
}
/**
* \brief A method to cast a value (which can be a value or a key) to string.
*
* QString spectialization
*
* \param[in] value a value that should be converted to string
* \returns a string presentation of value
*/
template<>
inline std::string LMDBAL::iStorage::toString(const QString& value) {
return value.toStdString();
}
/**
* \brief A method to cast a value (which can be a value or a key) to string.
*
* std::string spectialization
*
* \param[in] value a value that should be converted to string
* \returns a string presentation of value
*/
template<>
inline std::string LMDBAL::iStorage::toString(const std::string& value) {
return value;