diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 82f005623..000000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "src/speedy/r3"] - path = src/speedy/r3 - url = https://github.com/c9s/r3.git -[submodule "src/speedy/rapidjson"] - path = src/speedy/rapidjson - url = https://github.com/miloyip/rapidjson.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 0547d67ee..b5c6c74cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 3.1) -# set directory name as the project name # get directory name get_filename_component(ProjectId ${CMAKE_SOURCE_DIR} NAME) # replace whitespaces with underscores @@ -8,6 +7,8 @@ string(REPLACE " " "_" ProjectId ${ProjectId}) # set project name project(${ProjectId}) +find_package(Threads REQUIRED) + # c++14 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y") @@ -47,43 +48,35 @@ endif (UNIX) # external dependencies -include(ExternalProject) - set(build_include_dir ${CMAKE_BINARY_DIR}/include) set(src_dir ${CMAKE_SOURCE_DIR}/src) set(libs_dir ${CMAKE_SOURCE_DIR}/libs) -# lemon -set(lemon_dir "${libs_dir}/lemon") -set(lemon_tag "f38a55106d79b7a4c063abb958517d6c47dc6ac7") -set(lemon_url "http://www.sqlite.org/src/raw/tool/lemon.c?name=${lemon_tag}") -ExternalProject_Add( - lemon - DOWNLOAD_COMMAND wget ${lemon_url} -O lemon.c - DOWNLOAD_DIR ${lemon_dir} - SOURCE_DIR ${lemon_dir} - BINARY_DIR ${lemon_dir} - CONFIGURE_COMMAND "" - BUILD_COMMAND clang lemon.c -o lemon -O2 - INSTALL_COMMAND "" - TEST_COMMAND "" -) +# setup external dependencies -# lempar -set(lempar_dir "${libs_dir}/lemon") -set(lempar_tag "404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6") -set(lempar_url "http://www.sqlite.org/src/raw/tool/lempar.c?name=${lempar_tag}") -ExternalProject_Add( - lempar - DOWNLOAD_COMMAND wget ${lempar_url} -O lempar.c - DOWNLOAD_DIR ${lempar_dir} - SOURCE_DIR ${lempar_dir} - BINARY_DIR ${lempar_dir} - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" -) +# !! IMPORTANT !! run ./libs/setup.sh before cmake command +# TODO: run from execute_process + +# lemon & lempar +set(lemon_dir ${libs_dir}/lemon) +# lexertl +set(lexertl_dir ${libs_dir}/lexertl) +# fmt +set(fmt_source_dir ${libs_dir}/fmt) +set(fmt_static_lib ${fmt_source_dir}/fmt/libfmt.a) +# r3 +set(r3_source_dir ${libs_dir}/r3) +set(r3_static_lib ${r3_source_dir}/.libs/libr3.a) +# http-parser +set(http_parser_source_dir "${libs_dir}/http-parser") +set(http_parser_static_lib ${http_parser_source_dir}/libhttp_parser.a) +# libuv +set(libuv_source_dir ${libs_dir}/libuv) +set(libuv_static_lib ${libuv_source_dir}/.libs/libuv.a) +# rapidjson (C++ JSON encoder/decoder) +set(rapidjson_source_dir "${libs_dir}/rapidjson") +# Catch (C++ Automated Test Cases in Headers) +set(catch_source_dir "${libs_dir}/Catch") # build memgraph's cypher grammar # copy grammar file to the build directory @@ -100,46 +93,11 @@ SET(cypher_build_include_dir ${build_include_dir}/cypher) FILE(MAKE_DIRECTORY ${cypher_build_include_dir}) FILE(RENAME ${CMAKE_BINARY_DIR}/cypher.h ${cypher_build_include_dir}/cypher.h) -# lexertl -set(lexertl_dir ${libs_dir}/lexertl) -ExternalProject_Add( - lexertl - GIT_REPOSITORY "https://github.com/BenHanson/lexertl.git" - GIT_TAG "7d4d36a357027df0e817453cc9cf948f71047ca9" - SOURCE_DIR "${libs_dir}/lexertl" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" -) - -# fmtlib -set(fmt_dir "${libs_dir}/fmt") -set(fmt_tag "e5e4fb370ccf327bbdcdcd782eb3e53580e11094") # version 3.0.0 -ExternalProject_Add( - fmt - GIT_REPOSITORY "https://github.com/fmtlib/fmt.git" - GIT_TAG "${fmt_tag}" - SOURCE_DIR "${libs_dir}/fmt" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" -) -ExternalProject_Get_Property(fmt source_dir) -set(fmt_source_dir ${source_dir}) -ExternalProject_Get_Property(fmt binary_dir) -set(fmt_binary_dir ${binary_dir}) -set(fmt_static_lib ${fmt_binary_dir}/fmt/libfmt.a) -# message(STATUS "Fmt source dir is: ${fmt_source_dir}") -# message(STATUS "fmt binary dir is: ${fmt_binary_dir}") -# message(STATUS "fmt static lib is: ${fmt_static_lib}") - # compiler options SET(COMPILE_OPTIONS "-O0 -g3 -Wall -Werror -fmessage-length=0") # add all cpp file recursive into sourceFiles varibale -FILE(GLOB_RECURSE sourceFiles ${src_dir}/*.cpp) +# FILE(GLOB_RECURSE sourceFiles ${src_dir}/*.cpp) # print list of source files # MESSAGE(STATUS "All source files are: ${sourceFiles}") @@ -161,9 +119,13 @@ endif() # includes include_directories(${src_dir}) -include_directories(${lexertl_dir}) -include_directories(${fmt_source_dir}) include_directories(${build_include_dir}) +include_directories(${fmt_source_dir}) +include_directories(${http_parser_source_dir}) +include_directories(${lexertl_dir}) +include_directories(${libuv_source_dir}/include) +include_directories(${rapidjson_source_dir}/include) +include_directories(${r3_source_dir}/include) # creates build/libcypher_lib.a add_library(cypher_lib STATIC ${CMAKE_BINARY_DIR}/cypher.cpp) @@ -171,3 +133,18 @@ add_library(cypher_lib STATIC ${CMAKE_BINARY_DIR}/cypher.cpp) # tests enable_testing() add_subdirectory(tests) + +EXECUTE_PROCESS( + COMMAND python link_resources.py + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/api +) + +# add main executable +add_executable(memgraph src/memgraph.cpp) + +# link libraries +target_link_libraries(memgraph Threads::Threads) +target_link_libraries(memgraph pcre) +target_link_libraries(memgraph ${libuv_static_lib}) +target_link_libraries(memgraph ${r3_static_lib}) +target_link_libraries(memgraph ${http_parser_static_lib}) diff --git a/README.md b/README.md index 6ccd23ebc..632cc5379 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,6 @@ ctest -R concurrent ctest -R concurrent --parallel 4 ``` +# custom test build example +clang++ -std=c++1y -o concurrent_skiplist ../tests/concurrent/skiplist.cpp -pg -I../src/ -I../libs/fmt -Lfmt-prefix/src/fmt-build/fmt -lfmt -lpthread + diff --git a/docker/memgraph.dockerfile b/docker/memgraph.dockerfile new file mode 100644 index 000000000..357b53a8b --- /dev/null +++ b/docker/memgraph.dockerfile @@ -0,0 +1,33 @@ +FROM ubuntu:16.04 + +# apt-get setup +RUN apt-get update \ + && apt-get install -y cmake git python clang wget \ + && apt-get install -y check libpcre3 libpcre3-dev libjemalloc-dev \ + libjemalloc1 build-essential libtool automake \ + autoconf pkg-config +# && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# prepare source +RUN mkdir -p /memgraph/build +RUN mkdir -p /memgraph/libs +COPY libs/setup.sh /memgraph/libs/setup.sh +COPY src /memgraph/src +COPY tests /memgraph/tests +COPY CMakeLists.txt /memgraph/CMakeLists.txt + +# setup libs +WORKDIR /memgraph/libs +RUN ./setup.sh + +# build +WORKDIR /memgraph/build +RUN cmake -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DRUNTIME_ASSERT=OFF \ + -DTHROW_EXCEPTION_ON_ERROR=OFF \ + -DNDEBUG=OFF .. +RUN make + +# run +CMD /memgraph/build/memgraph 7474 diff --git a/docker/test.dockerfile b/docker/test.dockerfile deleted file mode 100644 index e88bfc407..000000000 --- a/docker/test.dockerfile +++ /dev/null @@ -1,45 +0,0 @@ -FROM ubuntu:16.04 - -# apt-get setup -RUN apt-get update \ - && apt-get install -y cmake git python clang \ - && apt-get install -y check libpcre3 libpcre3-dev libjemalloc-dev \ - libjemalloc1 build-essential libtool automake \ - autoconf pkg-config -# && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -RUN git clone https://pullbot:JnSdamFGKOanF1@phabricator.tomicevic.com/diffusion/MG/memgraph.git /memgraph - -# update all submodules -WORKDIR /memgraph -RUN git submodule update --init - -# install r3 -WORKDIR /memgraph/src/speedy/r3 -RUN git checkout 28726b27af3cd0a9d3166033c6619a9c7227cb48 -RUN ./autogen.sh && ./configure && make - -# install libuv -RUN git clone https://github.com/libuv/libuv.git /libs/libuv -WORKDIR /libs/libuv -RUN ./autogen.sh && ./configure && make && make check && make install -ENV LD_LIBRARY_PATH /usr/local/lib - -# install http_parser -RUN git clone https://github.com/nodejs/http-parser /libs/http_parser -WORKDIR /libs/http_parser -# TODO: remove from here, in the time of writing the master branch -# had a bug, some not HEAD commit was checked out -RUN git checkout 4e382f96e6d3321538a78f2c7f9506d4e79b08d6 -RUN make && make install - -WORKDIR /memgraph/build -RUN cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..\ - && make && ctest - -# compile memgraph -WORKDIR /memgraph -RUN ./build.sh - -# run memgraph -CMD /memgraph/memgraph 7474 diff --git a/libs/.gitignore b/libs/.gitignore index d6b7ef32c..e161b1247 100644 --- a/libs/.gitignore +++ b/libs/.gitignore @@ -1,2 +1,4 @@ * !.gitignore +!setup.sh +!cleanup.sh diff --git a/libs/cleanup.sh b/libs/cleanup.sh new file mode 100755 index 000000000..e70f042fd --- /dev/null +++ b/libs/cleanup.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +for folder in ./* ; do + if [ -d "$folder" ]; then + rm -rf $folder + fi +done diff --git a/libs/setup.sh b/libs/setup.sh new file mode 100755 index 000000000..1bcf8ad2e --- /dev/null +++ b/libs/setup.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# Catch +git clone https://github.com/philsquared/Catch.git +catch_tag="master" +cd Catch +git checkout ${catch_tag} +cd .. + +# fmt +git clone https://github.com/fmtlib/fmt.git +fmt_tag="e5e4fb370ccf327bbdcdcd782eb3e53580e11094" +cd fmt +git checkout ${fmt_tag} +cmake . +make +cd .. + +# http_parser +git clone https://github.com/nodejs/http-parser +http_parser_tag="4e382f96e6d3321538a78f2c7f9506d4e79b08d6" +cd http-parser +git checkout ${http_parser_tag} +make package +cd .. + +# lemon +mkdir lemon +cd lemon +lemon_tag="09a96bed19955697a5e20c49ad863ec2005815a2" +wget http://www.sqlite.org/src/raw/tool/lemon.c?name=${lemon_tag} -O lemon.c +lempar_tag="8c4e9d8517e50da391f1d89a519e743dd4afbc09" +wget http://www.sqlite.org/src/raw/tool/lempar.c?name=${lempar_tag} -O lempar.c +clang lemon.c -o lemon -O2 +cd .. + +# lexertl +git clone https://github.com/BenHanson/lexertl.git +lexertl_tag=7d4d36a357027df0e817453cc9cf948f71047ca9 +cd lexertl +git checkout ${lexertl_tag} +cd .. + +# libuv +git clone https://github.com/libuv/libuv.git +libuv_tag="c82eedd0a76233f0894098853b5a0c307af27064" +cd libuv +git checkout ${libuv_tag} +./autogen.sh && ./configure && make +cd .. + +# rapidjson +git clone https://github.com/miloyip/rapidjson.git +rapidjson_tag=${3d5848a7cd3367c5cb451c6493165b7745948308} +cd rapidjson +git checkout ${rapidjson_tag} +cd .. + +# r3 + +# UBUNTU 16.04 +# TODO: automate this +# sudo apt-get -y install check libpcre3 libpcre3-dev libjemalloc-dev +# sudo apt-get -y install libjemalloc1 build-essential libtool automake +# sudo apt-get -y install autoconf pkg-config + +git clone https://github.com/c9s/r3.git +r3_tag=28726b27af3cd0a9d3166033c6619a9c7227cb48 +cd r3 +git checkout ${r3_tag} +./autogen.sh && ./configure && make +cd .. diff --git a/src/api/resources/demo.hpp b/src/api/resources/demo.hpp index 7fa19ecb4..08cdbe4a3 100644 --- a/src/api/resources/demo.hpp +++ b/src/api/resources/demo.hpp @@ -65,8 +65,8 @@ public: auto e = db->graph.edges.insert(t); - v1.vlist->access(t).update()->data.out.add(e.vlist); - v2.vlist->access(t).update()->data.in.add(e.vlist); + v1.vlist->update(t)->data.out.add(e.vlist); + v2.vlist->update(t)->data.in.add(e.vlist); e.from(v1.vlist); e.to(v2.vlist); diff --git a/src/cypher/ast/accessor.hpp b/src/cypher/ast/accessor.hpp index 928321277..de4b7d9f3 100644 --- a/src/cypher/ast/accessor.hpp +++ b/src/cypher/ast/accessor.hpp @@ -9,7 +9,7 @@ namespace ast { -struct Accessor : public VisitableExpr<Accessor> +struct Accessor : public ValueExpr<Accessor> { Accessor(Identifier* entity, Identifier* prop) : entity(entity), prop(prop) {} diff --git a/src/cypher/ast/expr.hpp b/src/cypher/ast/expr.hpp index 71ac88217..701129759 100644 --- a/src/cypher/ast/expr.hpp +++ b/src/cypher/ast/expr.hpp @@ -10,7 +10,7 @@ struct Expr : public AstVisitable }; template <class Derived> -struct VisitableExpr : public Crtp<Derived>, public Expr +struct ValueExpr : public Crtp<Derived>, public Expr { using uptr = std::unique_ptr<Derived>; @@ -21,14 +21,14 @@ struct VisitableExpr : public Crtp<Derived>, public Expr }; template <class T, class Derived> -struct LeafExpr : public VisitableExpr<Derived> +struct LeafExpr : public ValueExpr<Derived> { LeafExpr(T value) : value(value) {} T value; }; template <class Derived> -struct BinaryExpr : public VisitableExpr<Derived> +struct BinaryExpr : public ValueExpr<Derived> { BinaryExpr(Expr* left, Expr* right) : left(left), right(right) {} @@ -36,10 +36,17 @@ struct BinaryExpr : public VisitableExpr<Derived> Expr* right; }; -struct PatternExpr : public VisitableExpr<PatternExpr> +struct PatternExpr : public Expr { + using uptr = std::unique_ptr<PatternExpr>; + PatternExpr(Pattern* pattern) : pattern(pattern) {} + virtual void accept(AstVisitor& visitor) + { + visitor.visit(*this); + } + Pattern* pattern; }; diff --git a/src/cypher/ast/start.hpp b/src/cypher/ast/start.hpp index 649e2a1e7..4573b16b5 100644 --- a/src/cypher/ast/start.hpp +++ b/src/cypher/ast/start.hpp @@ -3,22 +3,13 @@ #include "ast_node.hpp" #include "queries.hpp" +// LEGACY TODO remove from here + namespace ast { struct Start : public AstNode<Start> { - Start(WriteQuery* write_query) : write_query(write_query) {} - Start(ReadQuery* read_query) : read_query(read_query) {} - Start(UpdateQuery* update_query) : update_query(update_query) {} - Start(DeleteQuery* delete_query) : delete_query(delete_query) {} - - // TODO: the start structure must have a different implementation - // is this class necessary? - WriteQuery* write_query {nullptr}; - ReadQuery* read_query {nullptr}; - UpdateQuery* update_query {nullptr}; - DeleteQuery* delete_query {nullptr}; }; }; diff --git a/src/cypher/cypher.y b/src/cypher/cypher.y index 4237db439..74ceb2e02 100644 --- a/src/cypher/cypher.y +++ b/src/cypher/cypher.y @@ -56,19 +56,19 @@ // start structure start ::= write_query(WQ). { - ast->root = ast->create<ast::Start>(WQ); + ast->root = WQ; } start ::= read_query(RQ). { - ast->root = ast->create<ast::Start>(RQ); + ast->root = RQ; } start ::= update_query(UQ). { - ast->root = ast->create<ast::Start>(UQ); + ast->root = UQ; } start ::= delete_query(DQ). { - ast->root = ast->create<ast::Start>(DQ); + ast->root = DQ; } // write query structure @@ -211,10 +211,6 @@ node(N) ::= LP node_idn(I) label_idn(L) properties(P) RP. { N = ast->create<ast::Node>(I, L, P); } -node(N) ::= idn(I). { - N = ast->create<ast::Node>(I, nullptr, nullptr); -} - %type node_idn {ast::Identifier*} // a node identifier can be ommitted @@ -302,104 +298,114 @@ property_list(L) ::= property(P). { %type property {ast::Property*} // IDENTIFIER ':' <expression> -property(P) ::= idn(I) COLON expr(E). { +property(P) ::= idn(I) COLON value_expr(E). { P = ast->create<ast::Property>(I, E); } -%type expr {ast::Expr*} +%type value_expr {ast::Expr*} -expr(E) ::= expr(L) AND expr(R). { +value_expr(E) ::= value_expr(L) AND value_expr(R). { E = ast->create<ast::And>(L, R); } -expr(E) ::= expr(L) OR expr(R). { +value_expr(E) ::= value_expr(L) OR value_expr(R). { E = ast->create<ast::Or>(L, R); } -expr(E) ::= expr(L) LT expr(R). { +value_expr(E) ::= value_expr(L) LT value_expr(R). { E = ast->create<ast::Lt>(L, R); } -expr(E) ::= expr(L) GT expr(R). { +value_expr(E) ::= value_expr(L) GT value_expr(R). { E = ast->create<ast::Gt>(L, R); } -expr(E) ::= expr(L) GE expr(R). { +value_expr(E) ::= value_expr(L) GE value_expr(R). { E = ast->create<ast::Ge>(L, R); } -expr(E) ::= expr(L) LE expr(R). { +value_expr(E) ::= value_expr(L) LE value_expr(R). { E = ast->create<ast::Le>(L, R); } -expr(E) ::= expr(L) EQ expr(R). { +value_expr(E) ::= value_expr(L) EQ value_expr(R). { E = ast->create<ast::Eq>(L, R); } -expr(E) ::= expr(L) NE expr(R). { +value_expr(E) ::= value_expr(L) NE value_expr(R). { E = ast->create<ast::Ne>(L, R); } -expr(E) ::= expr(L) PLUS expr(R). { +value_expr(E) ::= value_expr(L) PLUS value_expr(R). { E = ast->create<ast::Plus>(L, R); } -expr(E) ::= expr(L) MINUS expr(R). { +value_expr(E) ::= value_expr(L) MINUS value_expr(R). { E = ast->create<ast::Minus>(L, R); } -expr(E) ::= expr(L) STAR expr(R). { +value_expr(E) ::= value_expr(L) STAR value_expr(R). { E = ast->create<ast::Star>(L, R); } -expr(E) ::= expr(L) SLASH expr(R). { +value_expr(E) ::= value_expr(L) SLASH value_expr(R). { E = ast->create<ast::Slash>(L, R); } -expr(E) ::= expr(L) REM expr(R). { +value_expr(E) ::= value_expr(L) REM value_expr(R). { E = ast->create<ast::Rem>(L, R); } -expr(E) ::= idn(I). { +value_expr(E) ::= idn(I). { E = ast->create<ast::Accessor>(I, nullptr); } -expr(E) ::= idn(I) DOT idn(P). { +value_expr(E) ::= idn(I) DOT idn(P). { E = ast->create<ast::Accessor>(I, P); } -// this production produces parser conflicts TODO: findout why -// the intention os to add patter in the RETURN statement -// expr(E) ::= pattern(P). { -// E = ast->create<ast::PatternExpr>(P); -// } - %type idn {ast::Identifier*} idn(I) ::= IDN(X). { I = ast->create<ast::Identifier>(X->value); } -expr(E) ::= INT(V). { +value_expr(E) ::= INT(V). { auto value = std::stoi(V->value); E = ast->create<ast::Integer>(value); } -expr(E) ::= FLOAT(V). { +value_expr(E) ::= FLOAT(V). { auto value = std::stod(V->value); E = ast->create<ast::Float>(value); } -expr(E) ::= STR(V). { +value_expr(E) ::= STR(V). { auto value = V->value.substr(1, V->value.size() - 2); E = ast->create<ast::String>(value); } -expr(E) ::= BOOL(V). { +value_expr(E) ::= BOOL(V). { auto value = V->value[0] == 't' || V->value[0] == 'T' ? true : false; E = ast->create<ast::Boolean>(value); } +// %type pattern_expr {ast::Expr*} +// +// patter_expr(E) ::= pattern(P). { +// E = ast->create<ast::PatternExpr>(P); +// } + +%type expr {ast::Expr*} + +expr(E) ::= value_expr(V). { + E = V; +} + +// expr(E) ::= patter_expr(P). { +// E = P; +// } + //%type alias {ast::Alias*} // //alias(A) ::= IDN(X) AS IDN(Y). { @@ -433,6 +439,6 @@ accessor(A) ::= idn(E) DOT idn(P). { %type set_value {ast::SetValue*} -set_value(V) ::= expr(E). { +set_value(V) ::= value_expr(E). { V = ast->create<ast::SetValue>(E); } diff --git a/src/cypher/visitor/traverser.hpp b/src/cypher/visitor/traverser.hpp index 252e486e6..222f441ab 100644 --- a/src/cypher/visitor/traverser.hpp +++ b/src/cypher/visitor/traverser.hpp @@ -12,14 +12,6 @@ public: void visit(ast::Start& start) override { - if (start.write_query != nullptr) - accept(start.write_query); - if (start.read_query != nullptr) - accept(start.read_query); - if (start.update_query != nullptr) - accept(start.update_query); - if (start.delete_query != nullptr) - accept(start.delete_query); } void visit(ast::DeleteQuery& delete_query) override diff --git a/src/data_structures/skiplist/skiplist_gc.hpp b/src/data_structures/skiplist/skiplist_gc.hpp index f85af7c8f..f1950e5da 100644 --- a/src/data_structures/skiplist/skiplist_gc.hpp +++ b/src/data_structures/skiplist/skiplist_gc.hpp @@ -28,10 +28,15 @@ public: } } + long long counter = 0; + // destroy all elements from local_freelist for (auto element : local_freelist) { + counter++; if (element->flags.is_marked()) T::destroy(element); } + + std::cout << "Destroy has been called: " << counter << std::endl; } void collect(T *node) { freelist.add(node); } diff --git a/src/mvcc/version_list.hpp b/src/mvcc/version_list.hpp index 49ae8b78a..63927faaf 100644 --- a/src/mvcc/version_list.hpp +++ b/src/mvcc/version_list.hpp @@ -19,68 +19,6 @@ public: using uptr = std::unique_ptr<VersionList<T>>; using item_t = T; - class Accessor - { - friend class VersionList<T>; - - Accessor(tx::Transaction& transaction, VersionList<T>& vlist) - : transaction(transaction), vlist(vlist) - { - vlist.add_ref(); - } - - public: - ~Accessor() - { - vlist.release_ref(); - } - - Accessor(const Accessor&) = default; - Accessor(Accessor&&) = default; - - Accessor& operator=(const Accessor&) = delete; - Accessor& operator=(Accessor&&) = delete; - - T* insert() - { - return vlist.insert(transaction); - } - - T* find() const - { - return vlist.find(transaction); - } - - T* update() - { - return vlist.update(transaction); - } - - T* update(T* record) - { - return vlist.update(record, transaction); - } - - bool remove() - { - return vlist.remove(transaction); - } - - bool remove(T* record) - { - return vlist.remove(record, transaction); - } - - const Id& id() const - { - return vlist.id; - } - - private: - tx::Transaction& transaction; - VersionList<T>& vlist; - }; - VersionList(Id id) : id(id) {} VersionList(const VersionList&) = delete; @@ -99,11 +37,6 @@ public: delete head.load(); } - Accessor access(tx::Transaction& transaction) - { - return Accessor(transaction, *this); - } - friend std::ostream& operator<<(std::ostream& stream, const VersionList<T>& vlist) { @@ -130,14 +63,6 @@ public: } - const Id id; - -private: - std::atomic<T*> head {nullptr}; - RecordLock lock; - - //static Recycler recycler; - T* find(const tx::Transaction& t) { auto r = head.load(std::memory_order_acquire); @@ -223,6 +148,9 @@ private: return true; } + const Id id; + +private: void lock_and_validate(T* record, tx::Transaction& t) { assert(record != nullptr); @@ -240,6 +168,9 @@ private: assert(record->hints.load().exp.is_committed()); throw SerializationError(); } + + std::atomic<T*> head {nullptr}; + RecordLock lock; }; } diff --git a/src/speedy/r3 b/src/speedy/r3 deleted file mode 160000 index cefefb239..000000000 --- a/src/speedy/r3 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cefefb239a698f85d1aae634f08bf79d5f9ec1d3 diff --git a/src/speedy/r3_include.h b/src/speedy/r3_include.h index 5901fd6b9..95cddaf75 100644 --- a/src/speedy/r3_include.h +++ b/src/speedy/r3_include.h @@ -12,8 +12,9 @@ #include <string.h> #include <pcre.h> #include <stdbool.h> -#include "r3/include/str_array.h" -#include "r3/include/r3_str.h" + +#include "str_array.h" +#include "r3_str.h" #ifdef __cplusplus extern "C" { diff --git a/src/speedy/rapidjson b/src/speedy/rapidjson deleted file mode 160000 index c02d52ad5..000000000 --- a/src/speedy/rapidjson +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c02d52ad56595dc70b38daf46b5f315d3a7115fa diff --git a/src/storage/edges.hpp b/src/storage/edges.hpp index e195d90dc..21c8ec081 100644 --- a/src/storage/edges.hpp +++ b/src/storage/edges.hpp @@ -14,9 +14,8 @@ public: if (edges_iterator == edges_accessor.end()) return Edge::Accessor(); - // find vertex - auto versions_accessor = edges_iterator->second.access(t); - auto edge = versions_accessor.find(); + // find edge + auto edge = edges_iterator->second.find(t); if (edge == nullptr) return Edge::Accessor(); @@ -41,8 +40,7 @@ public: // create new vertex auto inserted_edge_record = result.first; - auto edge_accessor = inserted_edge_record->second.access(t); - auto edge = edge_accessor.insert(); + auto edge = inserted_edge_record->second.insert(t); return Edge::Accessor(edge, &inserted_edge_record->second, this); } diff --git a/src/storage/record_accessor.hpp b/src/storage/record_accessor.hpp index bb8be62fe..19552553d 100644 --- a/src/storage/record_accessor.hpp +++ b/src/storage/record_accessor.hpp @@ -37,16 +37,14 @@ public: { assert(!empty()); - auto accessor = vlist->access(t); - return Derived(accessor.update(t), vlist, store); + return Derived(vlist->update(t), vlist, store); } bool remove(tx::Transaction& t) const { assert(!empty()); - auto accessor = vlist->access(t); - return accessor.remove(record); + return vlist->remove(record, t); } const Property& property(const std::string& key) const diff --git a/src/storage/vertices.hpp b/src/storage/vertices.hpp index c932fce33..16fc040e6 100644 --- a/src/storage/vertices.hpp +++ b/src/storage/vertices.hpp @@ -15,8 +15,7 @@ public: return Vertex::Accessor(); // find vertex - auto versions_accessor = vertices_iterator->second.access(t); - auto vertex = versions_accessor.find(); + auto vertex = vertices_iterator->second.find(t); if (vertex == nullptr) return Vertex::Accessor(); @@ -42,8 +41,7 @@ public: // create new vertex auto inserted_vertex_record = result.first; - auto vertex_accessor = inserted_vertex_record->second.access(t); - auto vertex = vertex_accessor.insert(); + auto vertex = inserted_vertex_record->second.insert(t); return Vertex::Accessor(vertex, &inserted_vertex_record->second, this); } diff --git a/src/utils/sysinfo/memory.hpp b/src/utils/sysinfo/memory.hpp new file mode 100644 index 000000000..802484aa8 --- /dev/null +++ b/src/utils/sysinfo/memory.hpp @@ -0,0 +1,24 @@ +#pragma mark + +#include "sys/types.h" +#include "sys/sysinfo.h" + +auto total_virtual_memory() +{ + struct sysinfo mem_info; + sysinfo (&mem_info); + long long total_virtual_memory = mem_info.totalram; + total_virtual_memory += mem_info.totalswap; + total_virtual_memory *= mem_info.mem_unit; + return total_virtual_memory; +} + +auto used_virtual_memory() +{ + struct sysinfo mem_info; + sysinfo (&mem_info); + long long virtual_memory_used = mem_info.totalram - mem_info.freeram; + virtual_memory_used += mem_info.totalswap - mem_info.freeswap; + virtual_memory_used *= mem_info.mem_unit; + return virtual_memory_used; +} diff --git a/src/utils/terminate_handler.hpp b/src/utils/terminate_handler.hpp index 294d31151..7c19396ac 100644 --- a/src/utils/terminate_handler.hpp +++ b/src/utils/terminate_handler.hpp @@ -26,7 +26,7 @@ void stacktrace(std::ostream& stream) noexcept // TODO: log to local file or remote database void terminate_handler(std::ostream& stream) noexcept { - if(auto exc = std::current_exception()) + if (auto exc = std::current_exception()) { try { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5d639378d..716d88dc9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,23 +2,6 @@ cmake_minimum_required(VERSION 3.1) project(memgraph_tests) -# setup dependencies -find_package(Threads REQUIRED) - -# Catch (C++ Automated Test Cases in Headers) dependency -ExternalProject_Add( - Catch - GIT_REPOSITORY "https://github.com/philsquared/Catch.git" - GIT_TAG "master" - SOURCE_DIR "${CMAKE_SOURCE_DIR}/libs/Catch" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" -) -ExternalProject_Get_Property(Catch source_dir) -set(catch_source_dir ${source_dir}) - include_directories(${catch_source_dir}/include) ## UNIT TESTS diff --git a/tests/concurrent/skiplist.cpp b/tests/concurrent/skiplist.cpp index 9ef4915ab..8651e51c7 100644 --- a/tests/concurrent/skiplist.cpp +++ b/tests/concurrent/skiplist.cpp @@ -5,6 +5,7 @@ #include "data_structures/skiplist/skiplist.hpp" #include "data_structures/static_array.hpp" #include "utils/assert.hpp" +#include "utils/sysinfo/memory.hpp" using std::cout; using std::endl; @@ -18,6 +19,8 @@ int main() { ds::static_array<std::thread, THREADS_NO> threads; skiplist_t skiplist; + + cout << "1. used virtual memory: " << used_virtual_memory() << endl; // put THREADS_NO * elems_per_thread items to the skiplist for (size_t thread_i = 0; thread_i < THREADS_NO; ++thread_i) { @@ -37,6 +40,8 @@ int main() thread.join(); } + cout << "1. used virtual memory: " << used_virtual_memory() << endl; + // get skiplist size { auto accessor = skiplist.access(); @@ -61,6 +66,8 @@ int main() thread.join(); } + cout << "1. used virtual memory: " << used_virtual_memory() << endl; + // check size { auto accessor = skiplist.access(); @@ -79,6 +86,8 @@ int main() } // TODO: test GC and memory + std::this_thread::sleep_for(5s); + cout << "1. used virtual memory: " << used_virtual_memory() << endl; return 0; } diff --git a/tests/data/cypher_queries/complex/powerlinx_opportunities.cypher b/tests/data/cypher_queries/complex/powerlinx_opportunities.cypher new file mode 100644 index 000000000..46bd5ec48 --- /dev/null +++ b/tests/data/cypher_queries/complex/powerlinx_opportunities.cypher @@ -0,0 +1 @@ +# MATCH (p:Personnel)-[:CREATED]->(o:Opportunity)-[:HAS_MATCH]->(c:Company {id: "321"}) RETURN (a:Account {id: "123"})-[:IS]->(p)