started adding support for transactions

This commit is contained in:
Dominik Tomičević 2015-07-04 11:51:33 +02:00
parent 518c2d19e9
commit 37fba19cc6
4 changed files with 172 additions and 0 deletions

View File

@ -0,0 +1,53 @@
#include <thread>
#include <vector>
#include <unistd.h>
#include "catch.hpp"
#include "transaction/transactionengine.hpp"
#include "sync/spinlock.hpp"
TEST_CASE("(try to) test correctness of the transaction life cycle")
{
constexpr int THREADS = 16;
constexpr int TRANSACTIONS = 10;
TransactionEngine<uint64_t, SpinLock> engine(0);
std::vector<uint64_t> sums;
sums.resize(THREADS);
auto f = [&engine, &sums](int idx, int n)
{
uint64_t sum = 0;
for(int i = 0; i < n; ++i)
{
auto t = engine.begin();
sum += t.id;
engine.commit(t);
}
sums[idx] = sum;
};
std::vector<std::thread> threads;
for(int i = 0; i < THREADS; ++i)
threads.push_back(std::thread(f, i, TRANSACTIONS));
for(auto& thread : threads)
thread.join();
uint64_t sum_computed = 0;
for(int i = 0; i < THREADS; ++i)
sum_computed += sums[i];
uint64_t sum_actual = 0;
for(uint64_t i = 0; i <= THREADS * TRANSACTIONS; ++i)
sum_actual += i;
REQUIRE(sum_computed == sum_actual);
}

View File

@ -0,0 +1,26 @@
#ifndef MEMGRAPH_TRANSACTION_TRANSACTION_HPP
#define MEMGRAPH_TRANSACTION_TRANSACTION_HPP
#include <cstdlib>
#include <vector>
template <class id_t>
struct Transaction
{
Transaction(id_t id, std::vector<id_t> active)
: id(id), active(std::move(active)) {}
// index of this transaction
id_t id;
// the ids of the currently active transactions used by the mvcc
// implementation for snapshot isolation
std::vector<id_t> active;
bool operator<(const Transaction<id_t>& rhs)
{
return id < rhs.id;
}
};
#endif

View File

@ -0,0 +1,5 @@
#ifndef MEMGRAPH_TRANSACTION_TRANSACTION_LOG_HPP
#define MEMGRAPH_TRANSACTION_TRANSACTION_LOG_HPP
#endif

View File

@ -0,0 +1,88 @@
#ifndef MEMGRAPH_TRANSACTION_TRANSACTIONENGINE_HPP
#define MEMGRAPH_TRANSACTION_TRANSACTIONENGINE_HPP
#include <cstdlib>
#include <atomic>
#include <mutex>
#include <vector>
#include <set>
#include <list>
#include "transaction.hpp"
template <class id_t, class lock_t>
class TransactionEngine
{
using trans_t = Transaction<id_t>;
public:
TransactionEngine(id_t n) : counter(n) {}
Transaction<id_t> begin()
{
auto guard = acquire();
auto id = ++counter;
auto t = Transaction<id_t>(id, active);
active.push_back(id);
return t;
}
void commit(const Transaction<id_t>& t)
{
auto guard = acquire();
finalize_transaction(t);
}
void rollback(const Transaction<id_t>& t)
{
auto guard = acquire();
// what to do here?
finalize_transaction(t);
}
// id of the last finished transaction
id_t epochs_passed()
{
auto guard = acquire();
return active.front() - 1;
}
// total number of transactions started from the beginning of time
id_t count()
{
auto guard = acquire();
return counter;
}
// the number of currently active transactions
size_t size()
{
auto guard = acquire();
return active.size();
}
private:
void finalize_transaction(const Transaction<id_t>& t)
{
// remove transaction from the active transactions list
auto last = std::remove(active.begin(), active.end(), t.id);
active.erase(last, active.end());
}
std::unique_lock<lock_t> acquire()
{
return std::unique_lock<lock_t>(lock);
}
id_t counter;
lock_t lock;
std::vector<id_t> active;
};
#endif