From 763b3a143a899117cb2b628c3e5c39f2424f47e8 Mon Sep 17 00:00:00 2001 From: Marko Budiselic Date: Sat, 12 Mar 2016 20:16:19 +0100 Subject: [PATCH] demo hack --- query_engine/main.cpp | 18 ++--- query_engine/prepare/main.cpp | 118 ++++++++++++++++++++++++++++++++ query_engine/query_result.hpp | 14 +++- query_engine/query_stripper.hpp | 2 + storage/edge_accessor.hpp | 15 ++++ storage/edges.hpp | 35 +++++++++- storage/graph.hpp | 6 -- storage/model/edge_type.hpp | 1 + storage/record_accessor.hpp | 9 ++- storage/vertex_accessor.hpp | 15 ++++ storage/vertices.hpp | 3 + utils/string/transform.hpp | 20 ++++++ 12 files changed, 235 insertions(+), 21 deletions(-) create mode 100644 query_engine/prepare/main.cpp create mode 100644 utils/string/transform.hpp diff --git a/query_engine/main.cpp b/query_engine/main.cpp index 9d9866df2..1a4031dc8 100644 --- a/query_engine/main.cpp +++ b/query_engine/main.cpp @@ -35,16 +35,16 @@ int main(int argc, char** argv) // cout << 1000000 / (counter / 1000000000) << "create_transactions per sec" << endl; // shell - // std::string command; - // cout << "-- Memgraph query engine --" << endl; - // do { - // cout << "> "; - // std::getline(cin, command); - // engine.execute(command); - // } while (command != "quit"); + std::string command; + cout << "-- Memgraph query engine --" << endl; + do { + cout << "> "; + std::getline(cin, command); + engine.execute(command); + } while (command != "quit"); - engine.execute("CREATE (n{id:2}) RETURN n"); - engine.execute("MATCH (n{id:0}) RETURN n"); + // engine.execute("CREATE (n{id:2}) RETURN n"); + // engine.execute("MATCH (n{id:0}) RETURN n"); return 0; } diff --git a/query_engine/prepare/main.cpp b/query_engine/prepare/main.cpp new file mode 100644 index 000000000..9415ec0ef --- /dev/null +++ b/query_engine/prepare/main.cpp @@ -0,0 +1,118 @@ +#include "database/db.hpp" +#include "query_engine/query_stripper.hpp" +#include "utils/hashing/fnv.hpp" +#include "storage/model/properties/all.hpp" +#include "query_engine/query_result.hpp" +#define DEBUG +#include "query_engine/debug.hpp" + +using std::cout; +using std::endl; + +int main() +{ + Db db; + + std::vector queries = {{ + std::string("CREATE (n{id:3}) RETURN n"), + std::string("MATCH (n{id:3}) RETURN n"), + std::string("MATCH (n{id:3}) SET n.prop = \"\" RETURN n"), + std::string("MATCH (n{id:3}) DELETE n"), + std::string("MATCH (n{id:3}),(m{id:2}) CREATE (n)-[r:TEST]->(m) RETURN r"), + std::string("MATCH (n{id:3})-[r]->(m{id:2}) RETURN count(r)") + }}; + + auto stripper = make_query_stripper(TK_INT, TK_FLOAT, TK_STR, TK_BOOL); + + for(auto query : queries) { + auto strip = stripper.strip(query).query; + auto hash = std::to_string(fnv(strip)); + cout << "QUERY: " << query << + " STRIP: " << strip << + " HASH: " << hash << endl; + } + + auto create_node = [&db](uint64_t id) { + auto& t = db.tx_engine.begin(); + auto vertex_accessor = db.graph.vertices.insert(t); + vertex_accessor.property( + "id", Int64(id) + ); + t.commit(); + return vertex_accessor; + }; + + auto find_node = [&db](uint64_t id) { + auto& t = db.tx_engine.begin(); + auto vertex_accessor = db.graph.vertices.find(t, id); + t.commit(); + return vertex_accessor; + }; + + auto edit_node = [&db](uint64_t id, std::string prop) { + auto& t = db.tx_engine.begin(); + auto vertex_accessor = db.graph.vertices.find(t, id); + if (!vertex_accessor) { + t.commit(); + return vertex_accessor; + } + vertex_accessor.property( + "prop", String(prop) + ); + t.commit(); + return vertex_accessor; + }; + + auto delete_node = [&db](uint64_t id) { + auto& t = db.tx_engine.begin(); + auto vertex_accessor = db.graph.vertices.find(t, id); + if (!vertex_accessor) + return vertex_accessor; + vertex_accessor.remove(t); + t.commit(); + return vertex_accessor; + }; + + auto create_edge = [&db](uint64_t id1, uint64_t id2, std::string type) { + auto& t = db.tx_engine.begin(); + auto v1 = db.graph.vertices.find(t, id1); + if (!v1) + return Edge::Accessor(); + auto v2 = db.graph.vertices.find(t, id2); + if (!v2) + return Edge::Accessor(); + auto edge_accessor = db.graph.edges.insert(t); + v1.vlist->access(t).update()->data.out.add(edge_accessor.vlist); + v2.vlist->access(t).update()->data.in.add(edge_accessor.vlist); + edge_accessor.from(v1.vlist); + edge_accessor.to(v2.vlist); + edge_accessor.edge_type(EdgeType(type)); + t.commit(); + return edge_accessor; + }; + + auto count_edges = [&db](uint64_t id) { + auto& t = db.tx_engine.begin(); + auto v = db.graph.vertices.find(t, id); + t.commit(); + return v.out_degree(); + }; + + auto created_node1 = create_node(100); + PRINT_PROPS(created_node1.properties()); + auto created_node2 = create_node(200); + PRINT_PROPS(created_node2.properties()); + auto found_node = find_node(0); + PRINT_PROPS(found_node.properties()); + auto edited_node = edit_node(0, "test"); + PRINT_PROPS(edited_node.properties()); + // delete_node(0); + if (!find_node(0)) + cout << "node doesn't exist" << endl; + auto edge_accessor = create_edge(0, 1, "test"); + if (edge_accessor) + cout << edge_accessor.record->data.edge_type << endl; + cout << count_edges(0) << endl; + + return 0; +} diff --git a/query_engine/query_result.hpp b/query_engine/query_result.hpp index 8c61ef8dd..b6bafeb71 100644 --- a/query_engine/query_result.hpp +++ b/query_engine/query_result.hpp @@ -12,13 +12,18 @@ struct ResultList using sptr = std::shared_ptr; using data_t = std::vector; - ResultList() = delete; + ResultList() = default; ResultList(ResultList& other) = delete; ResultList(ResultList&& other) = default; ResultList(data_t&& data) : data(std::forward(data)) {} + explicit operator bool() const + { + return data.size() > 0; + } + std::vector data; }; @@ -27,12 +32,17 @@ struct QueryResult using sptr = std::shared_ptr; using data_t = std::unordered_map; - QueryResult() = delete; + QueryResult() = default; QueryResult(QueryResult& other) = delete; QueryResult(QueryResult&& other) = default; QueryResult(data_t&& data) : data(std::forward(data)) {} + explicit operator bool() const + { + return data.size() > 0; + } + data_t data; }; diff --git a/query_engine/query_stripper.hpp b/query_engine/query_stripper.hpp index e1900b974..fc72cc38b 100644 --- a/query_engine/query_stripper.hpp +++ b/query_engine/query_stripper.hpp @@ -5,6 +5,7 @@ #include #include +#include "utils/string/transform.hpp" #include "cypher/cypher.h" #include "cypher/tokenizer/cypher_lexer.hpp" #include "utils/variadic/variadic.hpp" @@ -77,6 +78,7 @@ public: } stripped_query += std::to_string(index); } else { + // TODO: lowercase only keywords like (MATCH, CREATE, ...) stripped_query += token.value; } } diff --git a/storage/edge_accessor.hpp b/storage/edge_accessor.hpp index f2018e08a..4bf9a235f 100644 --- a/storage/edge_accessor.hpp +++ b/storage/edge_accessor.hpp @@ -9,4 +9,19 @@ class Edge::Accessor : public RecordAccessor { public: using RecordAccessor::RecordAccessor; + + void edge_type(EdgeType type) + { + this->record->data.edge_type = type; + } + + void from(VertexRecord* vertex_record) + { + this->record->data.from = vertex_record; + } + + void to(VertexRecord* vertex_record) + { + this->record->data.to = vertex_record; + } }; diff --git a/storage/edges.hpp b/storage/edges.hpp index 19b7da4ca..e195d90dc 100644 --- a/storage/edges.hpp +++ b/storage/edges.hpp @@ -8,12 +8,43 @@ class Edges public: Edge::Accessor find(tx::Transaction& t, const Id& id) { - throw std::runtime_error("not implemented"); + auto edges_accessor = edges.access(); + auto edges_iterator = edges_accessor.find(id); + + if (edges_iterator == edges_accessor.end()) + return Edge::Accessor(); + + // find vertex + auto versions_accessor = edges_iterator->second.access(t); + auto edge = versions_accessor.find(); + + if (edge == nullptr) + return Edge::Accessor(); + + return Edge::Accessor(edge, &edges_iterator->second, this); } Edge::Accessor insert(tx::Transaction& t) { - throw std::runtime_error("not implemented"); + // get next vertex id + auto next = counter.next(std::memory_order_acquire); + + // create new vertex record + EdgeRecord edge_record(next); + + // insert the new vertex record into the vertex store + auto edges_accessor = edges.access(); + auto result = edges_accessor.insert_unique( + next, + std::move(edge_record) + ); + + // create new vertex + auto inserted_edge_record = result.first; + auto edge_accessor = inserted_edge_record->second.access(t); + auto edge = edge_accessor.insert(); + + return Edge::Accessor(edge, &inserted_edge_record->second, this); } private: diff --git a/storage/graph.hpp b/storage/graph.hpp index 20932f0d3..6197cff2d 100644 --- a/storage/graph.hpp +++ b/storage/graph.hpp @@ -9,12 +9,6 @@ class Graph public: Graph() {} - // TODO: connect method - // procedure: - // 1. acquire unique over first node - // 2. acquire unique over second node - // 3. add edge - Vertices vertices; Edges edges; }; diff --git a/storage/model/edge_type.hpp b/storage/model/edge_type.hpp index df7a511a8..f4f3acd6c 100644 --- a/storage/model/edge_type.hpp +++ b/storage/model/edge_type.hpp @@ -7,6 +7,7 @@ class EdgeType : public TotalOrdering { public: + EdgeType() {} EdgeType(const std::string& id) : id(id) {} EdgeType(std::string&& id) : id(std::move(id)) {} diff --git a/storage/record_accessor.hpp b/storage/record_accessor.hpp index b61bb8b34..656e699b4 100644 --- a/storage/record_accessor.hpp +++ b/storage/record_accessor.hpp @@ -49,7 +49,7 @@ public: return accessor.remove(record); } - const Property* property(const std::string& key) const + const Property& property(const std::string& key) const { return record->data.props.at(key); } @@ -70,7 +70,12 @@ public: return record->data.props; } -protected: + explicit operator bool() const + { + return record != nullptr; + } + +// protected: T* const record {nullptr}; vlist_t* const vlist {nullptr}; Store* const store {nullptr}; diff --git a/storage/vertex_accessor.hpp b/storage/vertex_accessor.hpp index 8c11bac4c..c365469de 100644 --- a/storage/vertex_accessor.hpp +++ b/storage/vertex_accessor.hpp @@ -9,4 +9,19 @@ class Vertex::Accessor : public RecordAccessorrecord->data.out.degree(); + } + + size_t in_degree() const + { + return this->record->data.in.degree(); + } + + size_t degree() + { + return in_degree() + out_degree(); + } }; diff --git a/storage/vertices.hpp b/storage/vertices.hpp index 555426aa4..c932fce33 100644 --- a/storage/vertices.hpp +++ b/storage/vertices.hpp @@ -18,6 +18,9 @@ public: auto versions_accessor = vertices_iterator->second.access(t); auto vertex = versions_accessor.find(); + if (vertex == nullptr) + return Vertex::Accessor(); + return Vertex::Accessor(vertex, &vertices_iterator->second, this); } diff --git a/utils/string/transform.hpp b/utils/string/transform.hpp new file mode 100644 index 000000000..22197d1bd --- /dev/null +++ b/utils/string/transform.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include + +namespace utils +{ + +void str_tolower(std::string& s) +{ + // en_US.utf8 localization + std::transform(s.begin(), s.end(), s.begin(), + [](unsigned char c) { + return std::tolower(c, std::locale("en_US.utf8")); + } + ); +} + +}