started to work on duplicates support

This commit is contained in:
Blue 2023-08-15 15:48:19 -03:00
parent 7b26d57ab6
commit f0727aa73d
Signed by: blue
GPG key ID: 9B203B252A63EE38
9 changed files with 132 additions and 108 deletions

View file

@ -41,12 +41,13 @@
/**
* \brief Creates a storage
*
* \param[in] _name - name of the new storage
* \param[in] parent - parent database pointed (borrowed)
* \param[in] parent - LMDBAL::Base pointer for the owning database (borrowed)
* \param[in] name - the name of the storage
* \param[in] duplicates - true if storage supports duplicates, false otherwise (false by default)
*/
template<class K, class V>
LMDBAL::Storage<K, V>::Storage(const std::string& _name, Base* parent):
iStorage(_name, parent),
LMDBAL::Storage<K, V>::Storage(Base* parent, const std::string& name, bool duplicates):
iStorage(parent, name, duplicates),
keySerializer(),
valueSerializer(),
cursors()
@ -692,7 +693,7 @@ void LMDBAL::Storage<K, V>::removeRecord(const K& key, TransactionID txn) {
*/
template<class K, class V>
int LMDBAL::Storage<K, V>::open(MDB_txn* transaction) {
return makeStorage<K>(transaction);
return makeStorage<K, V>(transaction, duplicates);
}
/**
@ -719,6 +720,30 @@ LMDBAL::Cursor<K, V>* LMDBAL::Storage<K, V>::createCursor() {
return cursor;
}
/**
* \brief Reads current storage flags it was opened with
*
* This function exists mostly for testing purposes
*
* \returns Third out parameter of <a href="http://www.lmdb.tech/doc/group__internal.html#ga95ba4cb721035478a8705e57b91ae4d4">mdb_dbi_flags</a> function
*
* \exception LMDBAL::Closed thrown if the database was not opened
* \exception LMDBAL::Unknown if the result of <a href="http://www.lmdb.tech/doc/group__internal.html#ga95ba4cb721035478a8705e57b91ae4d4">mdb_dbi_flags</a> was not successfull
*/
template<class K, class V>
uint32_t LMDBAL::Storage<K, V>::flags() const {
ensureOpened(flagsMethodName);
uint32_t result;
TransactionID txn = beginReadOnlyTransaction();
int res = mdb_dbi_flags(txn, dbi, &result);
abortTransaction(txn);
if (res != MDB_SUCCESS)
throwUnknown(res);
return result;
}
/**
* \brief Destroys cursor
*
@ -726,7 +751,7 @@ LMDBAL::Cursor<K, V>* LMDBAL::Storage<K, V>::createCursor() {
*
* \param[in] cursor a pointer to a cursor you want to destroy
*
* \throws LMDBAL::Unknown thrown if you try to destroy something that this storage didn't create
* \exception LMDBAL::Unknown thrown if you try to destroy something that this storage didn't create
*/
template<class K, class V>
void LMDBAL::Storage<K, V>::destroyCursor(Cursor<K, V>* cursor) {
@ -770,79 +795,28 @@ void LMDBAL::Storage<K, V>::discoveredRecord(const K& key, const V& value, Trans
* \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!
* \param[in] duplicates - true if you wish to enable duplicates support for the storage
*
* \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 is 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);
}
template<class K, class V>
inline int LMDBAL::iStorage::makeStorage(MDB_txn* transaction, bool duplicates) {
unsigned int flags = MDB_CREATE;
if constexpr (std::is_integral<K>::value)
flags |= MDB_INTEGERKEY;
/**
* \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);
}
if (duplicates) {
flags |= MDB_DUPSORT;
/**
* \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);
}
if constexpr (std::is_integral<V>::value)
flags |= MDB_INTEGERDUP | MDB_DUPFIXED;
}
/**
* \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);
return mdb_dbi_open(transaction, name.c_str(), flags, &dbi);
}
/**