refactored transactions

This commit is contained in:
Dominik Tomičević 2015-07-31 12:36:41 +02:00
parent 2c9625e480
commit f31f4693ce
4 changed files with 47 additions and 52 deletions

View File

@ -10,7 +10,7 @@ public:
void lock()
{
// TODO add asm pause and counter first before sleeping
// TODO add asm_pause and counter first before sleeping
// might be faster, but test this and see
while(lock_flag.test_and_set(std::memory_order_acquire))
usleep(250);

View File

@ -2,16 +2,18 @@
#define MEMGRAPH_TRANSACTION_TRANSACTION_HPP
#include <cstdlib>
#include <cstdint>
#include <vector>
template <class id_t>
#include "transaction/commit_log.hpp"
struct Transaction
{
Transaction(id_t id, std::vector<id_t> active)
Transaction(uint64_t id, std::vector<uint64_t> active)
: id(id), cid(1), active(std::move(active)) {}
// index of this transaction
id_t id;
uint64_t id;
// index of the current command in the current transaction;
uint8_t cid;
@ -20,14 +22,22 @@ struct Transaction
// implementation for snapshot transaction isolation.
// std::vector is much faster than std::set for fewer number of items
// we don't expect the number of active transactions getting too large.
std::vector<id_t> active;
std::vector<uint64_t> active;
// check weather the transaction with the xid looks committed from the
// database snapshot given to this transaction
bool committed(id_t xid)
bool committed(uint64_t xid) const
{
// transaction xid is newer than id and therefore not visible at all
if (xid > id)
return false;
// transaction xid is not visible if it's currently active. the
// active transactions are sorted ascending and therefore we can stop
// looking as soon as we hit the active transaction with id greater
// than xid
for(size_t i = 0; i < active.size(); ++i)
if(xid < active[i])
if(xid <= active[i])
return false;
return true;

View File

@ -7,82 +7,80 @@
#include <vector>
#include <set>
#include <list>
#include <algorithm>
#include "transaction.hpp"
#include "utils/counters/simple_counter.hpp"
template <class id_t, class lock_t>
class TransactionEngine
#include "sync/spinlock.hpp"
#include "sync/lockable.hpp"
class TransactionEngine : Lockable<SpinLock>
{
using trans_t = Transaction<id_t>;
public:
TransactionEngine(id_t n) : counter(n) {}
TransactionEngine(uint64_t n) : counter(n) {}
Transaction<id_t> begin()
Transaction begin()
{
auto guard = acquire();
auto guard = this->acquire();
auto id = ++counter;
auto t = Transaction<id_t>(id, active);
auto id = counter.next();
auto t = Transaction(id, active);
active.push_back(id);
return t;
}
void commit(const Transaction<id_t>& t)
void commit(const Transaction& t)
{
auto guard = acquire();
auto guard = this->acquire();
finalize_transaction(t);
finalize(t);
}
void rollback(const Transaction<id_t>& t)
void rollback(const Transaction& t)
{
auto guard = acquire();
auto guard = this->acquire();
// what to do here?
finalize_transaction(t);
finalize(t);
}
// id of the last finished transaction
id_t epochs_passed()
uint64_t last_known_active()
{
auto guard = acquire();
return active.front() - 1;
auto guard = this->acquire();
return active.front();
}
// total number of transactions started from the beginning of time
id_t count()
uint64_t count()
{
auto guard = acquire();
return counter;
auto guard = this->acquire();
return counter.count();
}
// the number of currently active transactions
size_t size()
{
auto guard = acquire();
auto guard = this->acquire();
return active.size();
}
private:
void finalize_transaction(const Transaction<id_t>& t)
void finalize(const Transaction& t)
{
auto x = t.id;
// remove transaction from the active transactions list
auto last = std::remove(active.begin(), active.end(), t.id);
auto last = std::remove(active.begin(), active.end(), x);
active.erase(last, active.end());
}
std::unique_lock<lock_t> acquire()
{
return std::unique_lock<lock_t>(lock);
}
SimpleCounter<uint64_t> counter;
id_t counter;
lock_t lock;
std::vector<id_t> active;
std::vector<uint64_t> active;
};
#endif

View File

@ -1,13 +0,0 @@
#ifndef MEMGRAPH_TRANSACTION_TRANSACTION_LOG_HPP
#define MEMGRAPH_TRANSACTION_TRANSACTION_LOG_HPP
#include <cstdlib>
template <class id_t>
class TransactionLog
{
private:
}
#endif