2015-10-12 02:59:27 +08:00
|
|
|
#ifndef MEMGRAPH_TRANSACTIONS_ENGINE_HPP
|
|
|
|
#define MEMGRAPH_TRANSACTIONS_ENGINE_HPP
|
2015-07-04 17:51:33 +08:00
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "transaction.hpp"
|
2015-10-04 15:47:15 +08:00
|
|
|
#include "transaction_cache.hpp"
|
2015-10-08 06:58:29 +08:00
|
|
|
#include "commit_log.hpp"
|
2015-10-04 15:47:15 +08:00
|
|
|
|
2015-07-31 18:36:41 +08:00
|
|
|
#include "utils/counters/simple_counter.hpp"
|
2015-07-04 17:51:33 +08:00
|
|
|
|
2015-09-13 17:34:17 +08:00
|
|
|
#include "threading/sync/spinlock.hpp"
|
|
|
|
#include "threading/sync/lockable.hpp"
|
2015-07-04 17:51:33 +08:00
|
|
|
|
2015-10-04 15:47:15 +08:00
|
|
|
namespace tx
|
|
|
|
{
|
|
|
|
|
|
|
|
class TransactionError : std::runtime_error
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using std::runtime_error::runtime_error;
|
|
|
|
};
|
|
|
|
|
2015-10-12 02:59:27 +08:00
|
|
|
class Engine : Lockable<SpinLock>
|
2015-07-31 18:36:41 +08:00
|
|
|
{
|
2015-07-04 17:51:33 +08:00
|
|
|
public:
|
2015-10-12 02:59:27 +08:00
|
|
|
using sptr = std::shared_ptr<Engine>;
|
|
|
|
|
|
|
|
Engine() : counter(0) {}
|
2015-07-04 17:51:33 +08:00
|
|
|
|
2015-10-04 15:47:15 +08:00
|
|
|
const Transaction& begin()
|
2015-07-04 17:51:33 +08:00
|
|
|
{
|
2015-10-08 06:58:29 +08:00
|
|
|
auto guard = this->acquire_unique();
|
2015-07-04 17:51:33 +08:00
|
|
|
|
2015-07-31 18:36:41 +08:00
|
|
|
auto id = counter.next();
|
2015-10-04 15:47:15 +08:00
|
|
|
auto t = new Transaction(id, active);
|
2015-07-04 17:51:33 +08:00
|
|
|
|
|
|
|
active.push_back(id);
|
2015-10-04 15:47:15 +08:00
|
|
|
cache.put(id, t);
|
|
|
|
|
|
|
|
return *t;
|
|
|
|
}
|
2015-07-04 17:51:33 +08:00
|
|
|
|
2015-10-04 15:47:15 +08:00
|
|
|
const Transaction& advance(uint64_t id)
|
|
|
|
{
|
2015-10-08 06:58:29 +08:00
|
|
|
auto guard = this->acquire_unique();
|
2015-10-04 15:47:15 +08:00
|
|
|
|
|
|
|
auto* t = cache.get(id);
|
|
|
|
|
|
|
|
if(t == nullptr)
|
|
|
|
throw TransactionError("transaction does not exist");
|
|
|
|
|
|
|
|
// this is a new command
|
|
|
|
t->cid++;
|
|
|
|
|
|
|
|
return *t;
|
2015-07-04 17:51:33 +08:00
|
|
|
}
|
|
|
|
|
2015-07-31 18:36:41 +08:00
|
|
|
void commit(const Transaction& t)
|
2015-07-04 17:51:33 +08:00
|
|
|
{
|
2015-10-08 06:58:29 +08:00
|
|
|
auto guard = this->acquire_unique();
|
|
|
|
CommitLog::get().set_committed(t.id);
|
2015-07-04 17:51:33 +08:00
|
|
|
|
2015-07-31 18:36:41 +08:00
|
|
|
finalize(t);
|
2015-07-04 17:51:33 +08:00
|
|
|
}
|
|
|
|
|
2015-10-08 06:58:29 +08:00
|
|
|
void abort(const Transaction& t)
|
2015-07-04 17:51:33 +08:00
|
|
|
{
|
2015-10-08 06:58:29 +08:00
|
|
|
auto guard = this->acquire_unique();
|
|
|
|
CommitLog::get().set_aborted(t.id);
|
2015-07-04 17:51:33 +08:00
|
|
|
|
2015-07-31 18:36:41 +08:00
|
|
|
finalize(t);
|
2015-07-04 17:51:33 +08:00
|
|
|
}
|
|
|
|
|
2015-07-31 18:36:41 +08:00
|
|
|
uint64_t last_known_active()
|
2015-07-04 17:51:33 +08:00
|
|
|
{
|
2015-10-08 06:58:29 +08:00
|
|
|
auto guard = this->acquire_unique();
|
2015-07-31 18:36:41 +08:00
|
|
|
return active.front();
|
2015-07-04 17:51:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// total number of transactions started from the beginning of time
|
2015-07-31 18:36:41 +08:00
|
|
|
uint64_t count()
|
2015-07-04 17:51:33 +08:00
|
|
|
{
|
2015-10-08 06:58:29 +08:00
|
|
|
auto guard = this->acquire_unique();
|
2015-07-31 18:36:41 +08:00
|
|
|
return counter.count();
|
2015-07-04 17:51:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// the number of currently active transactions
|
|
|
|
size_t size()
|
|
|
|
{
|
2015-10-08 06:58:29 +08:00
|
|
|
auto guard = this->acquire_unique();
|
2015-07-04 17:51:33 +08:00
|
|
|
return active.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2015-07-31 18:36:41 +08:00
|
|
|
void finalize(const Transaction& t)
|
2015-07-04 17:51:33 +08:00
|
|
|
{
|
|
|
|
// remove transaction from the active transactions list
|
2015-10-04 15:47:15 +08:00
|
|
|
auto last = std::remove(active.begin(), active.end(), t.id);
|
2015-07-04 17:51:33 +08:00
|
|
|
active.erase(last, active.end());
|
2015-10-04 15:47:15 +08:00
|
|
|
|
|
|
|
// remove transaction from cache
|
|
|
|
cache.del(t.id);
|
2015-07-04 17:51:33 +08:00
|
|
|
}
|
|
|
|
|
2015-07-31 18:36:41 +08:00
|
|
|
SimpleCounter<uint64_t> counter;
|
2015-07-04 17:51:33 +08:00
|
|
|
|
2015-07-31 18:36:41 +08:00
|
|
|
std::vector<uint64_t> active;
|
2015-10-04 15:47:15 +08:00
|
|
|
TransactionCache<uint64_t> cache;
|
2015-07-04 17:51:33 +08:00
|
|
|
};
|
|
|
|
|
2015-10-04 15:47:15 +08:00
|
|
|
}
|
|
|
|
|
2015-07-04 17:51:33 +08:00
|
|
|
#endif
|