reconstructed rest api, but still this is broken version, TODO: discuss where is place for the id (versions accessor, versions or in vertex accessor

This commit is contained in:
Marko Budiselic 2016-01-02 22:20:09 +01:00
parent b93bab375e
commit e89da5f875
15 changed files with 135 additions and 192 deletions

View File

@ -6,6 +6,7 @@
#include "mvcc/version_list.hpp"
#include "api/response_json.hpp"
#include "api/restful/resource.hpp"
#include "storage/model/properties/property.hpp"
#pragma url /node
class Nodes : public Resource<Nodes, POST>
@ -20,13 +21,13 @@ public:
auto& transaction = db->tx_engine.begin();
// insert a new vertex
auto vertex_proxy = db->graph.vertices.insert(transaction);
auto vertex_accessor = db->graph.vertices.insert(transaction);
auto begin_it = req.json.MemberBegin();
auto end_it = req.json.MemberEnd();
for(auto it = begin_it; it != end_it; ++it)
{
vertex_proxy.property(
vertex_accessor.template property<String>(
it->name.GetString(), it->value.GetString()
);
}
@ -34,12 +35,12 @@ public:
// commit the transaction
transaction.commit();
return std::move(vertex_proxy);
return std::move(vertex_accessor);
},
[&req, &res](VertexProxy&& vertex_proxy) {
[&req, &res](Vertex::Accessor&& vertex_accessor) {
return res.send(
http::Status::Created,
vertex_create_response(vertex_proxy)
vertex_create_response(vertex_accessor)
);
});
}
@ -61,76 +62,78 @@ public:
Id id(std::stoull(req.params[0]));
// find node
auto vertex = db->graph.vertices.find(transaction, id);
auto vertex_accessor = db->graph.vertices.find(transaction, id);
// commit the transaction
transaction.commit();
return vertex;
return std::move(vertex_accessor);
},
[&req, &res](const Vertex* vertex) {
if (vertex == nullptr) {
[&req, &res](Vertex::Accessor&& vertex_accessor) {
if (vertex_accessor.empty()) {
return res.send(http::Status::NotFound, "The node was not found");
}
return res.send(vertex_props_to_string(vertex));
return res.send(
vertex_create_response(vertex_accessor)
);
});
}
void put(sp::Request& req, sp::Response& res)
{
task->run([this, &req]() -> Vertex* {
// create transaction
auto& transaction = db->tx_engine.begin();
// task->run([this, &req]() -> Vertex* {
// // create transaction
// auto& transaction = db->tx_engine.begin();
// read id param
Id id(std::stoull(req.params[0]));
// // read id param
// Id id(std::stoull(req.params[0]));
// find node
auto vertex = db->graph.vertices.update(transaction, id);
// // find node
// auto vertex = db->graph.vertices.update(transaction, id);
if (vertex == nullptr)
return nullptr;
// if (vertex == nullptr)
// return nullptr;
// map fields
for(auto it = req.json.MemberBegin(); it != req.json.MemberEnd(); ++it)
{
vertex->data.props.set<String>(it->name.GetString(), it->value.GetString());
}
// commit the transaction
transaction.commit();
// // map fields
// for(auto it = req.json.MemberBegin(); it != req.json.MemberEnd(); ++it)
// {
// vertex->data.props.set<String>(it->name.GetString(), it->value.GetString());
// }
//
// // commit the transaction
// transaction.commit();
return vertex;
},
[&req, &res](Vertex* vertex) {
if (vertex == nullptr) {
return res.send(http::Status::NotFound, "The node was not found");
}
return res.send(vertex_props_to_string(vertex));
});
// return vertex;
// },
// [&req, &res](Vertex* vertex) {
// if (vertex == nullptr) {
// return res.send(http::Status::NotFound, "The node was not found");
// }
// return res.send(vertex_props_to_string(vertex));
// });
}
void del(sp::Request& req, sp::Response& res)
{
task->run([this, &req]() -> bool {
// create transaction
auto& transaction = db->tx_engine.begin();
// task->run([this, &req]() -> bool {
// // create transaction
// auto& transaction = db->tx_engine.begin();
// read id param
Id id(std::stoull(req.params[0]));
// // read id param
// Id id(std::stoull(req.params[0]));
auto is_deleted = db->graph.vertices.remove(transaction, id);
// auto is_deleted = db->graph.vertices.remove(transaction, id);
// commit the transaction
transaction.commit();
// // commit the transaction
// transaction.commit();
return is_deleted;
},
[&req, &res](bool is_deleted) {
if (is_deleted)
return res.send(http::Status::Ok, "The node was deleted");
// return is_deleted;
// },
// [&req, &res](bool is_deleted) {
// if (is_deleted)
// return res.send(http::Status::Ok, "The node was deleted");
return res.send(http::Status::NotFound, "The node was not found");
});
// return res.send(http::Status::NotFound, "The node was not found");
// });
}
};

