diff --git a/database/db.hpp b/database/db.hpp index 230bcd9d8..77210b6da 100644 --- a/database/db.hpp +++ b/database/db.hpp @@ -11,4 +11,10 @@ public: Graph graph; tx::Engine tx_engine; + + // only for test purposes + std::string identifier() + { + return "memgraph"; + } }; diff --git a/dc/dynamic_lib.hpp b/dc/dynamic_lib.hpp index b33c432a7..c5baa3180 100644 --- a/dc/dynamic_lib.hpp +++ b/dc/dynamic_lib.hpp @@ -16,6 +16,15 @@ public: { } + // TODO debug why this doesn't work + typename T::lib_object* instance() + { + // TODO singleton, lazy, concurrency + this->load(); + lib_object = this->produce_method(); + return lib_object; + } + void load() { load_lib(); @@ -23,9 +32,17 @@ public: load_destruct_func(); } + ~DynamicLib() + { + if (lib_object != nullptr) { + destruct_method(lib_object); + } + } + private: std::string lib_path; void *dynamic_lib; + typename T::lib_object* lib_object; void load_lib() { diff --git a/query_engine/code_executor.hpp b/query_engine/code_executor.hpp new file mode 100644 index 000000000..abcc5dbec --- /dev/null +++ b/query_engine/code_executor.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include <string> + +#include "i_code_cpu.hpp" +#include "database/db.hpp" + +class CodeExecutor +{ +public: + + void execute(ICodeCPU *code_cpu) + { + code_cpu->name(); + code_cpu->run(db); + } + +private: + Db db; +}; diff --git a/query_engine/code_loader.hpp b/query_engine/code_loader.hpp new file mode 100644 index 000000000..3efb6c0a8 --- /dev/null +++ b/query_engine/code_loader.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include <string> +#include <unordered_map> +#include <memory> + +#include "memgraph_dynamic_lib.hpp" +#include "query_stripper.hpp" +#include "code_compiler.hpp" +#include "code_generator.hpp" +#include "utils/hashing/fnv.hpp" + +using std::string; +using std::cout; +using std::endl; + +class CodeLoader +{ +public: + + using sptr_code_lib = std::shared_ptr<CodeLib>; + + CodeLoader() + : stripper(make_query_stripper(TK_INT, TK_FLOAT, TK_STR)) + { + } + + ICodeCPU* load_code_cpu(const string& query) + { + // TODO implement me + // for now returns already compiled code + + auto stripped = stripper.strip(query); + // TODO move to logger + cout << "Stripped query is: " << stripped << endl; + auto stripped_hash = fnv(stripped); + // TODO move to logger + cout << "Query hash is: " << stripped_hash << endl; + + auto code_lib = load_code_lib("./compiled/cpu/create_return.so"); + code_libs.insert({{stripped_hash, code_lib}}); + + return code_lib->instance(); + } + +private: + // TODO somehow remove int.. from here + QueryStripper<int, int, int> stripper; + // TODO ifdef MEMGRAPH64 problem, how to use this kind + // of ifdef functions? + // uint64_t depends on fnv function + std::unordered_map<uint64_t, sptr_code_lib> code_libs; + + CodeGenerator code_generator; + CodeCompiler code_compiler; + + sptr_code_lib load_code_lib(const string& path) + { + sptr_code_lib code_lib = std::make_shared<CodeLib>(path); + code_lib->load(); + return code_lib; + } +}; diff --git a/query_engine/compile.sh b/query_engine/compile.sh index 4a0d99391..7d67363ff 100755 --- a/query_engine/compile.sh +++ b/query_engine/compile.sh @@ -1,4 +1,7 @@ #!/bin/bash # TODO: create Makefile or cmake script -clang++ -std=c++1y -g -I../ main.cpp ../cypher/cypher.cpp -o engine +cd compiled/cpu +clang++ -std=c++1y create_return.cpp -o create_return.so -I../../../ -shared -fPIC +cd ../.. +clang++ -std=c++1y -g -I../ main.cpp ../cypher/cypher.cpp -o engine -ldl diff --git a/query_engine/compiled/cpu/create_return.cpp b/query_engine/compiled/cpu/create_return.cpp new file mode 100644 index 000000000..968c23063 --- /dev/null +++ b/query_engine/compiled/cpu/create_return.cpp @@ -0,0 +1,33 @@ +#include <iostream> + +#include "query_engine/i_code_cpu.hpp" + +using std::cout; +using std::endl; + +class CreateReturn : public ICodeCPU +{ +public: + + void name() const override + { + cout << "CRETE RETURN QUERY" << endl; + } + + void run(Db& db) const override + { + cout << db.identifier() << endl; + } + + ~CreateReturn() {} +}; + +extern "C" ICodeCPU* produce() +{ + return new CreateReturn(); +} + +extern "C" void destruct(ICodeCPU* p) +{ + delete p; +} diff --git a/query_engine/engine b/query_engine/engine index 45665ba9a..ccb486170 100755 Binary files a/query_engine/engine and b/query_engine/engine differ diff --git a/query_engine/i_code_cpu.hpp b/query_engine/i_code_cpu.hpp new file mode 100644 index 000000000..ef25dbc42 --- /dev/null +++ b/query_engine/i_code_cpu.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "database/db.hpp" + +class ICodeCPU +{ +public: + virtual void name() const = 0; + virtual void run(Db& db) const = 0; + virtual ~ICodeCPU() {} +}; + +typedef ICodeCPU* (*produce_t)(); +typedef void (*destruct_t)(ICodeCPU*); diff --git a/query_engine/memgraph_dynamic_lib.hpp b/query_engine/memgraph_dynamic_lib.hpp new file mode 100644 index 000000000..7dbc07ed2 --- /dev/null +++ b/query_engine/memgraph_dynamic_lib.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "i_code_cpu.hpp" +#include "dc/dynamic_lib.hpp" + +class MemgraphDynamicLib +{ +public: + const static std::string produce_name; + const static std::string destruct_name; + using produce = produce_t; + using destruct = destruct_t; + using lib_object = ICodeCPU; +}; +const std::string MemgraphDynamicLib::produce_name = "produce"; +const std::string MemgraphDynamicLib::destruct_name = "destruct"; + +using CodeLib = DynamicLib<MemgraphDynamicLib>; diff --git a/query_engine/query_engine.hpp b/query_engine/query_engine.hpp index 673422b33..086ac8702 100644 --- a/query_engine/query_engine.hpp +++ b/query_engine/query_engine.hpp @@ -1,49 +1,30 @@ #pragma once -#include <iostream> - -#include "query_stripper.hpp" -#include "query_traverser.hpp" -#include "code_generator.hpp" -#include "code_compiler.hpp" -#include "query_executor.hpp" +#include "code_loader.hpp" +#include "code_executor.hpp" #include "query_result.hpp" -#include "utils/hashing/fnv.hpp" - -using std::cout; -using std::endl; // // Current arhitecture: -// query -> traverser -> [generator] -> [compiler] -> executor +// query -> code_loader -> query_stripper -> [code_generator] +// -> [code_compiler] -> code_executor // class QueryEngine { public: QueryEngine() - : stripper(make_query_stripper(TK_INT, TK_FLOAT, TK_STR)) { } - QueryResult execute(const std::string& query) + QueryResult* execute(const std::string& query) { - cout << "QUERY ENGINE EXECUTE" << endl; - auto stripped = stripper.strip(query); - cout << "STRIPPED: " << stripped << endl; - auto stripped_hash = fnv(stripped); - cout << "STRIPPED HASH: " << stripped_hash << endl; + executor.execute(loader.load_code_cpu(query)); - // traverser.build_tree(query); - // traverser.traverse(); - return QueryResult(); + throw std::runtime_error("implement me"); } private: - // TODO: use IoC or something similar - QueryStripper<int, int, int> stripper; - QueryTraverser traverser; - CodeGenerator generator; - CodeCompiler compiler; - QueryExecutor executor; + CodeLoader loader; + CodeExecutor executor; }; diff --git a/query_engine/query_executor.hpp b/query_engine/query_executor.hpp deleted file mode 100644 index 5aefbd39b..000000000 --- a/query_engine/query_executor.hpp +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -class QueryExecutor -{ -}; diff --git a/query_engine/traverser/code_compiler.hpp b/query_engine/traverser/code_compiler.hpp new file mode 100644 index 000000000..e69de29bb