Keep track of transaction epoch

This commit is contained in:
Piotr Wójcik 2024-08-22 17:08:18 +02:00
commit e1695d49f1
5 changed files with 42 additions and 4 deletions

View file

@ -1,5 +1,8 @@
#pragma once
#include <nano/lib/utility.hpp>
#include <nano/store/transaction.hpp>
#include <utility>
namespace nano::store
@ -8,7 +11,16 @@ template <typename T, typename U>
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<T, U> & operator++ () = 0;
virtual iterator_impl<T, U> & operator-- () = 0;
virtual bool operator== (iterator_impl<T, U> 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
}

View file

@ -14,7 +14,8 @@ template <typename T, typename U>
class iterator : public iterator_impl<T, U>
{
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<T, U> (transaction_a)
{
auto status (mdb_cursor_open (env_a.tx (transaction_a), db_a, &cursor));
release_assert (status == 0);

View file

@ -33,7 +33,8 @@ class iterator : public iterator_impl<T, U>
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<T, U> (transaction_a)
{
// Don't fill the block cache for any blocks read as a result of an iterator
if (is_read (transaction_a))

View file

@ -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 ();
}

View file

@ -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 };
};
/**