Merge branch 'master' of https://phabricator.tomicevic.com/diffusion/MG/memgraph
* 'master' of https://phabricator.tomicevic.com/diffusion/MG/memgraph: Initial code on crashes and exceptions logging. Related to T31. uint64_t was replaced with the Id object. Fixes T28. TotalOrdering and Id implementations, related to T28
This commit is contained in:
commit
039df559de
@ -69,7 +69,7 @@ public:
|
||||
{
|
||||
task->run([this, &req]() -> Vertex* {
|
||||
// read id param
|
||||
uint64_t id = std::stoull(req.params[0]);
|
||||
Id id(std::stoull(req.params[0]));
|
||||
// TODO: transaction?
|
||||
return db->graph.find_vertex(id);
|
||||
},
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef MEMGRAPH_CYPHER_LEXER_HPP
|
||||
#define MEMGRAPH_CYPHER_LEXER_HPP
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@ -59,5 +58,3 @@ protected:
|
||||
lexertl::rules rules;
|
||||
lexertl::state_machine sm;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
1
examples/.gitignore
vendored
Normal file
1
examples/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.out
|
41
examples/id.cpp
Normal file
41
examples/id.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "mvcc/id.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
int main() {
|
||||
|
||||
Id id0(0);
|
||||
Id id1(1);
|
||||
Id id2(1);
|
||||
Id id3(id2);
|
||||
Id id4 = id3;
|
||||
Id id5(5);
|
||||
|
||||
cout << id5 << " " << id0 << endl;
|
||||
|
||||
if (id0 < id5)
|
||||
cout << "id0 < id5" << endl;
|
||||
|
||||
if (id1 == id2)
|
||||
cout << "are equal" << endl;
|
||||
|
||||
if (id3 == id4)
|
||||
cout << "id3 == id4" << endl;
|
||||
|
||||
if (id5 > id0)
|
||||
cout << "id5 > id0" << endl;
|
||||
|
||||
if (id5 != id3)
|
||||
cout << "id5 != id3" << endl;
|
||||
|
||||
if (id1 >= id2)
|
||||
cout << "id1 >= id2" << endl;
|
||||
|
||||
if (id3 <= id4)
|
||||
cout << "id3 <= id4" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
33
memgraph.cpp
33
memgraph.cpp
@ -12,8 +12,41 @@
|
||||
#include "threading/pool.hpp"
|
||||
#include "threading/task.hpp"
|
||||
|
||||
#include <execinfo.h>
|
||||
|
||||
// TODO: move to separate header or source file
|
||||
// TODO: log to local file or remote database
|
||||
void stacktrace() noexcept
|
||||
{
|
||||
void *array[50];
|
||||
int size = backtrace(array, 50);
|
||||
std::cout << __FUNCTION__ << " backtrace returned " << size << " frames\n\n";
|
||||
char **messages = backtrace_symbols(array, size);
|
||||
for (int i = 0; i < size && messages != NULL; ++i) {
|
||||
std::cout << "[bt]: (" << i << ") " << messages[i] << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
free(messages);
|
||||
}
|
||||
|
||||
// TODO: log to local file or remote database
|
||||
void on_terminate() noexcept
|
||||
{
|
||||
if (auto exc = std::current_exception()) {
|
||||
try {
|
||||
std::rethrow_exception(exc);
|
||||
} catch (std::exception &ex) {
|
||||
std::cout << ex.what() << std::endl << std::endl;
|
||||
stacktrace();
|
||||
}
|
||||
}
|
||||
std::_Exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::set_terminate(&on_terminate);
|
||||
|
||||
ioc::Container container;
|
||||
|
||||
container.singleton<Db>();
|
||||
|
@ -1,8 +1,7 @@
|
||||
#ifndef MEMGRAPH_MVCC_ATOM_HPP
|
||||
#define MEMGRAPH_MVCC_ATOM_HPP
|
||||
#pragma once
|
||||
|
||||
#include "mvcc/id.hpp"
|
||||
#include "threading/sync/lockable.hpp"
|
||||
|
||||
#include "transactions/transaction.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
@ -14,7 +13,7 @@ class Atom : public Version<T>,
|
||||
public Lockable<SpinLock>
|
||||
{
|
||||
public:
|
||||
Atom(uint64_t id, T* first) : Version<T>(first), id(id)
|
||||
Atom(const Id& id, T* first) : Version<T>(first), id(id)
|
||||
{
|
||||
// it's illegal that the first version is nullptr. there should be at
|
||||
// least one version of a record
|
||||
@ -36,11 +35,9 @@ public:
|
||||
// every record has a unique id. 2^64 = 1.8 x 10^19. that should be enough
|
||||
// for a looong time :) but keep in mind that some vacuuming would be nice
|
||||
// to reuse indices for deleted nodes.
|
||||
uint64_t id;
|
||||
Id id;
|
||||
|
||||
std::atomic<Atom<T>*> next;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
36
mvcc/id.hpp
Normal file
36
mvcc/id.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
#include <stdint.h>
|
||||
#include "utils/total_ordering.hpp"
|
||||
|
||||
class Id : public TotalOrdering<Id>
|
||||
{
|
||||
public:
|
||||
Id() = default;
|
||||
|
||||
Id(uint64_t id) : id(id) {}
|
||||
|
||||
friend bool operator<(const Id& a, const Id& b)
|
||||
{
|
||||
return a.id < b.id;
|
||||
}
|
||||
|
||||
friend bool operator==(const Id& a, const Id& b)
|
||||
{
|
||||
return a.id == b.id;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, const Id& id)
|
||||
{
|
||||
return stream << id.id;
|
||||
}
|
||||
|
||||
operator uint64_t() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t id {0};
|
||||
};
|
@ -1,11 +1,10 @@
|
||||
#ifndef MEMGRAPH_STORAGE_MODEL_UTILS_MVCC_HPP
|
||||
#define MEMGRAPH_STORAGE_MODEL_UTILS_MVCC_HPP
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "transactions/transaction.hpp"
|
||||
#include "transactions/commit_log.hpp"
|
||||
|
||||
#include "mvcc/id.hpp"
|
||||
#include "minmax.hpp"
|
||||
#include "version.hpp"
|
||||
#include "hints.hpp"
|
||||
@ -26,7 +25,7 @@ public:
|
||||
// and tx.max is the id of the transaction that deleted the record
|
||||
// these values are used to determine the visibility of the record
|
||||
// to the current transaction
|
||||
MinMax<uint64_t> tx;
|
||||
MinMax<Id> tx;
|
||||
|
||||
// cmd.min is the id of the command in this transaction that created the
|
||||
// record and cmd.max is the id of the command in this transaction that
|
||||
@ -94,18 +93,18 @@ public:
|
||||
protected:
|
||||
Hints hints;
|
||||
|
||||
bool max_committed(uint64_t id, const tx::Transaction& t)
|
||||
bool max_committed(const Id& id, const tx::Transaction& t)
|
||||
{
|
||||
return committed(hints.max, id, t);
|
||||
}
|
||||
|
||||
bool min_committed(uint64_t id, const tx::Transaction& t)
|
||||
bool min_committed(const Id& id, const tx::Transaction& t)
|
||||
{
|
||||
return committed(hints.min, id, t);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
bool committed(U& hints, uint64_t id, const tx::Transaction& t)
|
||||
bool committed(U& hints, const Id& id, const tx::Transaction& t)
|
||||
{
|
||||
auto hint_bits = hints.load();
|
||||
|
||||
@ -135,5 +134,3 @@ protected:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef MEMGRAPH_STORAGE_GRAPH_HPP
|
||||
#define MEMGRAPH_STORAGE_GRAPH_HPP
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
|
||||
@ -39,7 +38,7 @@ public:
|
||||
}
|
||||
|
||||
// TODO: this should probably return mvcc::Atom<Vertex>*
|
||||
Vertex* find_vertex(uint64_t id)
|
||||
Vertex* find_vertex(const Id& id)
|
||||
{
|
||||
// get atom iterator
|
||||
auto atom_it = vertices.begin();
|
||||
@ -62,5 +61,3 @@ public:
|
||||
VertexStore vertices;
|
||||
EdgeStore edges;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef MEMGRAPH_STORAGE_VERTEX_HPP
|
||||
#define MEMGRAPH_STORAGE_VERTEX_HPP
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -42,4 +41,3 @@ inline std::string properties_to_string(Vertex* vertex)
|
||||
// respond to the use with the buffer
|
||||
return std::move(buffer.str());
|
||||
}
|
||||
#endif
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef MEMGRAPH_TRANSACTIONS_COMMIT_LOG_HPP
|
||||
#define MEMGRAPH_TRANSACTIONS_COMMIT_LOG_HPP
|
||||
|
||||
#include "mvcc/id.hpp"
|
||||
#include "data_structures/bitset/dynamic_bitset.hpp"
|
||||
|
||||
namespace tx
|
||||
@ -53,32 +54,32 @@ public:
|
||||
return log;
|
||||
}
|
||||
|
||||
Info fetch_info(uint64_t id)
|
||||
Info fetch_info(const Id& id)
|
||||
{
|
||||
return Info { log.at(2 * id, 2) };
|
||||
}
|
||||
|
||||
bool is_active(uint64_t id)
|
||||
bool is_active(const Id& id)
|
||||
{
|
||||
return fetch_info(id).is_active();
|
||||
}
|
||||
|
||||
bool is_committed(uint64_t id)
|
||||
bool is_committed(const Id& id)
|
||||
{
|
||||
return fetch_info(id).is_committed();
|
||||
}
|
||||
|
||||
void set_committed(uint64_t id)
|
||||
void set_committed(const Id& id)
|
||||
{
|
||||
log.set(2 * id);
|
||||
}
|
||||
|
||||
bool is_aborted(uint64_t id)
|
||||
bool is_aborted(const Id& id)
|
||||
{
|
||||
return fetch_info(id).is_aborted();
|
||||
}
|
||||
|
||||
void set_aborted(uint64_t id)
|
||||
void set_aborted(const Id& id)
|
||||
{
|
||||
log.set(2 * id + 1);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef MEMGRAPH_TRANSACTIONS_ENGINE_HPP
|
||||
#define MEMGRAPH_TRANSACTIONS_ENGINE_HPP
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
@ -33,16 +32,16 @@ public:
|
||||
{
|
||||
auto guard = this->acquire_unique();
|
||||
|
||||
auto id = counter.next();
|
||||
auto id = Id(counter.next());
|
||||
auto t = new Transaction(id, active);
|
||||
|
||||
active.push_back(id);
|
||||
active.insert(id);
|
||||
cache.put(id, t);
|
||||
|
||||
return *t;
|
||||
}
|
||||
|
||||
const Transaction& advance(uint64_t id)
|
||||
const Transaction& advance(const Id& id)
|
||||
{
|
||||
auto guard = this->acquire_unique();
|
||||
|
||||
@ -73,7 +72,7 @@ public:
|
||||
finalize(t);
|
||||
}
|
||||
|
||||
uint64_t last_known_active()
|
||||
Id last_known_active()
|
||||
{
|
||||
auto guard = this->acquire_unique();
|
||||
return active.front();
|
||||
@ -96,20 +95,15 @@ public:
|
||||
private:
|
||||
void finalize(const Transaction& t)
|
||||
{
|
||||
// remove transaction from the active transactions list
|
||||
auto last = std::remove(active.begin(), active.end(), t.id);
|
||||
active.erase(last, active.end());
|
||||
active.remove(t.id);
|
||||
|
||||
// remove transaction from cache
|
||||
cache.del(t.id);
|
||||
}
|
||||
|
||||
SimpleCounter<uint64_t> counter;
|
||||
|
||||
std::vector<uint64_t> active;
|
||||
Snapshot<Id> active;
|
||||
TransactionCache<uint64_t> cache;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef MEMGRAPH_TRANSACTIONS_SNAPSHOT_HPP
|
||||
#define MEMGRAPH_TRANSACTIONS_SNAPSHOT_HPP
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
@ -11,6 +10,8 @@ template <class id_t>
|
||||
class Snapshot
|
||||
{
|
||||
public:
|
||||
Snapshot() = default;
|
||||
|
||||
Snapshot(std::vector<id_t> active) : active(std::move(active)) {}
|
||||
|
||||
Snapshot(const Snapshot& other)
|
||||
@ -28,10 +29,30 @@ public:
|
||||
return std::binary_search(active.begin(), active.end(), xid);
|
||||
}
|
||||
|
||||
void insert(const id_t& id)
|
||||
{
|
||||
active.push_back(id);
|
||||
}
|
||||
|
||||
void remove(const id_t& id)
|
||||
{
|
||||
// remove transaction from the active transactions list
|
||||
auto last = std::remove(active.begin(), active.end(), id);
|
||||
active.erase(last, active.end());
|
||||
}
|
||||
|
||||
const id_t& front()
|
||||
{
|
||||
return active.front();
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return active.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<id_t> active;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,10 +1,10 @@
|
||||
#ifndef MEMGRAPH_MVCC_TRANSACTION_HPP
|
||||
#define MEMGRAPH_MVCC_TRANSACTION_HPP
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "mvcc/id.hpp"
|
||||
#include "snapshot.hpp"
|
||||
|
||||
namespace tx
|
||||
@ -12,19 +12,17 @@ namespace tx
|
||||
|
||||
struct Transaction
|
||||
{
|
||||
Transaction(uint64_t id, Snapshot<uint64_t> snapshot)
|
||||
Transaction(const Id& id, Snapshot<Id> snapshot)
|
||||
: id(id), cid(1), snapshot(std::move(snapshot)) {}
|
||||
|
||||
// index of this transaction
|
||||
uint64_t id;
|
||||
Id id;
|
||||
|
||||
// index of the current command in the current transaction;
|
||||
uint8_t cid;
|
||||
|
||||
// a snapshot of currently active transactions
|
||||
Snapshot<uint64_t> snapshot;
|
||||
Snapshot<Id> snapshot;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -8,9 +8,18 @@ struct TotalOrdering
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
friend bool operator>(const Derived& a, const Derived& b)
|
||||
friend bool operator<=(const Derived& a, const Derived& b)
|
||||
{
|
||||
return !(a == b);
|
||||
return a < b || a == b;
|
||||
}
|
||||
|
||||
friend bool operator>(const Derived& a, const Derived& b)
|
||||
{
|
||||
return !(a <= b);
|
||||
}
|
||||
|
||||
friend bool operator>=(const Derived& a, const Derived& b)
|
||||
{
|
||||
return !(a < b);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user