diff --git a/api/resources/node.hpp b/api/resources/node.hpp index c4db74ca1..f36d34d13 100644 --- a/api/resources/node.hpp +++ b/api/resources/node.hpp @@ -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 @@ -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( 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(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(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"); + // }); } }; diff --git a/api/response_json.hpp b/api/response_json.hpp index 26b676d4a..8a0a26231 100644 --- a/api/response_json.hpp +++ b/api/response_json.hpp @@ -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; using ptr_RJStringWriter = std::shared_ptr; -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(); diff --git a/mvcc/record.hpp b/mvcc/record.hpp index 7896a95f5..5395b21c9 100644 --- a/mvcc/record.hpp +++ b/mvcc/record.hpp @@ -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 diff --git a/mvcc/version_list.hpp b/mvcc/version_list.hpp index b6f44dd0d..a66a18151 100644 --- a/mvcc/version_list.hpp +++ b/mvcc/version_list.hpp @@ -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 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; +using EdgeRecord = mvcc::VersionList; diff --git a/storage/edge_proxy.hpp b/storage/edge_proxy.hpp deleted file mode 100644 index e7ac14254..000000000 --- a/storage/edge_proxy.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "record_proxy.hpp" -#include "edges.hpp" - -class EdgeProxy : public RecordProxy -{ - // TODO: implementation -}; diff --git a/storage/model/label_list.hpp b/storage/model/label_list.hpp index a9d123d8c..0f0d9fea7 100644 --- a/storage/model/label_list.hpp +++ b/storage/model/label_list.hpp @@ -24,8 +24,7 @@ public: return labels.count(label); } - size_t count() const - { + size_t count() const { return labels.size(); } diff --git a/storage/model/vertex_model.hpp b/storage/model/vertex_model.hpp index b04f32184..b19c48388 100644 --- a/storage/model/vertex_model.hpp +++ b/storage/model/vertex_model.hpp @@ -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; }; diff --git a/storage/record_accessor.hpp b/storage/record_accessor.hpp index 567fc5669..e70259970 100644 --- a/storage/record_accessor.hpp +++ b/storage/record_accessor.hpp @@ -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 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 void property(const std::string& key, Args&&... args) { - record->props.template set(key, std::forward(args)...); + record->data.props.template set(key, std::forward(args)...); + } + + Properties& properties() const + { + return record->data.props; } protected: diff --git a/storage/record_proxy.hpp b/storage/record_proxy.hpp deleted file mode 100644 index 8af317264..000000000 --- a/storage/record_proxy.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -#include "transactions/transaction.hpp" -#include "mvcc/version_list.hpp" -#include "storage/model/properties/property.hpp" - -template -class RecordProxy -{ -public: - RecordProxy( - const Id& id, - T* version, - Store *store, - mvcc::VersionList *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 - Property* property(const K& key) const - { - return version->data.props.find(key); - } - - template - void property(const K& key, const V& value) - { - version->data.props.template set(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 *version_list; -}; diff --git a/storage/vertex.hpp b/storage/vertex.hpp index 812b79060..4d534cd78 100644 --- a/storage/vertex.hpp +++ b/storage/vertex.hpp @@ -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 { diff --git a/storage/vertex_accessor.hpp b/storage/vertex_accessor.hpp index b02c4baaa..8c11bac4c 100644 --- a/storage/vertex_accessor.hpp +++ b/storage/vertex_accessor.hpp @@ -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 +class Vertices; + +class Vertex::Accessor : public RecordAccessor { public: using RecordAccessor::RecordAccessor; diff --git a/storage/vertex_proxy.hpp b/storage/vertex_proxy.hpp deleted file mode 100644 index bf7831ed4..000000000 --- a/storage/vertex_proxy.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "record_proxy.hpp" - -class Vertices; - -class VertexProxy : public RecordProxy -{ - using RecordProxy::RecordProxy; -}; diff --git a/storage/vertices.hpp b/storage/vertices.hpp index 3df3bfc45..b87d8fead 100644 --- a/storage/vertices.hpp +++ b/storage/vertices.hpp @@ -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> vertices; + SkipList vertices; AtomicCounter counter; }; diff --git a/transactions/lock_store.hpp b/transactions/lock_store.hpp index 5b3334487..6afe19752 100644 --- a/transactions/lock_store.hpp +++ b/transactions/lock_store.hpp @@ -3,7 +3,7 @@ #include #include #include -#include "database/locking/lock_status.hpp" +#include "storage/locking/lock_status.hpp" namespace tx { diff --git a/transactions/transaction.hpp b/transactions/transaction.hpp index f68a1fe37..a8e44f44c 100644 --- a/transactions/transaction.hpp +++ b/transactions/transaction.hpp @@ -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 {