diff --git a/src/cursorcommon.cpp b/src/cursorcommon.cpp index bfa77f0..b8f1564 100644 --- a/src/cursorcommon.cpp +++ b/src/cursorcommon.cpp @@ -71,7 +71,7 @@ LMDBAL::CursorCommon::CursorCommon (CursorCommon&& other): other.dropped(); if (state == openedPublic) - storage->attachCursorToTransaction(id, handle, this); + attachToTransaction(); } /** @@ -99,7 +99,7 @@ LMDBAL::CursorCommon& LMDBAL::CursorCommon::operator = (CursorCommon&& other) { other.reset(); if (state == openedPublic) - storage->attachCursorToTransaction(id, handle, this); + attachToTransaction(); return *this; } @@ -161,7 +161,7 @@ void LMDBAL::CursorCommon::terminated () { void LMDBAL::CursorCommon::close () { switch (state) { case openedPublic: - storage->disconnectCursorFromTransaction(id, handle); + disconnectFromTransaction(); storage->_mdbCursorClose(handle); state = closed; @@ -231,7 +231,7 @@ void LMDBAL::CursorCommon::open (const Transaction& transaction) { if (result != MDB_SUCCESS) storage->throwUnknown(result); - storage->attachCursorToTransaction(id, handle, this); + transaction.cursors[id] = this; state = openedPublic; } break; default: @@ -267,7 +267,7 @@ void LMDBAL::CursorCommon::renew () { storage->openCursorTransaction(&handle, true); break; case openedPublic: - storage->disconnectCursorFromTransaction(id, handle); + disconnectFromTransaction(); storage->openCursorTransaction(&handle, true); state = openedPrivate; break; @@ -309,16 +309,16 @@ void LMDBAL::CursorCommon::renew (const Transaction& transaction) { if (result != MDB_SUCCESS) storage->throwUnknown(result); - storage->attachCursorToTransaction(id, handle, this); + transaction.cursors[id] = this; state = openedPublic; } break; case openedPublic: { - storage->disconnectCursorFromTransaction(id, handle); + disconnectFromTransaction(); int result = storage->_mdbCursorRenew(txn, handle); if (result != MDB_SUCCESS) storage->throwUnknown(result); - storage->attachCursorToTransaction(id, handle, this); + transaction.cursors[id] = this; } break; default: break; @@ -340,3 +340,27 @@ bool LMDBAL::CursorCommon::empty () const { bool LMDBAL::CursorCommon::opened () const { return state != closed; } + +/** + * \brief Links cursor to the transaction it has been opened with + * + * Cursor must be opened by a public transaction + * + * \exception std::out_of_range thrown if LMDBAL::Transaction pointer wasn't found in the LMDBAL::Base + */ +void LMDBAL::CursorCommon::attachToTransaction () { + Transaction* txn = storage->getTransactionForCursor(handle); + txn->cursors[id] = this; +} + +/** + * \brief Disconnects cursor from the transaction it has been opened with + * + * Cursor must be still opened by a public transaction + * + * \exception std::out_of_range thrown if LMDBAL::Transaction pointer wasn't found in the LMDBAL::Base + */ +void LMDBAL::CursorCommon::disconnectFromTransaction () { + Transaction* txn = storage->getTransactionForCursor(handle); + txn->cursors.erase(id); +} diff --git a/src/cursorcommon.h b/src/cursorcommon.h index fee4e8b..bf9b312 100644 --- a/src/cursorcommon.h +++ b/src/cursorcommon.h @@ -61,6 +61,10 @@ protected: void dropped(); void reset(); +private: + void attachToTransaction(); + void disconnectFromTransaction(); + protected: uint32_t id; State state; diff --git a/src/storagecommon.cpp b/src/storagecommon.cpp index 298f48d..3d7e92c 100644 --- a/src/storagecommon.cpp +++ b/src/storagecommon.cpp @@ -162,21 +162,19 @@ LMDBAL::SizeType LMDBAL::StorageCommon::count() const { } /** - * \brief Links cursor to the transaction it has been opened with + * \brief Retrieves public transaction object for a cursor handle * - * This a service function is designed to be called by from LMDBAL::Cursor - * Cursor must be opened by a public transaction + * Cursor must be still opened by a public transaction + * + * \param[out] cursor - cursor handle * * \exception std::out_of_range thrown if LMDBAL::Transaction pointer wasn't found in the LMDBAL::Base */ - -void LMDBAL::StorageCommon::attachCursorToTransaction (uint32_t cursorId, MDB_cursor* cursorHandle, CursorCommon* pointer) const { - TransactionID txnID = _mdbCursorTxn(cursorHandle); - Transaction* txn = db->transactions.at(txnID); - txn->cursors[cursorId] = pointer; +LMDBAL::Transaction* LMDBAL::StorageCommon::getTransactionForCursor (MDB_cursor* cursor) const { + TransactionID txnID = _mdbCursorTxn(cursor); + return db->transactions.at(txnID); } - /** * \brief Opens a transaction that is ment to be private to LMDBAL::Cursor, but public to the LMDBAL::Storage * @@ -221,22 +219,6 @@ void LMDBAL::StorageCommon::closeCursorTransaction (MDB_cursor* cursor, bool clo transactionAborted(txn); } -/** - * \brief Disconnects cursor from the transaction it has been opened with - * - * This a service function is designed to be called by from LMDBAL::Cursor - * Cursor must be still opened by a public transaction - * - * \exception std::out_of_range thrown if LMDBAL::Transaction pointer wasn't found in the LMDBAL::Base - */ - -void LMDBAL::StorageCommon::disconnectCursorFromTransaction (uint32_t cursorId, MDB_cursor* cursorHandle) const { - TransactionID txnID = _mdbCursorTxn(cursorHandle); - Transaction* txn = db->transactions.at(txnID); - txn->cursors.erase(cursorId); -} - - /** * \brief Storage size (private transaction variant) * @@ -553,7 +535,6 @@ int LMDBAL::StorageCommon::_mdbFlags(MDB_txn* txn, uint32_t& flags) const { return mdb_dbi_flags(txn, dbi, &flags); } - int LMDBAL::StorageCommon::_mdbCursorOpen(MDB_txn* txn, MDB_cursor** cursor) const { return mdb_cursor_open(txn, dbi, cursor); } diff --git a/src/storagecommon.h b/src/storagecommon.h index 367ef62..77a56d2 100644 --- a/src/storagecommon.h +++ b/src/storagecommon.h @@ -74,10 +74,10 @@ protected: virtual int drop(TransactionID transaction); virtual SizeType count(TransactionID txn) const; + Transaction* getTransactionForCursor(MDB_cursor* cursor) const; + void openCursorTransaction(MDB_cursor** cursor, bool renew = false) const; void closeCursorTransaction(MDB_cursor* cursor, bool closeCursor = false) const; - void attachCursorToTransaction(uint32_t cursorId, MDB_cursor* cursorHandle, CursorCommon* pointer) const; - void disconnectCursorFromTransaction(uint32_t cursorId, MDB_cursor* cursorHandle) const; int _mdbOpen(MDB_txn* txn, unsigned int flags = 0); diff --git a/src/transaction.h b/src/transaction.h index 0fb28e3..4866f17 100644 --- a/src/transaction.h +++ b/src/transaction.h @@ -27,6 +27,7 @@ class CursorCommon; class Transaction { friend class Base; friend class StorageCommon; + friend class CursorCommon; public: explicit Transaction(); explicit Transaction(Transaction&& other); @@ -44,10 +45,10 @@ protected: void closeCursors(); protected: - TransactionID txn; /**<\brief Transaction inner handler*/ - bool active; /**<\brief Transaction state*/ - const Base* parent; /**<\brief Pointer to the database this transaction belongs to*/ - std::map cursors; /**<\brief a collection of cursors curently opened under this transaction*/ + TransactionID txn; /**<\brief Transaction inner handler*/ + bool active; /**<\brief Transaction state*/ + const Base* parent; /**<\brief Pointer to the database this transaction belongs to*/ + mutable std::map cursors; /**<\brief a collection of cursors curently opened under this transaction*/ }; class WriteTransaction : public Transaction {