View File

@ -1,7 +1,7 @@
#pragma once
#include "storage/vertex.hpp"
#include "storage/vertex_proxy.hpp"
#include "storage/vertex_accessor.hpp"
#include "storage/writer/rapidjson_stringwriter.hpp"
StringBuffer vertex_props_to_buffer(const Vertex* vertex)
@ -29,7 +29,7 @@ using RJStringBuffer = rapidjson::StringBuffer;
using RJStringWriter = rapidjson::Writer<RJStringBuffer>;
using ptr_RJStringWriter = std::shared_ptr<RJStringWriter>;
std::string vertex_create_response(const VertexProxy& vertex_proxy)
std::string vertex_create_response(const Vertex::Accessor& vertex_accessor)
{
// make a string buffer
RJStringBuffer buffer;
@ -40,14 +40,14 @@ std::string vertex_create_response(const VertexProxy& vertex_proxy)
writer->StartObject();
writer->String("id");
writer->Int64(vertex_proxy.record_id());
writer->Int64(vertex_accessor.id());
writer->EndObject();
writer->String("data");
writer->StartObject();
RapidJsonStringWriter dataBuffer(writer);
auto vertex = vertex_proxy.record_version();
vertex->data.props.accept(dataBuffer);
auto properties = vertex_accessor.properties();
properties.accept(dataBuffer);
writer->EndObject();
writer->EndObject();

View File

@ -8,7 +8,7 @@
#include "cre_exp.hpp"
#include "version.hpp"
#include "hints.hpp"
#include "database/locking/record_lock.hpp"
#include "storage/locking/record_lock.hpp"
// the mvcc implementation used here is very much like postgresql's
// more info: https://momjian.us/main/writings/pgsql/mvcc.pdf

View File

@ -45,7 +45,7 @@ public:
return vlist.insert(transaction);
}
const T* find() const
T* find() const
{
return vlist.find(transaction);
}
@ -72,7 +72,7 @@ public:
const Id& id() const
{
return vlist.id;
return vlist.identifier;
}
private:
@ -129,11 +129,21 @@ public:
}
const Id& id() const
{
return identifier;
}
void id(const Id& identifier)
{
this->identifier = identifier;
}
private:
std::atomic<T*> head {nullptr};
RecordLock lock;
Id id;
Id identifier;
//static Recycler recycler;
@ -157,10 +167,11 @@ private:
return r;
}
T* insert(tx::Transaction& t, const Id& id)
T* insert(tx::Transaction& t)
{
assert(head == nullptr);
this->id = id;
// this->id = id;
// create a first version of the record
// TODO replace 'new' with something better
@ -242,3 +253,9 @@ private:
};
}
class Vertex;
class Edge;
using VertexRecord = mvcc::VersionList<Vertex>;
using EdgeRecord = mvcc::VersionList<Edge>;

View File

@ -1,9 +0,0 @@
#pragma once
#include "record_proxy.hpp"
#include "edges.hpp"
class EdgeProxy : public RecordProxy<Edge, Edges, EdgeProxy>
{
// TODO: implementation
};

View File

