From e1695d49f1fd01f7dd6636d7d63e871c86b581cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:08:18 +0200 Subject: [PATCH] Keep track of transaction epoch --- nano/store/iterator_impl.hpp | 20 ++++++++++++++++++-- nano/store/lmdb/iterator.hpp | 3 ++- nano/store/rocksdb/iterator.hpp | 3 ++- nano/store/transaction.cpp | 13 +++++++++++++ nano/store/transaction.hpp | 7 +++++++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/nano/store/iterator_impl.hpp b/nano/store/iterator_impl.hpp index 0f873e97..48130d14 100644 --- a/nano/store/iterator_impl.hpp +++ b/nano/store/iterator_impl.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include namespace nano::store @@ -8,7 +11,16 @@ template class iterator_impl { public: - virtual ~iterator_impl () = default; + explicit iterator_impl (nano::store::transaction const & transaction_a) : + transaction{ transaction_a }, + transaction_epoch{ transaction_a.epoch () } + { + } + virtual ~iterator_impl () + { + debug_assert (transaction_epoch == transaction.epoch (), "invalid iterator-transaction lifetime detected"); + } + virtual iterator_impl & operator++ () = 0; virtual iterator_impl & operator-- () = 0; virtual bool operator== (iterator_impl const & other_a) const = 0; @@ -23,5 +35,9 @@ public: { return !(*this == other_a); } + +protected: + nano::store::transaction const & transaction; + nano::store::transaction::epoch_t const transaction_epoch; }; -} // namespace nano::store +} diff --git a/nano/store/lmdb/iterator.hpp b/nano/store/lmdb/iterator.hpp index ff7cb097..3c2fe197 100644 --- a/nano/store/lmdb/iterator.hpp +++ b/nano/store/lmdb/iterator.hpp @@ -14,7 +14,8 @@ template class iterator : public iterator_impl { public: - iterator (store::transaction const & transaction_a, env const & env_a, MDB_dbi db_a, MDB_val const & val_a = MDB_val{}, bool const direction_asc = true) + iterator (store::transaction const & transaction_a, env const & env_a, MDB_dbi db_a, MDB_val const & val_a = MDB_val{}, bool const direction_asc = true) : + nano::store::iterator_impl (transaction_a) { auto status (mdb_cursor_open (env_a.tx (transaction_a), db_a, &cursor)); release_assert (status == 0); diff --git a/nano/store/rocksdb/iterator.hpp b/nano/store/rocksdb/iterator.hpp index ec4865e5..b661c8af 100644 --- a/nano/store/rocksdb/iterator.hpp +++ b/nano/store/rocksdb/iterator.hpp @@ -33,7 +33,8 @@ class iterator : public iterator_impl public: iterator () = default; - iterator (::rocksdb::DB * db, store::transaction const & transaction_a, ::rocksdb::ColumnFamilyHandle * handle_a, db_val const * val_a, bool const direction_asc) + iterator (::rocksdb::DB * db, store::transaction const & transaction_a, ::rocksdb::ColumnFamilyHandle * handle_a, db_val const * val_a, bool const direction_asc) : + nano::store::iterator_impl (transaction_a) { // Don't fill the block cache for any blocks read as a result of an iterator if (is_read (transaction_a)) diff --git a/nano/store/transaction.cpp b/nano/store/transaction.cpp index cba69217..2609c231 100644 --- a/nano/store/transaction.cpp +++ b/nano/store/transaction.cpp @@ -29,6 +29,15 @@ nano::store::write_transaction_impl::write_transaction_impl (nano::id_dispenser: { } +/* + * transaction + */ + +auto nano::store::transaction::epoch () const -> epoch_t +{ + return current_epoch; +} + /* * read_transaction */ @@ -51,11 +60,13 @@ nano::id_dispenser::id_t nano::store::read_transaction::store_id () const void nano::store::read_transaction::reset () { + ++current_epoch; impl->reset (); } void nano::store::read_transaction::renew () { + ++current_epoch; impl->renew (); start = std::chrono::steady_clock::now (); } @@ -102,11 +113,13 @@ nano::id_dispenser::id_t nano::store::write_transaction::store_id () const void nano::store::write_transaction::commit () { + ++current_epoch; impl->commit (); } void nano::store::write_transaction::renew () { + ++current_epoch; impl->renew (); start = std::chrono::steady_clock::now (); } diff --git a/nano/store/transaction.hpp b/nano/store/transaction.hpp index e0b4b9eb..79e96cdc 100644 --- a/nano/store/transaction.hpp +++ b/nano/store/transaction.hpp @@ -36,10 +36,17 @@ public: class transaction { +public: + using epoch_t = size_t; + public: virtual ~transaction () = default; virtual void * get_handle () const = 0; virtual nano::id_dispenser::id_t store_id () const = 0; + epoch_t epoch () const; + +protected: + epoch_t current_epoch{ 0 }; }; /**