started adding support for transactions
This commit is contained in:
parent
518c2d19e9
commit
37fba19cc6
53
test/transactionengine.cpp
Normal file
53
test/transactionengine.cpp
Normal 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);
|
||||
}
|
26
transaction/transaction.hpp
Normal file
26
transaction/transaction.hpp
Normal 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
|
5
transaction/transaction_log.hpp
Normal file
5
transaction/transaction_log.hpp
Normal file
@ -0,0 +1,5 @@
|
||||
#ifndef MEMGRAPH_TRANSACTION_TRANSACTION_LOG_HPP
|
||||
#define MEMGRAPH_TRANSACTION_TRANSACTION_LOG_HPP
|
||||
|
||||
|
||||
#endif
|
88
transaction/transactionengine.hpp
Normal file
88
transaction/transactionengine.hpp
Normal 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
|
Loading…
Reference in New Issue
Block a user