@ -24,8 +24,7 @@ public:
return labels.count(label);
}
size_t count() const
{
size_t count() const {
return labels.size();
}

View File

@ -1,12 +1,12 @@
#pragma once
#include "property_model.hpp"
#include "label_list.hpp"
// #include "label_list.hpp"
#include "edge_list.hpp"
class VertexModel : public PropertyModel
{
public:
EdgeList in, out;
LabelList labels;
// LabelList labels;
};

View File

@ -3,6 +3,7 @@
#include "transactions/transaction.hpp"
#include "mvcc/version_list.hpp"
#include "storage/model/properties/property.hpp"
#include "storage/model/properties/properties.hpp"
template <class T, class Store, class Derived>
class RecordAccessor
@ -18,8 +19,7 @@ public:
const Id& id() const
{
auto accessor = vlist->access();
return accessor.id();
return vlist->id();
}
bool empty() const
@ -31,7 +31,7 @@ public:
{
assert(!empty());
auto accessor = vlist->access();
auto accessor = vlist->access(t);
return Derived(accessor->update(t), vlist, store);
}
@ -39,19 +39,24 @@ public:
{
assert(!empty());
auto accessor = vlist->access();
auto accessor = vlist->access(t);
return accessor->remove(t);
}
const Property* property(const std::string& key) const
{
return record->props.at(key);
return record->data.props.at(key);
}
template <class V, class... Args>
void property(const std::string& key, Args&&... args)
{
record->props.template set<V>(key, std::forward<Args>(args)...);
record->data.props.template set<V>(key, std::forward<Args>(args)...);
}
Properties& properties() const
{
return record->data.props;
}
protected:

View File

@ -1,79 +0,0 @@
#pragma once
#include "transactions/transaction.hpp"
#include "mvcc/version_list.hpp"
#include "storage/model/properties/property.hpp"
template <typename T, typename Store, typename Derived>
class RecordProxy
{
public:
RecordProxy(
const Id& id,
T* version,
Store *store,
mvcc::VersionList<T> *version_list) :
id(id), version(version), store(store), version_list(version_list)
{
}
RecordProxy(const RecordProxy& record_proxy) = delete;
RecordProxy(RecordProxy&& other) :
id(other.id), version(other.version), store(other.store),
version_list(other.version_list)
{
other.id = 0; // TODO: not very good idea because
// replace with something else
other.version = nullptr;
other.store = nullptr;
other.version_list = nullptr;
}
~RecordProxy()
{
// TODO: implementation
}
Derived update(tx::Transaction& transaction) const
{
// TODO: implementation
transaction.commit();
return nullptr;
}
void remove(tx::Transaction& transaction) const
{
// TODO: implementation
transaction.commit();
}
template<typename K>
Property* property(const K& key) const
{
return version->data.props.find(key);
}
template<typename K, typename V>
void property(const K& key, const V& value)
{
version->data.props.template set<String>(key, value);
// TODO: update the index
}
Id record_id() const
{
return id;
}
T* record_version() const
{
return version;
}
private:
Id id;
T* version;
Store *store;
mvcc::VersionList<T> *version_list;
};

View File

@ -1,8 +1,8 @@
#pragma once
#include "model/properties/jsonwriter.hpp"
#include "model/vertex_model.hpp"
#include "mvcc/record.hpp"
#include "model/vertex_model.hpp"
#include "model/properties/jsonwriter.hpp"
class Vertex : public mvcc::Record<Vertex>
{

View File

@ -1,10 +1,11 @@
#pragma once
#include "record_accessor.hpp"
#include "vertex.hpp"
#include "vertices.hpp"
#include "storage/vertex.hpp"
#include "storage/record_accessor.hpp"
class Vertex::Accessor : public RecordAccessor<Vertex, Vertices, Accessor>
class Vertices;
class Vertex::Accessor : public RecordAccessor<Vertex, Vertices, Vertex::Accessor>
{
public:
using RecordAccessor::RecordAccessor;

View File

@ -1,10 +0,0 @@
#pragma once
#include "record_proxy.hpp"
class Vertices;
class VertexProxy : public RecordProxy<Vertex, Vertices, VertexProxy>
{
using RecordProxy::RecordProxy;
};

View File

@ -1,34 +1,50 @@
#pragma once
#include "vertex.hpp"
#include "common.hpp"
#include "vertex_proxy.hpp"
#include "storage/vertex_accessor.hpp"
class Vertices
{
public:
const Vertex* find(tx::Transaction& transaction, const Id& id)
Vertex::Accessor find(tx::Transaction& t, const Id& id)
{
// find vertex record
auto vertices_accessor = vertices.access();
auto vertex_record = vertices_accessor.find(id);
auto vertices_iterator = vertices_accessor.find(id);
if (vertex_record == vertices_accessor.end())
return nullptr;
if (vertices_iterator == vertices_accessor.end())
return Vertex::Accessor();
// find vertex
auto vertex_accessor = vertex_record->second.access(transaction);
auto vertex = vertex_accessor.find();
auto versions_accessor = vertices_iterator->second.access(t);
auto vertex = versions_accessor.find();
return Vertex::Accessor(vertex, &vertices_iterator->second, this);
}
// TODO: here is problem to create vertex_proxy because vertex
// is const pointer
return vertex;
Vertex::Accessor insert(tx::Transaction& t)
{
// get next vertex id
auto next = counter.next(std::memory_order_acquire);
// create new vertex record
VertexRecord vertex_record;
vertex_record.id(next);
// insert the new vertex record into the vertex store
auto vertices_accessor = vertices.access();
auto result = vertices_accessor.insert_unique(next, std::move(vertex_record));
// create new vertex
auto inserted_vertex_record = result.first;
auto vertex_accessor = inserted_vertex_record->second.access(t);
auto vertex = vertex_accessor.insert();
return Vertex::Accessor(vertex, &inserted_vertex_record->second, this);
}
private:
Indexes indexes;
// Indexes indexes;
SkipList<uint64_t, VersionList<Vertex>> vertices;
SkipList<uint64_t, VertexRecord> vertices;
AtomicCounter<uint64_t> counter;
};

View File

@ -3,7 +3,7 @@
#include <vector>
#include <cassert>
#include <memory>
#include "database/locking/lock_status.hpp"
#include "storage/locking/lock_status.hpp"
namespace tx
{

View File

@ -7,7 +7,7 @@
#include "mvcc/id.hpp"
#include "snapshot.hpp"
#include "lock_store.hpp"
#include "database/locking/record_lock.hpp"
#include "storage/locking/record_lock.hpp"
namespace tx
{