diff --git a/.gitignore b/.gitignore index f3a791462..e6998ed40 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ tags .gdb_history Testing/ ve/ +ve3/ release/memgraph_* release/libs/ release/barrier/ diff --git a/CMakeLists.txt b/CMakeLists.txt index ae990505b..9e9d9de83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,9 @@ set(lexertl_dir ${libs_dir}/lexertl) # fmt set(fmt_source_dir ${libs_dir}/fmt) set(fmt_static_lib ${fmt_source_dir}/fmt/libfmt.a) +# yaml-cpp +set(yaml_source_dir ${libs_dir}/yaml-cpp) +set(yaml_static_lib ${yaml_source_dir}/libyaml-cpp.a) # r3 set(r3_source_dir ${libs_dir}/r3) set(r3_static_lib ${r3_source_dir}/.libs/libr3.a) @@ -394,6 +397,7 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${src_dir}) include_directories(${build_include_dir}) include_directories(${fmt_source_dir}) +include_directories(${yaml_source_dir}/include) include_directories(${http_parser_source_dir}) include_directories(${lexertl_dir}) include_directories(${libuv_source_dir}/include) @@ -412,6 +416,7 @@ EXECUTE_PROCESS( # TODO: create separate static library from bolt code set(memgraph_src_files + ${src_dir}/config/config.cpp ${src_dir}/dbms/dbms.cpp ${src_dir}/dbms/cleaner.cpp ${src_dir}/utils/string/transform.cpp @@ -518,7 +523,7 @@ string(STRIP ${COMMIT_BRANCH} COMMIT_BRANCH) string(STRIP ${COMMIT_NO} COMMIT_NO) string(STRIP ${COMMIT_HASH} COMMIT_HASH) set(MEMGRAPH_BUILD_NAME - "memgraph_${COMMIT_BRANCH}_${COMMIT_HASH}_${COMMIT_NO}_${CMAKE_BUILD_TYPE}") + "memgraph_${COMMIT_NO}_${COMMIT_HASH}_${COMMIT_BRANCH}_${CMAKE_BUILD_TYPE}") # memgraph main executable if (MEMGRAPH) @@ -536,6 +541,7 @@ if (MEMGRAPH) target_link_libraries(${MEMGRAPH_BUILD_NAME} crypto) # target_link_libraries(${MEMGRAPH_BUILD_NAME} ssl) target_link_libraries(${MEMGRAPH_BUILD_NAME} ${fmt_static_lib}) + target_link_libraries(${MEMGRAPH_BUILD_NAME} ${yaml_static_lib}) target_link_libraries(${MEMGRAPH_BUILD_NAME} dl) endif (UNIX) endif() diff --git a/config/memgraph.yaml b/config/memgraph.yaml new file mode 100644 index 000000000..18858d113 --- /dev/null +++ b/config/memgraph.yaml @@ -0,0 +1,4 @@ +compile_cpu_path: "./compiled/cpu/" +template_cpu_cpp_path: "./template/template_code_cpu.cpp" +barrier_template_cpu_cpp_path: "./template/barrier_template_code_cpu.cpp" +template_cpu_hpp_path: "./template/template_code_cpu.hpp" diff --git a/include/communication/bolt/v1/packing/codes.hpp b/include/communication/bolt/v1/packing/codes.hpp index 274cbb757..a8c6e7c3e 100644 --- a/include/communication/bolt/v1/packing/codes.hpp +++ b/include/communication/bolt/v1/packing/codes.hpp @@ -13,6 +13,7 @@ enum Code : uint8_t TinyString = 0x80, TinyList = 0x90, TinyMap = 0xA0, + TinyStruct = 0xB0, Null = 0xC0, @@ -53,6 +54,11 @@ enum Code : uint8_t EndOfStream = 0xDF, }; +enum Rule : uint8_t +{ + MaxInitStructSize = 0x02 +}; + } } diff --git a/include/config/config.hpp b/include/config/config.hpp index 748f94d0a..36d55b638 100644 --- a/include/config/config.hpp +++ b/include/config/config.hpp @@ -5,8 +5,27 @@ namespace config { +// this class is used as a Definition class of config::Config class from utils +// number of elements shoud be small, +// it depends on implementation of config::Config class +// in other words number of fields in Definition class should be related +// to the number of config keys +class MemgraphConfig +{ +public: + static const char *env_config_key; + static const char *default_file_path; +}; + +// -- all possible Memgraph's keys -- constexpr const char *COMPILE_CPU_PATH = "compile_cpu_path"; constexpr const char *TEMPLATE_CPU_CPP_PATH = "template_cpu_cpp_path"; constexpr const char *BARRIER_TEMPLATE_CPU_CPP_PATH = "barrier_template_cpu_cpp_path"; +// -- all possible Memgraph's keys -- + } + +// code uses this define for key access +// _KEY_ is value from all possible keys that are listed above +#define CONFIG(_KEY_) config::Config::instance()[_KEY_] diff --git a/include/dbms/dbms.hpp b/include/dbms/dbms.hpp index e4c376209..60e35a1bf 100644 --- a/include/dbms/dbms.hpp +++ b/include/dbms/dbms.hpp @@ -13,7 +13,7 @@ public: Db &active(); // set active database - // if active database doesn't exist create one + // if active database doesn't exist creates one Db &active(const std::string &name); // TODO: DELETE action diff --git a/include/query_engine/program_loader.hpp b/include/query_engine/program_loader.hpp index 184117463..aef72a4e3 100644 --- a/include/query_engine/program_loader.hpp +++ b/include/query_engine/program_loader.hpp @@ -48,7 +48,7 @@ public: // code has to be generated, compiled and loaded // TODO load output path from config - auto base_path = config::Config::instance()[config::COMPILE_CPU_PATH]; + auto base_path = CONFIG(config::COMPILE_CPU_PATH); auto path_cpp = base_path + hash_string + ".cpp"; auto stripped_space = stripper.strip_space(query); code_generator.generate_cpp(stripped_space.query, stripped.hash, diff --git a/include/utils/config/config.hpp b/include/utils/config/config.hpp index 0a3b33959..d18c7bebb 100644 --- a/include/utils/config/config.hpp +++ b/include/utils/config/config.hpp @@ -1,69 +1,59 @@ #pragma once -// #define YAML_CPP_DLL -// there are some problems with the yaml-cpp linking, something is missing -// cmake and make have passed fine -// and it seems that everything is included and linked -// the yaml-cpp lib is strange -// TODO debug yaml-cpp installation or write own yaml parser like a boss -// #include "yaml-cpp/yaml.h" - #include #include #include #include +// TODO: isolate from caller (caller should know that his dependency is +// yaml-cpp +#include "yaml-cpp/yaml.h" + namespace config { +template class Config { private: - // YAML::Node _config; + YAML::Node _config; + Config() { - // TODO: config places: priority - // 1. default system | - // 2. default user | - // 3. ENV var | - // 4. program argument \ / - // _config = YAML::LoadFile("config.yaml"); - - // env -> std::getenv("NAME") - // somehow inject (int argc, char* argv[]) + // config places: priority + // 1. default system | (/etc/name/config) + // 2. default user | (/home/user/.name/config) + // 3. ENV var | (PATH) + // 4. program argument \ / (PATH) + + if (const char* env_path = std::getenv(Definition::env_config_key)) + { + _config = YAML::LoadFile(env_path); + // TODO: error handling + } + else + { + _config = YAML::LoadFile(Definition::default_file_path); + // TODO: error handling + } + + // TODO: + // * default system + // * default user + // * program argument } public: - static Config& instance() + static Config& instance() { - static Config config; + static Config config; return config; } std::string operator[](const char* key) { - // TODO write proper implementation, remove memgraph dependant - // stuff from here - - if (0 == std::strcmp(key, "compile_cpu_path")) - return "./compiled/cpu/"; - - if (std::strcmp(key, "template_cpu_cpp_path") == 0) - return "./template/template_code_cpu.cpp"; - - if (std::strcmp(key, "barrier_template_cpu_cpp_path") == 0) - return "./template/barrier_template_code_cpu.cpp"; - - if (std::strcmp(key, "template_cpu_hpp_path") == 0) - return "./template/template_code_cpu.hpp"; - - throw std::runtime_error("implement me"); - - // TODO optimize access - // return _config[key].as(); + return _config[key].template as(); } }; } - -#define CONFIG(_KEY_) config::Config::instance()[_KEY_] diff --git a/include/web/client.hpp b/include/web/client.hpp new file mode 100644 index 000000000..1eed475ee --- /dev/null +++ b/include/web/client.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace web +{ + +class Client +{ + void post(const std::string& url, const std::string& body); +}; + +} diff --git a/include/web/logger.hpp b/include/web/logger.hpp new file mode 100644 index 000000000..6b08419a4 --- /dev/null +++ b/include/web/logger.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +namespace web +{ + +class Logger +{ +public: + + Logger() { /* create connection */ } + + // TODO: singleton + + void up_ping(); + void send(const std::string&); + void down_ping(); +}; + +} diff --git a/libs/setup.sh b/libs/setup.sh index 1bcf8ad2e..7aeb82fbb 100755 --- a/libs/setup.sh +++ b/libs/setup.sh @@ -16,6 +16,15 @@ cmake . make cd .. +# yaml-cpp +git clone https://github.com/jbeder/yaml-cpp +yaml_cpp_tag="519d33fea3fbcbe7e1f89f97ee0fa539cec33eb7" +cd yaml-cpp +git checkout ${yaml_cpp_tag} +cmake . +make +cd .. + # http_parser git clone https://github.com/nodejs/http-parser http_parser_tag="4e382f96e6d3321538a78f2c7f9506d4e79b08d6" diff --git a/src/communication/bolt/v1/states/init.cpp b/src/communication/bolt/v1/states/init.cpp index d792014c3..c0f2de255 100644 --- a/src/communication/bolt/v1/states/init.cpp +++ b/src/communication/bolt/v1/states/init.cpp @@ -1,7 +1,7 @@ #include "communication/bolt/v1/states/init.hpp" -#include "communication/bolt/v1/session.hpp" #include "communication/bolt/v1/messaging/codes.hpp" +#include "communication/bolt/v1/session.hpp" #include "utils/likely.hpp" @@ -10,24 +10,23 @@ namespace bolt Init::Init() : MessageParser(logging::log->logger("Init")) {} -State* Init::parse(Session& session, Message& message) +State *Init::parse(Session &session, Message &message) { auto struct_type = session.decoder.read_byte(); - if(UNLIKELY(struct_type != 0xB2)) - { + if (UNLIKELY(struct_type & 0x0F <= pack::Rule::MaxInitStructSize)) { logger.debug("{}", struct_type); - logger.debug("Expected struct marker 0xB2 instead of 0x{:02X}", - (unsigned)struct_type); + logger.debug( + "Expected struct marker of max size 0x{:02} instead of 0x{:02X}", + pack::Rule::MaxInitStructSize, pack::Code(unsigned) struct_type); return nullptr; } auto message_type = session.decoder.read_byte(); - if(UNLIKELY(message_type != MessageCode::Init)) - { + if (UNLIKELY(message_type != MessageCode::Init)) { logger.debug("Expected Init (0x01) instead of (0x{:02X})", (unsigned)message_type); @@ -36,12 +35,12 @@ State* Init::parse(Session& session, Message& message) message.client_name = session.decoder.read_string(); - // TODO read authentication tokens + // TODO read authentication tokens if B2 return this; } -State* Init::execute(Session& session, Message& message) +State *Init::execute(Session &session, Message &message) { logger.debug("Client connected '{}'", message.client_name); @@ -51,5 +50,4 @@ State* Init::execute(Session& session, Message& message) return session.bolt.states.executor.get(); } - } diff --git a/src/config/config.cpp b/src/config/config.cpp new file mode 100644 index 000000000..bf8f4700f --- /dev/null +++ b/src/config/config.cpp @@ -0,0 +1,9 @@ +#include "config/config.hpp" + +namespace config +{ + +const char *MemgraphConfig::env_config_key = "MEMGRAPH_CONFIG"; +const char *MemgraphConfig::default_file_path = "config.yaml"; + +} diff --git a/src/examples/bolt_py_client/create_benchmark.py b/src/examples/bolt_py_client/create_benchmark.py new file mode 100644 index 000000000..f826dabce --- /dev/null +++ b/src/examples/bolt_py_client/create_benchmark.py @@ -0,0 +1,35 @@ +import time +from neo4j.v1 import GraphDatabase, basic_auth, types +from concurrent.futures import ProcessPoolExecutor + +# create session +driver = GraphDatabase.driver("bolt://localhost", + auth=basic_auth("neo4j", "neo4j"), + encrypted=0) +session = driver.session() + +queries_no = 10 + +queries = ["CREATE (n {prop: 10}) RETURN n"] * queries_no + +def create_query(index): + ''' + Task (process or thread) + Runs create query agains the database. + + :param index: int -> number of task + :returns: (int, float) -> (task index, elapsed time) + ''' + start = time.time() + for query in queries: + for record in session.run(query): + pass + end = time.time() + return time + + +with ProcessPoolExecutor(processes=4) as executor: + results = [] + print(results) + +# print(1.0 * queries_no / (end - start)) diff --git a/src/web/client.cpp b/src/web/client.cpp new file mode 100644 index 000000000..aafe281d8 --- /dev/null +++ b/src/web/client.cpp @@ -0,0 +1,10 @@ +#include "web/client.hpp" + +namespace web +{ + +void Client::post(const std::string&, const std::string&) +{ +} + +} diff --git a/src/web/logger.cpp b/src/web/logger.cpp new file mode 100644 index 000000000..455206175 --- /dev/null +++ b/src/web/logger.cpp @@ -0,0 +1,18 @@ +#include "web/logger.hpp" + +namespace web +{ + +void Logger::up_ping() +{ +} + +void Logger::send(const std::string&) +{ +} + +void Logger::down_ping() +{ +} + +}