diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f399fd1..b652feb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,7 @@ - catkin_make - cd src - cp -r /builds/$GITLAB_USER_LOGIN/mementar . + - git clone -b proba https://github.com/sarthou/ontologenius.git - cd .. - catkin_make @@ -15,8 +16,11 @@ - catkin_make - cd src - cp -r /builds/$GITLAB_USER_LOGIN/mementar . + - git clone -b proba https://github.com/sarthou/ontologenius.git - cd .. - catkin_make + - source devel/setup.bash + - catkin_make run_tests_mementar_rostest -j1 && catkin_make test -j1 -DCATKIN_WHITELIST_PACKAGES="mementar" .kinetic_before_template : &kinetic_before_definition before_script: diff --git a/CMakeLists.txt b/CMakeLists.txt index a56be20..b254b74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ find_package(catkin REQUIRED COMPONENTS genmsg message_generation pluginlib + ontologenius ) ## System dependencies are found with CMake's conventions @@ -31,6 +32,8 @@ find_package(OpenCV REQUIRED) ## Generate messages in the 'msg' folder add_message_files( FILES + MementarAction.msg + MementarExplanation.msg MementarOccasion.msg StampedString.msg ) @@ -61,7 +64,7 @@ find_package(OpenCV REQUIRED) catkin_package( INCLUDE_DIRS include LIBRARIES mementar_lib - CATKIN_DEPENDS roscpp rospy std_msgs + CATKIN_DEPENDS roscpp rospy std_msgs ontologenius DEPENDS OpenCV ) @@ -72,7 +75,7 @@ catkin_package( ## Specify additional locations of header files ## Your package locations should be listed before other locations include_directories( - include + include include/mementar/API ${catkin_INCLUDE_DIRS} ) @@ -83,6 +86,17 @@ include_directories( ## ARCHIVING & COMPRESSION ############################## +############################## +## EVENTS +############################## + +add_library(mementar_events_lib + src/core/Occasions/Subscription.cpp + src/core/Occasions/OccasionsManager.cpp +) +target_link_libraries(mementar_events_lib ${catkin_LIBRARIES}) +add_dependencies(mementar_events_lib ${catkin_EXPORTED_TARGETS} mementar_gencpp) + ############################## ## CORE ############################## @@ -100,16 +114,13 @@ add_library(mementar_memGraphs_lib src/core/memGraphs/Branchs/ValuedNode.cpp src/core/memGraphs/Branchs/types/Action.cpp src/core/memGraphs/Branchs/types/Fact.cpp - src/core/memGraphs/Branchs/types/Event.cpp - src/core/memGraphs/DoublyLinkedList/DllCargoNode.cpp - src/core/memGraphs/DoublyLinkedList/DllLinkedElement.cpp - src/core/memGraphs/EventLinkedList/EllElement.cpp - src/core/memGraphs/EventLinkedList/EllNode.cpp + src/core/memGraphs/Branchs/types/SoftPoint.cpp + src/core/memGraphs/Branchs/types/Triplet.cpp src/core/memGraphs/Graphs/ActionGraph.cpp - src/core/memGraphs/Graphs/EventGraph.cpp + src/core/memGraphs/Graphs/FactGraph.cpp ) -add_library(mementar_core_lib +add_library(mementar_lt_lib src/core/LtManagement/EpisodicTree/CompressedLeaf.cpp src/core/LtManagement/EpisodicTree/CompressedLeafNode.cpp src/core/LtManagement/EpisodicTree/Context.cpp @@ -118,22 +129,20 @@ add_library(mementar_core_lib src/core/LtManagement/EpisodicTree/ArchivedLeaf.cpp src/core/LtManagement/EpisodicTree/ArchivedLeafNode.cpp ) -target_link_libraries(mementar_core_lib +target_link_libraries(mementar_lt_lib mementar_compression_lib mementar_memGraphs_lib pthread ) -############################## -## EVENTS -############################## - -add_library(mementar_events_lib - src/core/Occasions/Subscription.cpp - src/core/Occasions/OccasionsManager.cpp +add_library(mementar_core_lib + src/core/feeder/FeedStorage.cpp + src/core/feeder/Feeder.cpp + src/core/Parametrization/Configuration.cpp ) -target_link_libraries(mementar_events_lib ${catkin_LIBRARIES}) -add_dependencies(mementar_events_lib ${catkin_EXPORTED_TARGETS} mementar_gencpp) +target_link_libraries(mementar_core_lib mementar_lt_lib) +target_link_libraries(mementar_core_lib ${catkin_LIBRARIES}) +add_dependencies(mementar_core_lib ${catkin_EXPORTED_TARGETS}) ############################## ## DRAWER @@ -141,7 +150,7 @@ add_dependencies(mementar_events_lib ${catkin_EXPORTED_TARGETS} mementar_gencpp) add_library(mementar_drawer_lib src/graphical/timeline/ActionReader.cpp - src/graphical/timeline/EventReader.cpp + src/graphical/timeline/FactReader.cpp src/graphical/timeline/TimelineDrawer.cpp ) target_include_directories(mementar_drawer_lib @@ -158,6 +167,8 @@ target_link_libraries(mementar_drawer_lib ############################## add_library(mementar_lib + src/API/ActionsPublisher.cpp + src/API/ActionsSubscriber.cpp src/API/TimelineManipulator.cpp src/API/TimelinesManipulator.cpp src/API/clients/ManagerClient.cpp @@ -175,7 +186,7 @@ add_dependencies(mementar_lib ${catkin_EXPORTED_TARGETS} mementar_gencpp) add_library(mementar_interface src/RosInterface.cpp ) -target_link_libraries(mementar_interface mementar_core_lib mementar_events_lib) +target_link_libraries(mementar_interface mementar_core_lib mementar_events_lib mementar_drawer_lib) target_link_libraries(mementar_interface ${catkin_LIBRARIES}) add_dependencies(mementar_interface ${catkin_EXPORTED_TARGETS} mementar_gencpp) @@ -204,6 +215,10 @@ add_dependencies(mementar_timeline ${catkin_EXPORTED_TARGETS}) ## Test executables ############################## +add_executable(config src/test/config.cpp) +target_link_libraries(config ${catkin_LIBRARIES}) +target_link_libraries(config mementar_interface) + add_executable(event_sub_pub src/test/occasions_sub_pub.cpp) target_link_libraries(event_sub_pub ${catkin_LIBRARIES}) target_link_libraries(event_sub_pub mementar_lib) @@ -214,7 +229,62 @@ target_link_libraries(graphs mementar_memGraphs_lib) #add_executable(eventLink src/test/EventLink.cpp) -#target_link_libraries(eventLink mementar_core_lib) +#target_link_libraries(eventLink mementar_lt_lib) + +############################################################################## +# Qt Environment +############################################################################## + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) + +############################################################################## +# Sections +############################################################################## + +file(GLOB QT_FORMS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ui/*.ui) +file(GLOB QT_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} resources/*.qrc) + +QT5_ADD_RESOURCES(QT_RESOURCES_CPP ${QT_RESOURCES}) +QT5_WRAP_UI(QT_FORMS_HPP ${QT_FORMS}) + +add_definitions( -std=c++11 -fPIC) + +############################################################################## +# Sources +############################################################################## + +set( QT_SOURCES + src/graphical/mementarGUI/main.cpp + src/graphical/mementarGUI/mementargui.cpp + src/graphical/mementarGUI/DarkStyle.cpp + src/graphical/mementarGUI/QPushButtonExtended.cpp + src/graphical/mementarGUI/QCheckBoxExtended.cpp + src/graphical/mementarGUI/QLineEditExtended.cpp + + include/mementar/graphical/mementarGUI/mementargui.h + include/mementar/graphical/mementarGUI/DarkStyle.h + include/mementar/graphical/mementarGUI/QPushButtonExtended.h + include/mementar/graphical/mementarGUI/QCheckBoxExtended.h + include/mementar/graphical/mementarGUI/QLineEditExtended.h +) +############################################################################## +# Binaries +############################################################################## + +add_executable(mementarGUI ${QT_SOURCES} ${QT_RESOURCES_CPP} ${QT_FORMS_HPP} ${QT_MOC_HPP}) +target_include_directories(mementarGUI + PRIVATE + ${catkin_INCLUDE_DIRS} +) +add_dependencies(mementarGUI mementar_gencpp) +target_link_libraries(mementarGUI + ${catkin_LIBRARIES} + Qt5::Core + Qt5::Widgets + Qt5::PrintSupport +) +install(TARGETS mementarGUI RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) ############################## ## Install @@ -241,6 +311,10 @@ install(DIRECTORY include/${PROJECT_NAME}/ if(CATKIN_ENABLE_TESTING) find_package(rostest REQUIRED) - #add_rostest_gtest(mementar_tester test/library.test src/tests/library.cpp) - #target_link_libraries(mementar_tester mementar_lib) + add_rostest_gtest(mementar_fact_pub_sub_tester test/fact_pub_sub.test src/test/CI/fact_pub_sub.cpp) + target_link_libraries(mementar_fact_pub_sub_tester mementar_lib ontologenius_lib) + + add_rostest_gtest(mementar_action_pub_sub_tester test/action_pub_sub.test src/test/CI/action_pub_sub.cpp) + target_link_libraries(mementar_action_pub_sub_tester mementar_lib ontologenius_lib) + endif() diff --git a/files/config_example.yaml b/files/config_example.yaml new file mode 100644 index 0000000..c1b7ed3 --- /dev/null +++ b/files/config_example.yaml @@ -0,0 +1,6 @@ +whitelist: + - isPositioned + - hasColor +#blacklist: +# - isPositioned +# - hasColor diff --git a/include/mementar/API/ActionsPublisher.h b/include/mementar/API/ActionsPublisher.h new file mode 100644 index 0000000..f5e92f0 --- /dev/null +++ b/include/mementar/API/ActionsPublisher.h @@ -0,0 +1,28 @@ +#ifndef MEMENTAR_API_ACTIONSPUBLISHER_H +#define MEMENTAR_API_ACTIONSPUBLISHER_H + +#include + +#include + +namespace mementar +{ + +class ActionsPublisher +{ +public: + ActionsPublisher(ros::NodeHandle* n, const std::string& name = ""); + + void insert(const std::string& name, time_t start_stamp = time(0), time_t end_stamp = 0); + void insertEnd(const std::string& name, time_t end_stamp = time(0)); + +private: + ros::NodeHandle* n_; + ros::Publisher pub_; + + void publish(const std::string& name, time_t start_stamp, time_t end_stamp); +}; + +} // namespace mementar + +#endif // MEMENTAR_API_ACTIONSPUBLISHER_H diff --git a/include/mementar/API/ActionsSubscriber.h b/include/mementar/API/ActionsSubscriber.h new file mode 100644 index 0000000..99dbf88 --- /dev/null +++ b/include/mementar/API/ActionsSubscriber.h @@ -0,0 +1,40 @@ +#ifndef MEMENTAR_API_ACTIONSSUBSCRIBER_H +#define MEMENTAR_API_ACTIONSSUBSCRIBER_H + +#include +#include +#include +#include + +#include +#include + +#include "mementar/MementarOccasion.h" +#include "mementar/API/Fact.h" +#include "mementar/API/OccasionsSubscriber.h" + +namespace mementar +{ + +class ActionsSubscriber : private OccasionsSubscriber +{ +public: + ActionsSubscriber(std::function callback, const std::string& name = "", bool spin_thread = true); + ActionsSubscriber(std::function callback, bool spin_thread); + ~ActionsSubscriber(); + + bool subscribeToStart(const std::string& name, size_t count = -1); + bool subscribeToEnd(const std::string& name, size_t count = -1); + bool cancel(); + + bool end() { return OccasionsSubscriber::end(); } + +private: + std::function callback_; + + void privateCallback(const Fact& fact); +}; + +} // namespace mementar + +#endif // MEMENTAR_API_ACTIONSSUBSCRIBER_H diff --git a/include/mementar/API/Fact.h b/include/mementar/API/Fact.h index 53fcf1d..18dc1f5 100644 --- a/include/mementar/API/Fact.h +++ b/include/mementar/API/Fact.h @@ -3,6 +3,7 @@ #include #include +#include namespace mementar { @@ -10,33 +11,50 @@ namespace mementar class Fact { public: - Fact(const std::string& fact) + Fact(const std::string& fact, bool add = true) { - std::vector splitted = split(fact, "|"); - if(splitted.size() >= 1) - subject_ = splitted[0]; - if(splitted.size() >= 2) - predicat_ = splitted[1]; - if(splitted.size() >= 3) - object_ = splitted[2]; + std::smatch match; + std::regex regex("\\[(\\w+)\\]([^|]+)\\|([^|]+)\\|([^|]+)"); + if(std::regex_match(fact, match, regex)) + { + subject_ = match[2].str(); + predicat_ = match[3].str(); + object_ = match[4].str(); + add_ = (match[1].str() == "ADD") || (match[1].str() == "add"); + } + else + { + std::vector splitted = split(fact, "|"); + if(splitted.size() >= 1) + subject_ = splitted[0]; + if(splitted.size() >= 2) + predicat_ = splitted[1]; + if(splitted.size() >= 3) + object_ = splitted[2]; + add_ = add; + } } - Fact(const std::string& subject, const std::string& predicat, const std::string& object) + Fact(const std::string& subject, const std::string& predicat, const std::string& object, bool add = true) { subject_ = subject; predicat_ = predicat; object_ = object; + add_ = true; } - std::string subject() const { return subject_; } - std::string predicat() const { return predicat_; } - std::string object() const { return object_; } - std::string operator()() const {return subject_ + "|" + predicat_ + "|" + object_; } + std::string getSubject() const { return subject_; } + std::string getPredicat() const { return predicat_; } + std::string getObject() const { return object_; } + bool getAdd() const { return add_; } + std::string operator()() const { return (add_ ? "[add]" : "[del]") + subject_ + "|" + predicat_ + "|" + object_; } + std::string to_string() const { return (add_ ? "[add]" : "[del]") + subject_ + "|" + predicat_ + "|" + object_; } - void subject(const std::string& subject) { subject_ = subject; } - void predicat(const std::string& predicat) { predicat_ = predicat; } - void object(const std::string& object) { object_ = object; } - void operator()(const std::string& fact) + void setSubject(const std::string& subject) { subject_ = subject; } + void setPredicat(const std::string& predicat) { predicat_ = predicat; } + void setObject(const std::string& object) { object_ = object; } + void setAdd(bool add) { add_ = add; } + void operator()(const std::string& fact, bool add = true) { std::vector splitted = split(fact, "|"); if(splitted.size() >= 1) @@ -45,12 +63,14 @@ class Fact predicat_ = splitted[1]; if(splitted.size() >= 3) object_ = splitted[2]; + add_ = add; } private: std::string subject_; std::string predicat_; std::string object_; + bool add_; std::vector split(const std::string& str, const std::string& delim) { diff --git a/include/mementar/API/OccasionsPublisher.h b/include/mementar/API/OccasionsPublisher.h index 7ea83d4..58b53e4 100644 --- a/include/mementar/API/OccasionsPublisher.h +++ b/include/mementar/API/OccasionsPublisher.h @@ -15,13 +15,13 @@ class OccasionsPublisher public: OccasionsPublisher(ros::NodeHandle* n, const std::string& name = ""); - void insert(const Fact& fact, time_t stamp = 0); + void insert(const Fact& fact, time_t stamp = time(0)); private: ros::NodeHandle* n_; ros::Publisher pub_; - void publish(const std::string& str, time_t stamp = 0); + void publish(const std::string& str, time_t stamp = time(0)); }; } // namespace mementar diff --git a/include/mementar/API/OccasionsSubscriber.h b/include/mementar/API/OccasionsSubscriber.h index d3a284a..fc494d0 100644 --- a/include/mementar/API/OccasionsSubscriber.h +++ b/include/mementar/API/OccasionsSubscriber.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -20,7 +20,7 @@ class OccasionsSubscriber public: OccasionsSubscriber(std::function callback, const std::string& name = "", bool spin_thread = true); OccasionsSubscriber(std::function callback, bool spin_thread); - ~OccasionsSubscriber(); + virtual ~OccasionsSubscriber(); bool subscribe(const Fact& pattern, size_t count = -1); bool cancel(); @@ -28,15 +28,14 @@ class OccasionsSubscriber bool end() { return ids_.size() == 0; } private: - ros::NodeHandle n_; ros::Subscriber sub_; ros::ServiceClient client_subscribe_; ros::ServiceClient client_cancel_; - std::mutex terminate_mutex_; - bool need_to_terminate_; + std::atomic need_to_terminate_; std::thread* spin_thread_; ros::CallbackQueue callback_queue_; + ros::NodeHandle n_; std::vector ids_; diff --git a/include/mementar/API/TimelineManipulator.h b/include/mementar/API/TimelineManipulator.h index 4199244..b508484 100644 --- a/include/mementar/API/TimelineManipulator.h +++ b/include/mementar/API/TimelineManipulator.h @@ -5,13 +5,14 @@ #include +#include "mementar/API/ActionsPublisher.h" #include "mementar/API/OccasionsPublisher.h" #include "mementar/API/clients/ClientBase.h" namespace mementar { -class TimelineManipulator : public OccasionsPublisher +class TimelineManipulator { public: TimelineManipulator(ros::NodeHandle* n, const std::string& name = ""); @@ -23,6 +24,9 @@ class TimelineManipulator : public OccasionsPublisher void verbose(bool verbose) { ClientBase::verbose(verbose); } + OccasionsPublisher fact_feeder; + ActionsPublisher action_feeder; + private: ros::NodeHandle* n_; std::string name_; diff --git a/include/mementar/RosInterface.h b/include/mementar/RosInterface.h index 70f6f56..9776dde 100644 --- a/include/mementar/RosInterface.h +++ b/include/mementar/RosInterface.h @@ -7,46 +7,86 @@ #include #include "std_msgs/String.h" +#include "ontologenius/OntologyManipulator.h" + +#include "mementar/MementarAction.h" +#include "mementar/MementarExplanation.h" #include "mementar/MementarService.h" #include "mementar/StampedString.h" -#include "mementar/core/LtManagement/EpisodicTree/ArchivedLeafNode.h" +//#include "mementar/core/LtManagement/EpisodicTree/ArchivedLeafNode.h" +#include "mementar/core/feeder/Feeder.h" +#include "mementar/core/memGraphs/Timeline.h" #include "mementar/core/Occasions/OccasionsManager.h" +#include "mementar/core/Parametrization/Configuration.h" namespace mementar { +struct param_t +{ + std::string base; + + std::string operator()() { return base; } +}; + class RosInterface { public: - RosInterface(ros::NodeHandle* n, const std::string& directory, size_t order = 10, std::string name = ""); + RosInterface(ros::NodeHandle* n, const std::string& directory, const std::string& configuration_file, size_t order = 10, std::string name = ""); ~RosInterface(); void run(); void stop() {run_ = false; } - inline bool isRunning() {return run_; } - ArchivedLeafNode* getTree() {return tree_; } + inline bool isRunning() { return run_; } + + void lock(); + void release(); private: ros::NodeHandle* n_; std::string directory_; + Configuration configuration_; size_t order_; - ArchivedLeafNode* tree_; + OntologyManipulator onto_; + + Timeline* timeline_; + Feeder feeder_; OccasionsManager occasions_; std::string name_; std::atomic run_; std::shared_timed_mutex mut_; + std::mutex feeder_mutex_; void reset(); void knowledgeCallback(const std_msgs::String::ConstPtr& msg); void stampedKnowledgeCallback(const StampedString::ConstPtr& msg); + void explanationKnowledgeCallback(const MementarExplanation::ConstPtr& msg); + void actionKnowledgeCallback(const MementarAction::ConstPtr& msg); + + bool managerInstanceHandle(mementar::MementarService::Request &req, + mementar::MementarService::Response &res); + bool actionHandle(mementar::MementarService::Request &req, + mementar::MementarService::Response &res); - bool actionsHandle(mementar::MementarService::Request &req, - mementar::MementarService::Response &res); + void feedThread(); void removeUselessSpace(std::string& text); + void set2string(const std::unordered_set& word_set, std::string& result); + void set2vector(const std::unordered_set& word_set, std::vector& result); + param_t getParams(const std::string& param); + + std::string getTopicName(const std::string& topic_name) + { + return getTopicName(topic_name, name_); + } + + std::string getTopicName(const std::string& topic_name, const std::string& onto_name) + { + return (onto_name == "") ? "/mementar/" + topic_name : "/mementar/" + topic_name + "/" + onto_name; + } }; } // namespace mementar diff --git a/include/mementar/core/LtManagement/EpisodicTree/ArchivedLeaf.h b/include/mementar/core/LtManagement/EpisodicTree/ArchivedLeaf.h index ff15b06..9fdf421 100644 --- a/include/mementar/core/LtManagement/EpisodicTree/ArchivedLeaf.h +++ b/include/mementar/core/LtManagement/EpisodicTree/ArchivedLeaf.h @@ -18,7 +18,7 @@ class ArchivedLeaf std::string getDirectory() { return directory_; } time_t getKey() { return key_; } - Btree* getTree(size_t i); + BplusTree* getTree(size_t i); std::vector getContexts(); private: diff --git a/include/mementar/core/LtManagement/EpisodicTree/ArchivedLeafNode.h b/include/mementar/core/LtManagement/EpisodicTree/ArchivedLeafNode.h index 9f7c7d2..6668d73 100644 --- a/include/mementar/core/LtManagement/EpisodicTree/ArchivedLeafNode.h +++ b/include/mementar/core/LtManagement/EpisodicTree/ArchivedLeafNode.h @@ -10,16 +10,17 @@ namespace mementar class ArchivedLeafNode { + using LeafType = typename BplusLeaf::LeafType; public: ArchivedLeafNode(const std::string& directory, size_t order = 10); ~ArchivedLeafNode(); - void insert(Event* data); - void remove(Event* data); - BtreeLeaf* find(const time_t& key); - BtreeLeaf* findNear(const time_t& key); - BtreeLeaf* getFirst(); - BtreeLeaf* getLast(); + void insert(Fact* data); + void remove(Fact* data); + LeafType* find(const time_t& key); + LeafType* findNear(const time_t& key); + LeafType* getFirst(); + LeafType* getLast(); void display(time_t key); diff --git a/include/mementar/core/LtManagement/EpisodicTree/CompressedLeaf.h b/include/mementar/core/LtManagement/EpisodicTree/CompressedLeaf.h index df3212d..0e11d85 100644 --- a/include/mementar/core/LtManagement/EpisodicTree/CompressedLeaf.h +++ b/include/mementar/core/LtManagement/EpisodicTree/CompressedLeaf.h @@ -4,8 +4,8 @@ #include #include -#include "mementar/core/memGraphs/Btree/Btree.h" -#include "mementar/core/memGraphs/Branchs/types/Event.h" +#include "mementar/core/memGraphs/Btree/BplusTree.h" +#include "mementar/core/memGraphs/Branchs/types/Fact.h" namespace mementar { @@ -13,18 +13,18 @@ namespace mementar class CompressedLeaf { public: - CompressedLeaf(Btree* tree, const std::string& directory); + CompressedLeaf(BplusTree* tree, const std::string& directory); CompressedLeaf(const time_t& key, const std::string& directory); std::string getDirectory() { return directory_; } time_t getKey() { return key_; } - Btree* getTree(); + BplusTree* getTree(); private: time_t key_; std::string directory_; - std::string treeToString(Btree* tree); + std::string treeToString(BplusTree* tree); }; } // namespace mementar diff --git a/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafNode.h b/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafNode.h index 1fd8760..14259e9 100644 --- a/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafNode.h +++ b/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafNode.h @@ -6,8 +6,8 @@ #include #include -#include "mementar/core/memGraphs/Branchs/types/Event.h" -#include "mementar/core/memGraphs/Btree/Btree.h" +#include "mementar/core/memGraphs/Branchs/types/Fact.h" +#include "mementar/core/memGraphs/Btree/BplusTree.h" #include "mementar/core/LtManagement/EpisodicTree/CompressedLeaf.h" #include "mementar/core/LtManagement/EpisodicTree/Context.h" @@ -19,18 +19,19 @@ class ArchivedLeaf; class CompressedLeafNode { friend ArchivedLeaf; + using LeafType = typename BplusLeaf::LeafType; public: - CompressedLeafNode(std::string directory, size_t order = 10); + CompressedLeafNode(const std::string& directory); ~CompressedLeafNode(); CompressedLeafNode* split(); - void insert(Event* data); - void remove(Event* data); - BtreeLeaf* find(const time_t& key); - BtreeLeaf* findNear(const time_t& key); - BtreeLeaf* getFirst(); - BtreeLeaf* getLast(); + void insert(Fact* data); + void remove(Fact* data); + LeafType* find(const time_t& key); + LeafType* findNear(const time_t& key); + LeafType* getFirst(); + LeafType* getLast(); void display(time_t key); size_t size() { return keys_.size(); } @@ -51,16 +52,15 @@ class CompressedLeafNode void init(); std::string directory_; - size_t order_; mutable std::shared_timed_mutex mut_; // keys_.size() == btree_childs_.size() + compressed_childs_.size() // keys_[i] correspond to the first key of child i std::vector keys_; std::vector contexts_; - std::vector*> btree_childs_; + std::vector*> btree_childs_; std::vector compressed_childs_; - std::vector*> compressed_sessions_tree_; + std::vector*> compressed_sessions_tree_; std::vector compressed_sessions_timeout_; //ms std::vector modified_; diff --git a/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafNodeSession.h b/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafNodeSession.h index be95d5a..e8b44bc 100644 --- a/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafNodeSession.h +++ b/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafNodeSession.h @@ -6,8 +6,8 @@ #include #include -#include "mementar/core/memGraphs/Branchs/types/Event.h" -#include "mementar/core/memGraphs/Btree/Btree.h" +#include "mementar/core/memGraphs/Branchs/types/Fact.h" +#include "mementar/core/memGraphs/Btree/BplusTree.h" #include "mementar/core/LtManagement/EpisodicTree/CompressedLeafSession.h" #include "mementar/core/LtManagement/EpisodicTree/Context.h" @@ -19,16 +19,17 @@ namespace mementar class CompressedLeafNodeSession { + using LeafType = typename BplusLeaf::LeafType; public: CompressedLeafNodeSession(const std::string& file_name); ~CompressedLeafNodeSession(); - void insert(Event* data); - bool remove(Event* data); - BtreeLeaf* find(const time_t& key); - BtreeLeaf* findNear(const time_t& key); - BtreeLeaf* getFirst(); - BtreeLeaf* getLast(); + void insert(Fact* data); + bool remove(Fact* data); + LeafType* find(const time_t& key); + LeafType* findNear(const time_t& key); + LeafType* getFirst(); + LeafType* getLast(); time_t getKey() { @@ -49,7 +50,7 @@ class CompressedLeafNodeSession // keys_[i] correspond to the first key of child i std::vector contexts_; std::vector childs_; - std::vector*> sessions_tree_; + std::vector*> sessions_tree_; std::vector modified_; time_t earlier_key_; diff --git a/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafSession.h b/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafSession.h index 66c921b..e80b8bd 100644 --- a/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafSession.h +++ b/include/mementar/core/LtManagement/EpisodicTree/CompressedLeafSession.h @@ -4,8 +4,8 @@ #include "mementar/core/LtManagement/archiving_compressing/archiving/Archive.h" #include "mementar/core/LtManagement/archiving_compressing/archiving/Header.h" -#include "mementar/core/memGraphs/Btree/Btree.h" -#include "mementar/core/memGraphs/Branchs/types/Event.h" +#include "mementar/core/memGraphs/Btree/BplusTree.h" +#include "mementar/core/memGraphs/Branchs/types/Fact.h" namespace mementar { @@ -18,7 +18,7 @@ class CompressedLeafSession time_t getKey() { return key_; } size_t getIndex() { return index_; } - Btree* getTree(Header& header, Archive& arch); + BplusTree* getTree(Header& header, Archive& arch); std::vector getRawData(Header& header, Archive& arch); private: time_t key_; diff --git a/include/mementar/core/LtManagement/EpisodicTree/Context.h b/include/mementar/core/LtManagement/EpisodicTree/Context.h index 96b711f..ee108b2 100644 --- a/include/mementar/core/LtManagement/EpisodicTree/Context.h +++ b/include/mementar/core/LtManagement/EpisodicTree/Context.h @@ -5,7 +5,7 @@ #include #include -#include "mementar/core/memGraphs/Branchs/types/Fact.h" +#include "mementar/core/memGraphs/Branchs/types/Triplet.h" namespace mementar { @@ -15,8 +15,8 @@ class Context public: Context(time_t key) { key_ = key; } - void insert(const Fact* fact); - void remove(const Fact* fact); + void insert(const Triplet* triplet); + void remove(const Triplet* triplet); bool exist(const std::string& name); bool subjectExist(const std::string& subject); diff --git a/include/mementar/core/Occasions/OccasionsManager.h b/include/mementar/core/Occasions/OccasionsManager.h index ef0b962..894128c 100644 --- a/include/mementar/core/Occasions/OccasionsManager.h +++ b/include/mementar/core/Occasions/OccasionsManager.h @@ -7,11 +7,13 @@ #include +#include "ontologenius/OntologyManipulator.h" + #include "mementar/MementarOccasionSubscription.h" #include "mementar/MementarOcassionUnsubscription.h" #include "mementar/core/Occasions/Subscription.h" -#include "mementar/core/memGraphs/Branchs/types/Fact.h" +#include "mementar/core/memGraphs/Branchs/types/Triplet.h" namespace mementar { @@ -20,16 +22,18 @@ class OccasionsManager { public: OccasionsManager(ros::NodeHandle* n, std::string name = ""); + OccasionsManager(ros::NodeHandle* n, OntologyManipulator* onto, std::string name = ""); void run(); - void add(const Fact* fact); + void add(const Triplet& triplet); void stop() {run_ = false; } inline bool isRunning() {return run_; } private: ros::NodeHandle* n_; + OntologyManipulator* onto_; Subscription subscription_; std::atomic run_; @@ -40,15 +44,15 @@ class OccasionsManager std::mutex mutex_; bool queue_choice_; - std::queue fifo_1; - std::queue fifo_2; + std::queue fifo_1; + std::queue fifo_2; bool SubscribeCallback(mementar::MementarOccasionSubscription::Request &req, mementar::MementarOccasionSubscription::Response &res); bool UnsubscribeCallback(mementar::MementarOcassionUnsubscription::Request &req, mementar::MementarOcassionUnsubscription::Response &res); - const Fact* get(); + Triplet get(); bool empty(); }; diff --git a/include/mementar/core/Occasions/Subscription.h b/include/mementar/core/Occasions/Subscription.h index 57609cb..24d4efd 100644 --- a/include/mementar/core/Occasions/Subscription.h +++ b/include/mementar/core/Occasions/Subscription.h @@ -5,7 +5,9 @@ #include #include -#include "mementar/core/memGraphs/Branchs/types/Fact.h" +#include "ontologenius/OntologyManipulator.h" + +#include "mementar/core/memGraphs/Branchs/types/TripletPattern.h" #include "mementar/core/Occasions/IdManager.h" namespace mementar @@ -14,20 +16,27 @@ namespace mementar class Subscription { public: - size_t subscribe(const Fact& patern, size_t count); + Subscription(OntologyManipulator* onto = nullptr) { onto_ = onto; } + + size_t subscribe(const Triplet& patern, size_t count); bool unsubscribe(size_t id); bool isFinished(size_t id); - bool empty() { return fact_paterns_.size() == 0; } + bool empty() { return triplet_paterns_.size() == 0; } - std::vector evaluate(const Fact* fact); + std::vector evaluate(const Triplet& triplet); private: - std::map fact_paterns_; + std::map triplet_paterns_; std::map counts_; std::mutex map_mut_; IdManager id_manager_; + + OntologyManipulator* onto_; + + TripletPattern getPattern(const Triplet& triplet); + bool compareToTriplet(const TripletPattern& pattern, const Triplet& triplet); }; } // namespace mementar diff --git a/include/mementar/core/Parametrization/Configuration.h b/include/mementar/core/Parametrization/Configuration.h new file mode 100644 index 0000000..34f0987 --- /dev/null +++ b/include/mementar/core/Parametrization/Configuration.h @@ -0,0 +1,80 @@ +#ifndef MEMENTAR_CONFIGURATION_H +#define MEMENTAR_CONFIGURATION_H + +#include +#include +#include +#include + +namespace mementar +{ + +class ConfigElement +{ +public: + std::experimental::optional> data; + std::experimental::optional> subelem; + + ConfigElement operator[](const std::string& name) + { + if(subelem) + return subelem.value()[name]; + else + return ConfigElement(); + } + + bool exist(const std::string& name) + { + if(subelem) + return (subelem.value().find(name) != subelem.value().end()); + else + return false; + } + + std::vector value() + { + if(data) + return data.value(); + else + return {}; + } + + void push_back(const std::string& value) + { + data.value().push_back(value); + } +}; + +class Configuration +{ +public: + std::map config_; + + bool read(const std::string& path); + bool write(const std::string& path); + + void display(); + + ConfigElement& operator[](const std::string& name) + { + return config_[name]; + } + + bool exist(const std::string& name) + { + return (config_.find(name) != config_.end()); + } + +private: + void display(std::map& config, size_t nb = 0); + void displayTab(size_t nb); + + std::string getConfig(std::map& config, size_t nb = 0); + std::string getTabs(size_t nb); + + void removeComment(std::string& line); +}; + +} // namespace mementar + +#endif // MEMENTAR_CONFIGURATION_H diff --git a/include/mementar/core/Parametrization/Parameters.h b/include/mementar/core/Parametrization/Parameters.h new file mode 100644 index 0000000..ab4dc01 --- /dev/null +++ b/include/mementar/core/Parametrization/Parameters.h @@ -0,0 +1,154 @@ +#ifndef MEMENTAR_PARAMETERS_H +#define MEMENTAR_PARAMETERS_H + +#include +#include +#include +#include + +#include "mementar/graphical/Display.h" + +namespace mementar +{ + +class Parameter +{ +public: + std::string name_; + std::vector options_; + std::vector values_; + std::vector default_values_; + + Parameter(const std::string& name, const std::vector& options, const std::vector& default_values = {}) + { + name_ = name; + options_ = options; + default_values_ = default_values; + } + + Parameter(const Parameter& other) + { + name_ = other.name_; + options_ = other.options_; + values_ = other.values_; + default_values_ = other.default_values_; + } + + void insert(const std::string& value) { values_.push_back(value); } + + std::string getFirst() + { + if(values_.size() == 0) + return (default_values_.size() ? default_values_[0] : ""); + else + return (values_.size() ? values_[0] : ""); + } + + std::vector get() + { + if(values_.size() == 0) + return default_values_; + else + return values_; + } + + bool testOption(const std::string& option) + { + for(auto op : options_) + if(option == op) + return true; + return false; + } + + void display() + { + Display::info(name_ + ":"); + + if(values_.size()) + { + for(auto value : values_) + Display::info("\t- " + value); + } + else + { + for(auto value : default_values_) + Display::info("\t- " + value); + } + } +}; + +class Parameters +{ +public: + std::map parameters_; +private: + std::string default_param_name_; + std::string process_name_; + +public: + + void insert(const Parameter& param) + { + parameters_.insert(std::pair(param.name_,param)); + if(param.options_.size() == 0) + default_param_name_ = param.name_; + } + + void set(int argc, char** argv) + { + process_name_ = std::string(argv[0]); + size_t pose; + while ((pose = process_name_.find("/")) != std::string::npos) { + process_name_ = process_name_.substr(pose+1); + } + process_name_ = " " + process_name_ + " "; + + for(size_t i = 1; i < (size_t)argc; i++) + { + if(argv[i][0] == '-') + { + std::string param_name = ""; + for(auto param : parameters_) + if(param.second.testOption(std::string(argv[i]))) + { + param_name = param.second.name_; + break; + } + + if(param_name == "") + Display::warning("unknow option " + std::string(argv[i])); + else + { + if(i+1 < (size_t)argc) + { + i++; + parameters_.at(param_name).insert(std::string(argv[i])); + } + } + } + else + { + if(default_param_name_ != "") + parameters_.at(default_param_name_).insert(std::string(argv[i])); + else + Display::warning("No default parameter"); + } + } + } + + void display() + { + std::string delim = "****************"; + std::string delim_gap; + for(size_t i = 0; i < process_name_.size(); i++) + delim_gap += "*"; + Display::info(delim + process_name_ + delim); + for(auto param : parameters_) + param.second.display(); + Display::info(delim + delim_gap + delim); + } +}; + +} // namespace mementar + +#endif // MEMENTAR_PARAMETERS_H diff --git a/include/mementar/core/feeder/DoubleQueue.h b/include/mementar/core/feeder/DoubleQueue.h new file mode 100644 index 0000000..2a99d31 --- /dev/null +++ b/include/mementar/core/feeder/DoubleQueue.h @@ -0,0 +1,83 @@ +#ifndef MEMENTAR_DOUBLEQUEUE_H +#define MEMENTAR_DOUBLEQUEUE_H + +#include +#include + +namespace mementar +{ + +template +class DoubleQueue +{ +public: + DoubleQueue() + { + queue_choice_ = true; + } + + void insert(T& data) + { + mutex_.lock(); + if(queue_choice_ == true) + fifo_1.push(data); + else + fifo_2.push(data); + + mutex_.unlock(); + } + + void insert(std::vector& datas) + { + mutex_.lock(); + if(queue_choice_ == true) + { + for(auto& data : datas) + fifo_1.push(data); + } + else + { + for(auto& data : datas) + fifo_2.push(data); + } + mutex_.unlock(); + } + + std::queue get() + { + std::queue tmp; + mutex_.lock(); + if(queue_choice_ == true) + { + while(!fifo_2.empty()) + fifo_2.pop(); + queue_choice_ = false; + tmp = fifo_1; + } + else + { + while(!fifo_1.empty()) + fifo_1.pop(); + queue_choice_ = true; + tmp = fifo_2; + } + mutex_.unlock(); + return tmp; + } + + size_t size() + { + return fifo_1.size() + fifo_2.size(); + } + +private: + std::mutex mutex_; + + bool queue_choice_; + std::queue fifo_1; + std::queue fifo_2; +}; + +} // namespace mementar + +#endif // MEMENTAR_DOUBLEQUEUE_H diff --git a/include/mementar/core/feeder/FeedStorage.h b/include/mementar/core/feeder/FeedStorage.h new file mode 100644 index 0000000..e126440 --- /dev/null +++ b/include/mementar/core/feeder/FeedStorage.h @@ -0,0 +1,79 @@ +#ifndef MEMENTER_FEEDSTORAGE_H +#define MEMENTER_FEEDSTORAGE_H + +#include +#include +#include + +#include "mementar/core/feeder/DoubleQueue.h" +#include "mementar/core/memGraphs/Branchs/types/Fact.h" + +namespace mementar { + +enum feed_commande_t +{ + cmd_add, + cmd_del, + cmd_commit, + cmd_checkout, + cmd_nop +}; + +struct feed_fact_t +{ + feed_commande_t cmd_; + std::experimental::optional fact_; + std::vector expl_; + bool checkout_; + + feed_fact_t() { checkout_ = false; } +}; + +struct feed_action_t +{ + std::string name_; + SoftPoint::Ttime t_start_; + SoftPoint::Ttime t_end_; + bool checkout_; + + feed_action_t() + { + t_start_ = SoftPoint::default_time; + t_end_ = SoftPoint::default_time; + checkout_ = false; + } +}; + +class FeedStorage +{ +public: + FeedStorage(); + + void insertFact(const std::string& regex, const SoftPoint::Ttime& stamp); + void insertFact(const std::string& regex, const std::string& expl_regex); + void insertFacts(std::vector& datas); + void insertAction(const std::string& name, const SoftPoint::Ttime& start_stamp, const SoftPoint::Ttime& end_stamp); + void insertActions(std::vector& datas); + + std::queue getFacts(); + std::queue getActions(); + + size_t size() + { + std::cout << fact_queue_.size() << " : " << action_queue_.size() << std::endl; + return fact_queue_.size() + action_queue_.size(); + } + +private: + std::regex base_regex; + + DoubleQueue fact_queue_; + DoubleQueue action_queue_; + + feed_fact_t getFeedFact(const std::string& regex, const SoftPoint::Ttime& stamp = SoftPoint::default_time); + std::vector split(const std::string& str, const std::string& delim); +}; + +} // namespace mementar + +#endif // MEMENTER_FEEDSTORAGE_H diff --git a/include/mementar/core/feeder/Feeder.h b/include/mementar/core/feeder/Feeder.h new file mode 100644 index 0000000..65d6cb6 --- /dev/null +++ b/include/mementar/core/feeder/Feeder.h @@ -0,0 +1,69 @@ +#ifndef MEMENTAR_FEEDER_H +#define MEMENTAR_FEEDER_H + +#include "mementar/core/feeder/FeedStorage.h" +#include "mementar/core/feeder/IdGenerator.h" +//#include "ontologenius/core/feeder/Versionor.h" + +#include "ontologenius/OntologyManipulator.h" + +#include +#include + +namespace mementar { + +class Timeline; + +class Feeder +{ +public: + Feeder(OntologyManipulator* onto, Timeline* timeline = nullptr); + Feeder(Timeline* timeline = nullptr); + + void storeFact(const std::string& feed, const SoftPoint::Ttime& stamp) { feed_storage_.insertFact(feed, stamp); } + void storeFact(const std::string& feed, const std::string& expl) { feed_storage_.insertFact(feed, expl); } + void storeAction(const std::string& name, const SoftPoint::Ttime& start_stamp, const SoftPoint::Ttime& end_stamp) { feed_storage_.insertAction(name, start_stamp, end_stamp); } + bool run(); + void link(Timeline* timeline) {timeline_ = timeline; } + void setCallback(const std::function& callback) { callback_ = callback; } + + bool setWhitelist(std::vector list); + bool setBlacklist(std::vector list); + + std::vector getNotifications() + { + auto tmp = std::move(notifications_); + notifications_.clear(); + return tmp; + } + + //void activateVersionning(bool activated) { versionor_.activate(activated); } + //void exportToXml(const std::string& path) { versionor_.exportToXml(path); } + + size_t size() { return feed_storage_.size(); } + +private: + FeedStorage feed_storage_; + IdGenerator id_generator_; + //Versionor versionor_; + Timeline* timeline_; + OntologyManipulator* onto_; + std::function callback_; + + std::experimental::optional is_whitelist_; + std::unordered_set list_; + + // Here the notifications are about miss formed queries + std::vector notifications_; + + bool runForFacts(); + bool runForActions(); + + void setList(const std::vector& base_list); + + void defaultCallback(const Triplet&) {} +}; + +} // namespace mementar + +#endif // MEMENTAR_FEEDER_H diff --git a/include/mementar/core/feeder/IdGenerator.h b/include/mementar/core/feeder/IdGenerator.h new file mode 100644 index 0000000..9e6a93c --- /dev/null +++ b/include/mementar/core/feeder/IdGenerator.h @@ -0,0 +1,39 @@ +#ifndef MEMENTAR_IDGENERATOR_H +#define MEMENTAR_IDGENERATOR_H + +#include +#include + +namespace mementar { + +class IdGenerator +{ +public: + IdGenerator() { id_ = 0; } + + void inspect(const std::string& str_id) + { + std::stringstream convertor; + size_t id; + convertor << str_id; + convertor >> id; + + if(convertor.fail() == false) + { + if(id >= id_) + id_ = id + 1; + } + } + + std::string get() + { + return std::to_string(id_++); + } + +private: + size_t id_; +}; + +} // namespace mementar + +#endif // MEMENTAR_IDGENERATOR_H diff --git a/include/mementar/core/memGraphs/Branchs/ContextualizedEvent.h b/include/mementar/core/memGraphs/Branchs/ContextualizedEvent.h deleted file mode 100644 index 220ddb4..0000000 --- a/include/mementar/core/memGraphs/Branchs/ContextualizedEvent.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef MEMENTAR_CONTEXTUALIZEDEVENT_H -#define MEMENTAR_CONTEXTUALIZEDEVENT_H - -#include "mementar/core/memGraphs/Branchs/types/Event.h" -#include "mementar/core/memGraphs/Branchs/types/Action.h" -#include "mementar/core/memGraphs/Branchs/ValuedNode.h" - -#include "mementar/core/memGraphs/DoublyLinkedList/DllLinkedElement.h" -#include "mementar/core/memGraphs/EventLinkedList/EllElement.h" - -#include - -namespace mementar { - -class ContextualizedEvent : public Event, public ValuedNode, public EllElement -{ -public: - ContextualizedEvent(const std::string& id, const Event& other, Action* action = nullptr) : Event(other), ValuedNode(id) - { - action_ = action; - } - - ContextualizedEvent(const std::string& id, const std::string& data, const SoftPoint& soft_point, Action* action = nullptr) : Event(data, soft_point), ValuedNode(id) - { - action_ = action; - } - - virtual ~ContextualizedEvent() {} - - std::string getId() { return getValue(); } - - bool isPartOfAction() { return action_ != nullptr; } - Action* getActionPart() { return action_; } - - std::string toString() { return getValue() + " " + SoftPoint::toString() + " : " + getData() + std::string(action_ ? " => part of action " + action_->getName() : ""); } - - virtual void print(std::ostream& os) const - { - os << getValue(); - } - -private: - Action* action_; - - bool operator==(const DllLinkedElement* other) - { - return this->Event::operator==(static_cast(other)); - } - - virtual bool isEventPart(const DllLinkedElement* other) - { - return ( (subject_ == static_cast(other)->subject_) && - (predicat_ == static_cast(other)->predicat_)); - } -}; - -} // namespace mementar - -#endif // MEMENTAR_CONTEXTUALIZEDEVENT_H diff --git a/include/mementar/core/memGraphs/Branchs/ContextualizedFact.h b/include/mementar/core/memGraphs/Branchs/ContextualizedFact.h new file mode 100644 index 0000000..091fe74 --- /dev/null +++ b/include/mementar/core/memGraphs/Branchs/ContextualizedFact.h @@ -0,0 +1,81 @@ +#ifndef MEMENTAR_CONTEXTUALIZEDFACT_H +#define MEMENTAR_CONTEXTUALIZEDFACT_H + +#include "mementar/core/memGraphs/Branchs/types/Fact.h" +#include "mementar/core/memGraphs/Branchs/types/Action.h" +#include "mementar/core/memGraphs/Branchs/ValuedNode.h" + +#include "mementar/core/memGraphs/ExtendedBtree/EventLinkedLeaf.h" + +#include + +namespace mementar { + +class ContextualizedFact : public Fact, public ValuedNode, public LinkedEvent, ContextualizedFact> +{ +public: + using LeafType = EventLinkedLeaf; + + ContextualizedFact(const std::string& id, const Fact& other, Action* action = nullptr) : Fact(other), ValuedNode(id) + { + action_ = action; + } + + ContextualizedFact(const std::string& id, const std::string& data, const SoftPoint& soft_point, Action* action = nullptr) : Fact(data, soft_point), ValuedNode(id) + { + action_ = action; + } + + virtual ~ContextualizedFact() {} + + std::string getId() const { return getValue(); } + + bool isPartOfAction() const { return action_ != nullptr; } + Action* getActionPart() { return action_; } + + std::string toString() const { return getValue() + " " + SoftPoint::toString() + " : " + getData() + std::string(action_ ? " => part of action " + action_->getName() : ""); } + + bool operator==(const ContextualizedFact& other) + { + return this->Fact::operator==(other); + } + + bool isPartOf(const ContextualizedFact& other) + { + return ( (subject_ == other.subject_) && + (predicat_ == other.predicat_) ); + } + + friend std::ostream& operator<<(std::ostream& os, const ContextualizedFact& ctx_fact) + { + os << ctx_fact.toString(); + return os; + } + + std::vector getNextData() + { + std::vector res; + auto next_leaf = getNextLeaf(); + if(next_leaf != nullptr) + res = next_leaf->getData(); + + return res; + } + + std::vector getPreviousData() + { + std::vector res; + auto prev_leaf = getPreviousLeaf(); + if(prev_leaf != nullptr) + res = prev_leaf->getData(); + + return res; + } + +private: + Action* action_; +}; + +} // namespace mementar + +#endif // MEMENTAR_CONTEXTUALIZEDFACT_H diff --git a/include/mementar/core/memGraphs/Branchs/types/Action.h b/include/mementar/core/memGraphs/Branchs/types/Action.h index 4da4167..8856d1f 100644 --- a/include/mementar/core/memGraphs/Branchs/types/Action.h +++ b/include/mementar/core/memGraphs/Branchs/types/Action.h @@ -8,13 +8,15 @@ namespace mementar { -class ContextualizedEvent; +class ContextualizedFact; class Action : public ValuedNode { public: - Action(const std::string& name, const SoftPoint& start, const std::experimental::optional& end = std::experimental::nullopt); - Action(const std::string& name, const SoftPoint& start, const SoftPoint::Ttime& end); + Action(const std::string& name, const SoftPoint& start); + Action(const std::string& name, const SoftPoint& start, const SoftPoint& end); + + Action(const Action& other) = delete; bool setEnd(const SoftPoint& end); @@ -25,14 +27,14 @@ class Action : public ValuedNode size_t getMaxDuration(); bool isSoft(); - bool isPending() { return !end_; } + bool isPending() { return end_ == std::experimental::nullopt; } - ContextualizedEvent* getStartEvent() { return start_; } - ContextualizedEvent* getEndEvent() { return end_.value(); } + ContextualizedFact* getStartFact() { return start_; } + ContextualizedFact* getEndFact() { return end_.value(); } private: - ContextualizedEvent* start_; - std::experimental::optional end_; + ContextualizedFact* start_; + std::experimental::optional end_; }; } // namespace mementar diff --git a/include/mementar/core/memGraphs/Branchs/types/Event.h b/include/mementar/core/memGraphs/Branchs/types/Event.h deleted file mode 100644 index d2ee685..0000000 --- a/include/mementar/core/memGraphs/Branchs/types/Event.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef MEMENTAR_EVENT_H -#define MEMENTAR_EVENT_H - -#include -#include - -#include "mementar/core/memGraphs/Branchs/types/SoftPoint.h" -#include "mementar/core/memGraphs/Branchs/types/Fact.h" - -namespace mementar { - -class Event : public SoftPoint, public Fact -{ -public: - Event(const std::string& data, SoftPoint::Ttime t_start, std::experimental::optional t_end = std::experimental::nullopt) : SoftPoint(t_start, t_end), Fact(data) - { - } - - Event(const std::string& data, const SoftPoint& soft_point) : SoftPoint(soft_point), Fact(data) - { - } - - Event(const Fact& fact, const SoftPoint& soft_point) : SoftPoint(soft_point), Fact(fact) - { - } - - - Event(const Event& other) : SoftPoint(other), Fact(other) - { - } - - static std::string serialize(const Event& event) - { - if(event.isInstantaneous()) - return "[" + std::to_string(event.getTimeStart()) + "]{" + Fact::serialize(&event) + "}"; - else - return "[" + std::to_string(event.getTimeStart()) + "," + std::to_string(event.getTimeEnd()) + "]{" + Fact::serialize(&event) + "}"; - } - - static std::string serialize(const Event* event) - { - if(event->isInstantaneous()) - return "[" + std::to_string(event->getTimeStart()) + "]{" + Fact::serialize(event) + "}"; - else - return "[" + std::to_string(event->getTimeStart()) + "," + std::to_string(event->getTimeEnd()) + "]{" + Fact::serialize(event) + "}"; - } - - static Event deserialize(const std::string& str) - { - if(std::regex_match(str, match, regex)) - { - if(match[3].str() == "") - return Event(Fact::deserialize(match[4].str()), std::stoul(match[1].str())); - else - return Event(Fact::deserialize(match[4].str()), SoftPoint(std::stoul(match[1].str()), std::stoul(match[3].str()))); - } - else - return Event("", 0); - } - - static Event* deserializePtr(const std::string& str) - { - if(std::regex_match(str, match, regex)) - { - if(match[3].str() == "") - return new Event(Fact::deserialize(match[4].str()), std::stoul(match[1].str())); - else - return new Event(Fact::deserialize(match[4].str()), SoftPoint(std::stoul(match[1].str()), std::stoul(match[3].str()))); - } - else - return nullptr; - } - - std::string getData() { return Fact::toString(); } - - friend std::ostream& operator<<(std::ostream& os, Event* event) - { - std::string space = " "; - os << event->getData(); - return os; - } - - bool operator==(const Event& other) - { - return Fact::operator==(other); - } - - bool operator==(const Event* other) - { - return Fact::operator==(other); - } - -protected: - - static std::regex regex; - static std::smatch match; -}; - -} // namespace mementar - -#endif // MEMENTAR_EVENT_H diff --git a/include/mementar/core/memGraphs/Branchs/types/Fact.h b/include/mementar/core/memGraphs/Branchs/types/Fact.h index 6404736..b32fbfe 100644 --- a/include/mementar/core/memGraphs/Branchs/types/Fact.h +++ b/include/mementar/core/memGraphs/Branchs/types/Fact.h @@ -2,141 +2,98 @@ #define MEMENTAR_FACT_H #include -#include -#include -#include +#include -namespace mementar -{ +#include "mementar/core/memGraphs/Branchs/types/SoftPoint.h" +#include "mementar/core/memGraphs/Branchs/types/Triplet.h" + +namespace mementar { -class Fact +class Fact : public SoftPoint, public Triplet { public: - Fact(const std::string& subject, const std::string& predicat, const std::string& object, bool add = true) + Fact(const std::string& data, SoftPoint::Ttime t_start, std::experimental::optional t_end = std::experimental::nullopt) : SoftPoint(t_start, t_end), Triplet(data) { - subject_ = subject; - predicat_ = predicat; - object_ = object; - add_ = add; } - Fact(const std::string& triplet = "", bool add = true) + Fact(const std::string& data, const SoftPoint& soft_point) : SoftPoint(soft_point), Triplet(data) { - std::vector splitted = split(triplet, "|"); - if(splitted.size() >= 1) - subject_ = splitted[0]; - if(splitted.size() >= 2) - predicat_ = splitted[1]; - if(splitted.size() >= 3) - object_ = splitted[2]; - add_ = add; } - Fact(const Fact& other) + Fact(const Triplet& triplet, const SoftPoint& soft_point) : SoftPoint(soft_point), Triplet(triplet) + { + } + + + Fact(const Fact& other) : SoftPoint(other), Triplet(other) { - subject_ = other.subject_; - predicat_ = other.predicat_; - object_ = other.object_; - add_ = other.add_; } static std::string serialize(const Fact& fact) { - return (fact.add_ ? "A|" : "D|") + fact.subject_ + "|" + fact.predicat_ + "|" + fact.object_; + if(fact.isInstantaneous()) + return "[" + std::to_string(fact.getTimeStart()) + "]{" + Triplet::serialize(&fact) + "}"; + else + return "[" + std::to_string(fact.getTimeStart()) + "," + std::to_string(fact.getTimeEnd()) + "]{" + Triplet::serialize(&fact) + "}"; } static std::string serialize(const Fact* fact) { - return (fact->add_ ? "A|" : "D|") + fact->subject_ + "|" + fact->predicat_ + "|" + fact->object_; + if(fact->isInstantaneous()) + return "[" + std::to_string(fact->getTimeStart()) + "]{" + Triplet::serialize(fact) + "}"; + else + return "[" + std::to_string(fact->getTimeStart()) + "," + std::to_string(fact->getTimeEnd()) + "]{" + Triplet::serialize(fact) + "}"; } static Fact deserialize(const std::string& str) { if(std::regex_match(str, match, regex)) - return Fact(match[2].str(), match[3].str(), match[4].str(), match[1].str() == "A"); + { + if(match[3].str() == "") + return Fact(Triplet::deserialize(match[4].str()), std::stoul(match[1].str())); + else + return Fact(Triplet::deserialize(match[4].str()), SoftPoint(std::stoul(match[1].str()), std::stoul(match[3].str()))); + } else - return Fact(); + return Fact("", 0); } static Fact* deserializePtr(const std::string& str) { if(std::regex_match(str, match, regex)) - return new Fact(match[2].str(), match[3].str(), match[4].str(), match[1].str() == "A"); + { + if(match[3].str() == "") + return new Fact(Triplet::deserialize(match[4].str()), std::stoul(match[1].str())); + else + return new Fact(Triplet::deserialize(match[4].str()), SoftPoint(std::stoul(match[1].str()), std::stoul(match[3].str()))); + } else return nullptr; } - bool valid() const - { - return((subject_ != "") && (predicat_ != "") && (object_ != "")); - } + std::string getData() const { return Triplet::toString(); } - std::string toString() const + friend std::ostream& operator<<(std::ostream& os, Fact* fact) { - return (add_ ? "[add]" : "[del]") + subject_ + " | " + predicat_ + " | " + object_; + std::string space = " "; + os << fact->getData(); + return os; } bool operator==(const Fact& other) const { - return ( (add_ == other.add_) - && (subject_ == other.subject_) - && (predicat_ == other.predicat_) - && (object_ == other.object_)); + return Triplet::operator==(other); } bool operator==(const Fact* other) const { - return ( (add_ == other->add_) - && (subject_ == other->subject_) - && (predicat_ == other->predicat_) - && (object_ == other->object_)); + return Triplet::operator==(other); } - bool fit(const Fact& other) const - { - return ( (add_ == other.add_) - && ((subject_ == other.subject_) || (subject_ == "?") || (other.subject_ == "?")) - && ((predicat_ == other.predicat_) || (predicat_ == "?") || (other.predicat_ == "?")) - && ((object_ == other.object_) || (object_ == "?") || (other.object_ == "?"))); - } - - friend std::ostream& operator<<(std::ostream& os, const Fact& fact) - { - os << fact.toString(); - return os; - } - - std::string subject_; - std::string predicat_; - std::string object_; - bool add_; - protected: + static std::regex regex; static std::smatch match; - -private: - - std::vector split(const std::string& str, const std::string& delim) - { - std::vector tokens; - size_t prev = 0, pos = 0; - do - { - pos = str.find(delim, prev); - if (pos == std::string::npos) - pos = str.length(); - - std::string token = str.substr(prev, pos-prev); - - if (!token.empty()) - tokens.push_back(token); - prev = pos + delim.length(); - } - while ((pos < str.length()) && (prev < str.length())); - - return tokens; - } }; } // namespace mementar diff --git a/include/mementar/core/memGraphs/Branchs/types/SoftPoint.h b/include/mementar/core/memGraphs/Branchs/types/SoftPoint.h index e4dbca5..206c57c 100644 --- a/include/mementar/core/memGraphs/Branchs/types/SoftPoint.h +++ b/include/mementar/core/memGraphs/Branchs/types/SoftPoint.h @@ -9,8 +9,9 @@ namespace mementar { class SoftPoint { public: - //typedef size_t Ttime; - typedef float Ttime; + typedef size_t Ttime; + static Ttime default_time; + //typedef float Ttime; SoftPoint(Ttime t_start, std::experimental::optional t_end = std::experimental::nullopt) { diff --git a/include/mementar/core/memGraphs/Branchs/types/Triplet.h b/include/mementar/core/memGraphs/Branchs/types/Triplet.h new file mode 100644 index 0000000..4296fb5 --- /dev/null +++ b/include/mementar/core/memGraphs/Branchs/types/Triplet.h @@ -0,0 +1,149 @@ +#ifndef MEMENTAR_TRIPLET_H +#define MEMENTAR_TRIPLET_H + +#include +#include +#include +#include + +namespace mementar +{ + +class Triplet +{ +public: + Triplet(const std::string& subject, const std::string& predicat, const std::string& object, bool add = true) + { + subject_ = subject; + predicat_ = predicat; + object_ = object; + add_ = add; + } + + Triplet(const std::string& str_triplet = "", bool add = true) + { + std::vector splitted = split(str_triplet, "|"); + if(splitted.size() >= 1) + subject_ = splitted[0]; + if(splitted.size() >= 2) + predicat_ = splitted[1]; + if(splitted.size() >= 3) + object_ = splitted[2]; + add_ = add; + } + + Triplet(const Triplet& other) + { + subject_ = other.subject_; + predicat_ = other.predicat_; + object_ = other.object_; + add_ = other.add_; + } + + static std::string serialize(const Triplet& triplet) + { + return (triplet.add_ ? "A|" : "D|") + triplet.subject_ + "|" + triplet.predicat_ + "|" + triplet.object_; + } + + static std::string serialize(const Triplet* triplet) + { + return (triplet->add_ ? "A|" : "D|") + triplet->subject_ + "|" + triplet->predicat_ + "|" + triplet->object_; + } + + static Triplet deserialize(const std::string& str) + { + if(std::regex_match(str, match, regex)) + return Triplet(match[2].str(), match[3].str(), match[4].str(), match[1].str() == "A"); + else if(std::regex_match(str, match, regex2)) + return Triplet(match[2].str(), match[3].str(), match[4].str(), (match[1].str() == "ADD") || (match[1].str() == "add")); + else + return Triplet(); + } + + static Triplet* deserializePtr(const std::string& str) + { + if(std::regex_match(str, match, regex)) + return new Triplet(match[2].str(), match[3].str(), match[4].str(), match[1].str() == "A"); + else if(std::regex_match(str, match, regex2)) + return new Triplet(match[2].str(), match[3].str(), match[4].str(), (match[1].str() == "ADD") || (match[1].str() == "add")); + else + return nullptr; + } + + bool valid() const + { + return((subject_ != "") && (predicat_ != "") && (object_ != "")); + } + + std::string toString() const + { + return (add_ ? "[add]" : "[del]") + subject_ + "|" + predicat_ + "|" + object_; + } + + bool operator==(const Triplet& other) const + { + return ( (add_ == other.add_) + && (subject_ == other.subject_) + && (predicat_ == other.predicat_) + && (object_ == other.object_)); + } + + bool operator==(const Triplet* other) const + { + return ( (add_ == other->add_) + && (subject_ == other->subject_) + && (predicat_ == other->predicat_) + && (object_ == other->object_)); + } + + bool fit(const Triplet& other) const + { + return ( (add_ == other.add_) + && ((subject_ == other.subject_) || (subject_ == "?") || (other.subject_ == "?")) + && ((predicat_ == other.predicat_) || (predicat_ == "?") || (other.predicat_ == "?")) + && ((object_ == other.object_) || (object_ == "?") || (other.object_ == "?"))); + } + + friend std::ostream& operator<<(std::ostream& os, const Triplet& triplet) + { + os << triplet.toString(); + return os; + } + + std::string subject_; + std::string predicat_; + std::string object_; + bool add_; + +protected: + static std::regex regex; + static std::regex regex2; + static std::smatch match; + +private: + + std::vector split(const std::string& str, const std::string& delim) + { + std::vector tokens; + size_t prev = 0, pos = 0; + do + { + pos = str.find(delim, prev); + if (pos == std::string::npos) + pos = str.length(); + + std::string token = str.substr(prev, pos-prev); + + if (!token.empty()) + tokens.push_back(token); + prev = pos + delim.length(); + } + while ((pos < str.length()) && (prev < str.length())); + + return tokens; + } +}; + +} // namespace mementar + +#endif // MEMENTAR_TRIPLET_H diff --git a/include/mementar/core/memGraphs/Branchs/types/TripletPattern.h b/include/mementar/core/memGraphs/Branchs/types/TripletPattern.h new file mode 100644 index 0000000..e17a046 --- /dev/null +++ b/include/mementar/core/memGraphs/Branchs/types/TripletPattern.h @@ -0,0 +1,95 @@ +#ifndef MEMENTAR_TRIPLETPATTERN_H +#define MEMENTAR_TRIPLETPATTERN_H + +#include +#include + +#include "mementar/core/memGraphs/Branchs/types/Triplet.h" + +namespace mementar { + +class TripletPattern : public Triplet +{ +public: + TripletPattern(const std::string& subject, const std::string& predicat, const std::string& object, bool add = true) : Triplet(subject, predicat, object, add) + { + init(); + } + + TripletPattern(const std::string& str_triplet, bool add) : Triplet(str_triplet, add) + { + init(); + } + + TripletPattern(const Triplet& triplet) : Triplet(triplet) + { + init(); + } + + TripletPattern(const TripletPattern& other) : Triplet(other) + { + subject_is_indiv_ = other.subject_is_indiv_; + object_is_indiv_ = other.object_is_indiv_; + predicat_is_object_property_ = other.predicat_is_object_property_; + + subject_is_undefined_ = other.subject_is_undefined_; + object_is_undefined_ = other.object_is_undefined_; + predicat_is_undefined_ = other.predicat_is_undefined_; + } + + static std::string serialize(const TripletPattern& pattern) + { + return Triplet::serialize(pattern); + } + + static std::string serialize(const TripletPattern* pattern) + { + return Triplet::serialize(pattern); + } + + bool operator==(const Triplet& other) const = delete; + bool operator==(const Triplet* other) const = delete; + + void setSubjectAsClass() { subject_is_indiv_ = false; } + void setSubjectAsIndividual() { subject_is_indiv_ = true; } + void setObjectAsClass() { object_is_indiv_ = false; } + void setObjectAsIndividual() { object_is_indiv_ = true; } + void setPredicatAsDataProperty() { predicat_is_object_property_ = false; } + void setPredicatAsObjectProperty() { predicat_is_object_property_ = true; } + + bool isSubjectClass () const { return !subject_is_indiv_; } + bool isSubjectIndividual() const { return subject_is_indiv_; } + bool isObjectClass() const { return !object_is_indiv_; } + bool isObjectIndividual() const { return object_is_indiv_; } + bool isPredicatDataProperty() const { return !predicat_is_object_property_; } + bool isPredicatObjectProperty() const { return predicat_is_object_property_; } + + bool isSubjectUndefined() const { return subject_is_undefined_; } + bool isObjectUndefined() const { return object_is_undefined_; } + bool isPredicatUndefined() const { return predicat_is_undefined_; } + +protected: + bool subject_is_indiv_; + bool object_is_indiv_; + bool predicat_is_object_property_; + + bool subject_is_undefined_; + bool object_is_undefined_; + bool predicat_is_undefined_; + +private: + void init() + { + subject_is_indiv_ = true; + object_is_indiv_ = true; + predicat_is_object_property_ = true; + + subject_is_undefined_ = (this->subject_ == "?"); + object_is_undefined_ = (this->object_ == "?"); + predicat_is_undefined_ = (this->predicat_ == "?"); + } +}; + +} // namespace mementar + +#endif // MEMENTAR_TRIPLETPATTERN_H diff --git a/include/mementar/core/memGraphs/Btree/BplusTree.h b/include/mementar/core/memGraphs/Btree/BplusTree.h new file mode 100644 index 0000000..62c658d --- /dev/null +++ b/include/mementar/core/memGraphs/Btree/BplusTree.h @@ -0,0 +1,192 @@ +#ifndef MEMENTAR_BPLUSTREE_H +#define MEMENTAR_BPLUSTREE_H + +#include "mementar/core/memGraphs/Btree/Btree.h" + +namespace mementar { + +template +class BplusLeaf +{ +public: + using LeafType = BtreeLeafBase >; + using DataType = Tdata; + + BplusLeaf() + { + prev_ = nullptr; + next_ = nullptr; + } + + void insert(LeafType* leaf, DataType data) + { + (void)leaf; + payload_.push_back(data); + } + void remove(LeafType* leaf, DataType data) + { + (void)leaf; + for(size_t i = 0; i < payload_.size();) + { + if(payload_[i] == data) + payload_.erase(payload_.begin() + i); + else + i++; + } + } + bool hasData() + { + return (payload_.size() != 0); + } + + std::vector getData() + { + return payload_; + } + + BplusLeaf* getPreviousLeaf() { return prev_; } + BplusLeaf* getNextLeaf() { return next_; } + + void setPreviousLeaf(BplusLeaf* prev) { prev_ = prev; } + void setNextLeaf(BplusLeaf* next) { next_ = next; } + + std::vector payload_; + BplusLeaf* prev_; + BplusLeaf* next_; +private: +}; + +template +class BplusLeaf +{ +public: + using LeafType = BtreeLeafBase >; + using DataType = Tdata*; + + BplusLeaf() + { + prev_ = nullptr; + next_ = nullptr; + } + + void insert(LeafType* leaf, DataType data) + { + (void)leaf; + payload_.push_back(data); + } + void remove(LeafType* leaf, DataType data) + { + (void)leaf; + for(size_t i = 0; i < payload_.size();) + { + if(payload_[i]->operator==(*data)) + payload_.erase(payload_.begin() + i); + else + i++; + } + } + bool hasData() + { + return (payload_.size() != 0); + } + + std::vector getData() + { + return payload_; + } + + BplusLeaf* getPreviousLeaf() { return prev_; } + BplusLeaf* getNextLeaf() { return next_; } + + void setPreviousLeaf(BplusLeaf* prev) { prev_ = prev; } + void setNextLeaf(BplusLeaf* next) { next_ = next; } + + std::vector payload_; + BplusLeaf* prev_; + BplusLeaf* next_; +private: +}; + +template +class BplusTree : public Btree, N> +{ +public: + template + class BtreeIterator + { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = T; + using pointer = T*; + using reference = T&; + + BtreeIterator(T* ptr = nullptr){ ptr_ = ptr;} + BtreeIterator(const BtreeIterator& other) = default; + + BtreeIterator& operator=(const BtreeIterator& other) = default; + BtreeIterator& operator=(BtreeIterator* other){ ptr_ = other->ptr; return (*this); } + + operator bool() const + { + if(ptr_) + return true; + else + return false; + } + + bool operator==(const BtreeIterator& other)const{ return (ptr_ == other.ptr_); } + bool operator!=(const BtreeIterator& other)const{ return (ptr_ != other.ptr_); } + + BtreeIterator& operator++() { ptr_ = ptr_->getNextLeaf(); return (*this); } + BtreeIterator& operator--() { ptr_ = ptr_->getPreviousLeaf(); return (*this); } + + T& operator*() { return *ptr_; } + const T& operator*() const { return *ptr_; } + T* operator->() { return ptr_; } + + protected: + + T* ptr_; + }; + + template + class BtreeReverseIterator : public BtreeIterator + { + public: + + BtreeReverseIterator(T* ptr = nullptr):BtreeIterator(ptr) {} + BtreeReverseIterator(const BtreeIterator& forward_iterator) { this->ptr_ = *forward_iterator; } + BtreeReverseIterator(const BtreeReverseIterator& other) = default; + + BtreeReverseIterator& operator=(const BtreeReverseIterator& other) = default; + BtreeReverseIterator& operator=(const BtreeIterator& forward_iterator){ this->ptr_ = *forward_iterator; return (*this); } + BtreeReverseIterator& operator=(T* ptr) { this->ptr_ = ptr; return (*this); } + + BtreeReverseIterator& operator++(){ this->ptr_ = this->ptr_->getPreviousLeaf(); return (*this);} + BtreeReverseIterator& operator--(){ this->ptr_ = this->ptr_->getNextLeaf(); return (*this);} + + BtreeIterator base(){BtreeIterator forwardIterator(this->ptr_); ++forwardIterator; return forwardIterator;} + }; + + using iterator = BtreeIterator>; + using const_iterator = BtreeIterator>; + + using reverse_iterator = BtreeReverseIterator>; + using const_reverse_iterator = BtreeReverseIterator>; + + iterator begin() { return iterator(this->getFirst()); } + iterator end() { return iterator(nullptr); } + + const_iterator cbegin() { return const_iterator(this->getFirst()); } + const_iterator cend() { return const_iterator(nullptr); } + + reverse_iterator rbegin() { return reverse_iterator(this->getLast()); } + reverse_iterator rend() { return reverse_iterator(nullptr); } + + const_reverse_iterator crbegin() { return const_reverse_iterator(this->getLast()); } + const_reverse_iterator crend() { return const_reverse_iterator(nullptr); } +}; + +} // namespace mementar + +#endif // MEMENTAR_BPLUSTREE_H diff --git a/include/mementar/core/memGraphs/Btree/Btree.h b/include/mementar/core/memGraphs/Btree/Btree.h index 265160f..def74c3 100644 --- a/include/mementar/core/memGraphs/Btree/Btree.h +++ b/include/mementar/core/memGraphs/Btree/Btree.h @@ -1,29 +1,23 @@ #ifndef MEMENTAR_BTREE_H #define MEMENTAR_BTREE_H -#include -#include - +#include "mementar/core/memGraphs/Btree/BtreeLeafBase.h" #include "mementar/core/memGraphs/Btree/BtreeNode.h" -#include "mementar/core/memGraphs/Btree/BtreeLeafNode.h" -#include "mementar/core/memGraphs/Btree/BtreeLeaf.h" -#include "mementar/core/memGraphs/DoublyLinkedList/DllNode.h" +#include -namespace mementar -{ +namespace mementar { -template> +template class Btree { - //static_assert(std::is_base_of,Tnode>::value, "Tnode must be derived from DllNode"); + using Tdata = typename Tleaf::DataType; public: - Btree(size_t order = 10) + Btree() { root_ = nullptr; + first_ = nullptr; last_ = nullptr; - order_ = order; - level_ = 0; nb_data_ = 0; } @@ -31,79 +25,85 @@ class Btree { if(root_ != nullptr) delete root_; - - BtreeLeaf* tmp; - while(last_ != nullptr) - { - tmp = last_; - last_ = static_cast*>(last_->getPreviousNode()); - delete tmp; - } } size_t insert(const Tkey& key, const Tdata& data); bool remove(const Tkey& key, const Tdata& data); - BtreeLeaf* find(const Tkey& key); - BtreeLeaf* findNear(const Tkey& key); - BtreeLeaf* getFirst(); - BtreeLeaf* getLast() { return last_; } + BtreeLeafBase* find(const Tkey& key); + BtreeLeafBase* findNear(const Tkey& key); + BtreeLeafBase* getFirst() { return first_; } + BtreeLeafBase* getLast() { return last_; } - size_t estimateMinLeaves() - { - return pow((double)order_/2. + 1., (double)level_ - 1.) * root_->getNbChilds(); - } + void displayLinear(int count = -1); + void displayTree(); - size_t estimateMaxLevel(size_t nbLeafs) - { - return log((double)nbLeafs/2.) / log((double)order_/2. + 1) + 1; - } + size_t size() { return nb_data_; } - size_t getCurrentLevel() { return level_; } +private: + BtreeNode* root_; + BtreeLeafBase* first_; + BtreeLeafBase* last_; - void display(int count = -1); + std::vector*> nodes_; + std::vector*> leafs_; -private: - BtreeNode* root_; - BtreeLeaf* last_; - size_t order_; - size_t level_; size_t nb_data_; + + BtreeLeafBase* insertInLeaf(BtreeNode* node, const Tkey& key, const Tdata& data); + BtreeLeafBase* insertInNode(BtreeNode* node, const Tkey& key, const Tdata& data); + void insertNode(BtreeNode* node, BtreeNode* new_node, const Tkey& key); + bool needBalancing(BtreeNode* node); + void splitLeafNode(BtreeNode* node); + void splitNode(BtreeNode* node); + + bool removeInNode(BtreeNode* node, const Tkey& key, const Tdata& data); + bool removeInLeafNode(BtreeNode* node, const Tkey& key, const Tdata& data); + + BtreeLeafBase* findNearInNode(BtreeNode* node, const Tkey& key); + BtreeLeafBase* findInNode(BtreeNode* node, const Tkey& key); + BtreeLeafBase* findNearInLeafNode(BtreeNode* node, const Tkey& key); + BtreeLeafBase* findInLeafNode(BtreeNode* node, const Tkey& key); + + void displayNode(BtreeNode* node, size_t depth = 0); + void displayLeafNode(BtreeNode* node, size_t depth); }; -template -size_t Btree::insert(const Tkey& key, const Tdata& data) +template +size_t Btree::insert(const Tkey& key, const Tdata& data) { nb_data_++; if(last_ == nullptr) { - root_ = new BtreeLeafNode(order_); - level_ = root_->getLevel(); - last_ = root_->insert(key, data); + root_ = new BtreeNode(); + first_ = insertInLeaf(root_, key, data); + last_ = first_; + leafs_.push_back(first_); + nodes_.push_back(root_); } else { - BtreeLeaf* tmp = root_->insert(key, data); + BtreeLeafBase* tmp = insertInNode(root_, key, data); if(tmp != nullptr) { - if(tmp->operator>(last_)) + leafs_.push_back(tmp); + if(tmp->operator>(*last_)) last_ = tmp; + else if(tmp->operator<(*first_)) + first_ = tmp; if(root_->getMother() != nullptr) - { root_ = root_->getMother(); - level_ = root_->getLevel(); - } } } return nb_data_; } -template -bool Btree::remove(const Tkey& key, const Tdata& data) +template +bool Btree::remove(const Tkey& key, const Tdata& data) { nb_data_--; if(root_ != nullptr) - if(root_->remove(key, data)) + if(removeInNode(root_, key, data)) { nb_data_--; return true; @@ -111,37 +111,333 @@ bool Btree::remove(const Tkey& key, const Tdata& data) return false; } -template -BtreeLeaf* Btree::find(const Tkey& key) +template +BtreeLeafBase* Btree::findNear(const Tkey& key) { if(root_ != nullptr) - return root_->find(key); + return findNearInNode(root_, key); else return nullptr; } -template -BtreeLeaf* Btree::findNear(const Tkey& key) +template +BtreeLeafBase* Btree::find(const Tkey& key) { if(root_ != nullptr) - return root_->findNear(key); + return findInNode(root_, key); else return nullptr; } -template -BtreeLeaf* Btree::getFirst() +template +BtreeLeafBase* Btree::findNearInNode(BtreeNode* node, const Tkey& key) { - if(root_ != nullptr) - return root_->getFirst(); + if(node->isLeafNode()) + return findNearInLeafNode(node, key); + + for(size_t i = 0; i < node->keys_.size(); i++) + { + if(node->keys_[i] > key) + return findNearInNode(node->childs_[i], key); + } + return findNearInNode(node->childs_.back(), key); +} + +template +BtreeLeafBase* Btree::findInNode(BtreeNode* node, const Tkey& key) +{ + if(node->isLeafNode()) + return findInLeafNode(node, key); + + for(size_t i = 0; i < node->keys_.size(); i++) + { + if(node->keys_[i] > key) + return findInNode(node->childs_[i], key); + } + return findInNode(node->childs_.back(), key); +} + +template +BtreeLeafBase* Btree::findNearInLeafNode(BtreeNode* node, const Tkey& key) +{ + for(size_t i = 0; i < node->keys_.size(); i++) + { + if(node->keys_[i] >= key) + return node->leafs_[i]; + } + return node->leafs_.back(); +} + +template +BtreeLeafBase* Btree::findInLeafNode(BtreeNode* node, const Tkey& key) +{ + for(size_t i = 0; i < node->keys_.size(); i++) + { + if(node->keys_[i] == key) + return node->leafs_[i]; + } + return nullptr; +} + +template +bool Btree::removeInNode(BtreeNode* node, const Tkey& key, const Tdata& data) +{ + if(node->isLeafNode()) + return removeInLeafNode(node, key, data); + + size_t index = node->keys_.size(); + for(size_t i = 0; i < node->keys_.size(); i++) + { + if(node->keys_[i] > key) + { + index = i; + break; + } + } + return removeInNode(node->childs_[index], key, data); +} + +template +bool Btree::removeInLeafNode(BtreeNode* node, const Tkey& key, const Tdata& data) +{ + for(size_t i = 0; i < node->keys_.size(); i++) + { + if(node->keys_[i] == key) + { + node->leafs_[i]->remove(node->leafs_[i], data); + if(node->leafs_[i]->hasData() == false) + { + if(node->leafs_[i]->getPreviousLeaf() != nullptr) + node->leafs_[i]->getPreviousLeaf()->setNextLeaf(node->leafs_[i]->getNextLeaf()); + if(node->leafs_[i]->getNextLeaf() != nullptr) + node->leafs_[i]->getNextLeaf()->setPreviousLeaf(node->leafs_[i]->getPreviousLeaf()); + + delete node->leafs_[i]; + node->leafs_.erase(node->leafs_.begin() + i); + node->keys_.erase(node->keys_.begin() + i); + + if(node->leafs_.size() == 0) + std::cout << "a node is empty but will not be destroyed" << std::endl; + } + return true; + } + } + return false; +} + +template +BtreeLeafBase* Btree::insertInLeaf(BtreeNode* node, const Tkey& key, const Tdata& data) +{ + BtreeLeafBase* res = nullptr; + + if(node->leafs_.size() == 0) + { + node->keys_.push_back(key); + res = new BtreeLeafBase(key); + node->leafs_.push_back(res); + res->setMother(node); + res->insert(res, data); + return res; + } else - return nullptr; + { + BtreeLeafBase* last = nullptr; + if(node->leafs_.size()) + last = node->leafs_.back(); + + if(key > node->keys_.back()) + { + node->keys_.push_back(key); + res = new BtreeLeafBase(key); + node->leafs_.push_back(res); + res->setNextLeaf(last->getNextLeaf()); + last->setNextLeaf(res); + res->setPreviousLeaf(last); + res->setMother(node); + res->insert(res, data); + } + else if(node->keys_.back() == key) + { + last->insert(last, data); + } + else + { + for(size_t i = 0; i < node->keys_.size(); i++) + { + if(node->keys_[i] == key) + { + node->leafs_[i]->insert(node->leafs_[i], data); + break; + } + else if(node->keys_[i] > key) + { + res = new BtreeLeafBase(key); + // here last is the next node of res + last = node->leafs_[i]; + res->setNextLeaf(last); + res->setPreviousLeaf(last->getPreviousLeaf()); + if(res->getPreviousLeaf()) + res->getPreviousLeaf()->setNextLeaf(res); + if(res->getNextLeaf()) + res->getNextLeaf()->setPreviousLeaf(res); + node->keys_.insert(node->keys_.begin() + i, key); + node->leafs_.insert(node->leafs_.begin() + i, res); + res->setMother(node); + res->insert(res, data); + break; + } + } + } + } + + if(needBalancing(node)) + { + if(node->isLeafNode()) + splitLeafNode(node); + else + splitNode(node); + } + + return res; +} + +template +BtreeLeafBase* Btree::insertInNode(BtreeNode* node, const Tkey& key, const Tdata& data) +{ + if(node->isLeafNode()) + return insertInLeaf(node, key, data); + else + { + size_t index; + for(index = 0; index < node->keys_.size(); index++) + { + if(key < node->keys_[index]) + break; + } + return insertInNode(node->childs_[index], key, data); + } +} + +template +void Btree::insertNode(BtreeNode* node, BtreeNode* new_node, const Tkey& key) +{ + if(node->childs_.size() == 0) + { + node->childs_.push_back(new_node); + new_node->setMother(node); + return; + } + else + { + if(node->keys_.size() == 0) + { + node->keys_.push_back(key); + node->childs_.push_back(new_node); + new_node->setMother(node); + } + else if(key > node->keys_.back()) + { + node->keys_.push_back(key); + node->childs_.push_back(new_node); + new_node->setMother(node); + } + else + { + for(size_t i = 0; i < node->keys_.size(); i++) + { + if(key < node->keys_[i]) + { + node->keys_.insert(node->keys_.begin() + i, key); + node->childs_.insert(node->childs_.begin() + i + 1, new_node); + new_node->setMother(node); + break; + } + } + } + } + + if(needBalancing(node)) + splitNode(node); +} + +template +bool Btree::needBalancing(BtreeNode* node) +{ + if(node->isLeafNode()) + return node->leafs_.size() > N; + else + return node->childs_.size() > N; } -template -void Btree::display(int count) +template +void Btree::splitLeafNode(BtreeNode* node) { - BtreeLeaf* tmp = last_; + BtreeNode* new_leaf_node = new BtreeNode(); + + size_t half_order = N/2; + for(size_t i = 0; i < half_order; i++) + { + new_leaf_node->leafs_.insert(new_leaf_node->leafs_.begin(), node->leafs_.back()); + node->leafs_.pop_back(); + new_leaf_node->leafs_[i]->setMother(new_leaf_node); + + new_leaf_node->keys_.insert(new_leaf_node->keys_.begin(), node->keys_.back()); + node->keys_.pop_back(); + } + + if(node->mother_ != nullptr) + { + insertNode(node->mother_, new_leaf_node, new_leaf_node->keys_[0]); + } + else + { + BtreeNode* new_mother = new BtreeNode(); + nodes_.push_back(new_mother); + insertNode(new_mother, node, node->keys_[0]); + insertNode(new_mother, new_leaf_node, new_leaf_node->keys_[0]); + } +} + +template +void Btree::splitNode(BtreeNode* node) +{ + BtreeNode* new_node = new BtreeNode(); + nodes_.push_back(new_node); + + size_t half_order = N/2 - 1; + for(size_t i = 0; i < half_order; i++) + { + new_node->childs_.insert(new_node->childs_.begin(), node->childs_.back()); + node->childs_.pop_back(); + new_node->childs_[i]->setMother(new_node); + + new_node->keys_.insert(new_node->keys_.begin(), node->keys_.back()); + node->keys_.pop_back(); + } + + new_node->childs_.insert(new_node->childs_.begin(), node->childs_.back()); + node->childs_.pop_back(); + new_node->childs_[half_order]->setMother(new_node); + + if(node->mother_ != nullptr) + { + insertNode(node->mother_, new_node, node->keys_.back()); + node->keys_.pop_back(); + } + else + { + BtreeNode* new_mother = new BtreeNode(); + nodes_.push_back(new_mother); + insertNode(new_mother, node, node->keys_.back()); + insertNode(new_mother, new_node, node->keys_.back()); + node->keys_.pop_back(); + } +} + +template +void Btree::displayLinear(int count) +{ + BtreeLeafBase* tmp = first_; int cpt = 0; std::cout << "******" << std::endl; while((tmp != nullptr) && ((cpt < count) || (count == -1))) @@ -150,12 +446,53 @@ void Btree::display(int count) for(auto data : tmp->getData()) std::cout << data << " : "; std::cout << std::endl; - tmp = static_cast*>(tmp->getPreviousNode()); + tmp = tmp->getNextLeaf(); cpt++; } std::cout << "******" << std::endl; +} + +template +void Btree::displayTree() +{ + std::cout << "******" << std::endl; if(root_) - root_->display(); + displayNode(root_); + std::cout << "******" << std::endl; +} + +template +void Btree::displayNode(BtreeNode* node, size_t depth) +{ + size_t depth_1 = depth + 1; + + if(node->isLeafNode()) + displayLeafNode(node, depth_1); + else + { + for(size_t i = 0; i < node->keys_.size(); i++) + { + displayNode(node->childs_[i], depth_1); + for(size_t j = 0; j < depth; j++) + std::cout << "\t"; + std::cout << node->keys_[i] << std::endl; + } + displayNode(node->childs_[node->keys_.size()], depth_1); + } +} + +template +void Btree::displayLeafNode(BtreeNode* node, size_t depth) +{ + for(size_t i = 0; i < node->keys_.size(); i++) + { + for(size_t j = 0; j < depth; j++) + std::cout << "\t"; + std::cout << node->keys_[i] << " => "; + for(auto data : node->leafs_[i]->getData()) + std::cout << data << " : "; + std::cout << std::endl; + } } } // namespace mementar diff --git a/include/mementar/core/memGraphs/Btree/BtreeLeaf.h b/include/mementar/core/memGraphs/Btree/BtreeLeaf.h deleted file mode 100644 index 251c175..0000000 --- a/include/mementar/core/memGraphs/Btree/BtreeLeaf.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef MEMENTAR_BTREELEAF_H -#define MEMENTAR_BTREELEAF_H - -#include - -#include "mementar/core/memGraphs/DoublyLinkedList/DllNode.h" - -namespace mementar -{ - -template -class BtreeLeafNode; - -template> -class BtreeLeaf : public Tnode -{ - //static_assert(std::is_base_of,Tnode>::value, "Tnode must be derived from DllNode"); -public: - BtreeLeaf(const Tkey& key) : Tnode() - { - mother_ = nullptr; - - key_ = key; - } - - ~BtreeLeaf() { } - - bool operator==(const Tkey& other) { return key_ == other; } - bool operator>(const Tkey& other) { return key_ > other; } - bool operator<(const Tkey& other) { return key_ < other; } - bool operator>=(const Tkey& other) { return ((key_ > other) || (key_ == other)); } - bool operator<=(const Tkey& other) { return ((key_ < other) || (key_ == other)); } - - bool operator==(const BtreeLeaf* other) { return key_ == other->key_; } - bool operator>(const BtreeLeaf* other) { return key_ > other->key_; } - bool operator<(const BtreeLeaf* other) { return key_ < other->key_; } - bool operator>=(const BtreeLeaf* other) { return ((key_ > other->key_) || (key_ == other->key_)); } - bool operator<=(const BtreeLeaf* other) { return ((key_ < other->key_) || (key_ == other->key_)); } - - Tkey getKey() const { return key_; } - - void setMother(BtreeLeafNode* mother) { mother_ = mother; } - BtreeLeafNode* getMother() { return mother_; } - -private: - Tkey key_; - BtreeLeafNode* mother_; -}; - -} // mementar - -#endif // MEMENTAR_BTREELEAF_H diff --git a/include/mementar/core/memGraphs/Btree/BtreeLeafBase.h b/include/mementar/core/memGraphs/Btree/BtreeLeafBase.h new file mode 100644 index 0000000..2c4cd26 --- /dev/null +++ b/include/mementar/core/memGraphs/Btree/BtreeLeafBase.h @@ -0,0 +1,41 @@ +#ifndef MEMENTAR_BTREELEAF_H +#define MEMENTAR_BTREELEAF_H + +#include + +namespace mementar { + +template +class BtreeNode; + +template +class BtreeLeafBase : public Tleaf +{ + using Tdata = typename Tleaf::DataType; +public: + BtreeLeafBase(const Tkey& key) + { + mother_ = nullptr; + + key_ = key; + } + + bool operator==(const BtreeLeafBase& other) { return key_ == other.key_; } + bool operator>(const BtreeLeafBase& other) { return key_ > other.key_; } + bool operator<(const BtreeLeafBase& other) { return key_ < other.key_; } + bool operator>=(const BtreeLeafBase& other) { return ((key_ > other.key_) || (key_ == other.key_)); } + bool operator<=(const BtreeLeafBase& other) { return ((key_ < other.key_) || (key_ == other.key_)); } + + Tkey getKey() const { return key_; } + + void setMother(BtreeNode* mother) { mother_ = mother; } + BtreeNode* getMother() { return mother_; } + +private: + Tkey key_; + BtreeNode* mother_; +}; + +} // namespace mementar + +#endif // MEMENTAR_BTREELEAF_H diff --git a/include/mementar/core/memGraphs/Btree/BtreeLeafNode.h b/include/mementar/core/memGraphs/Btree/BtreeLeafNode.h deleted file mode 100644 index 36c31fa..0000000 --- a/include/mementar/core/memGraphs/Btree/BtreeLeafNode.h +++ /dev/null @@ -1,214 +0,0 @@ -#ifndef MEMENTAR_BTREELEAFNODE_H -#define MEMENTAR_BTREELEAFNODE_H - -#include "mementar/core/memGraphs/Btree/BtreeNode.h" -#include "mementar/core/memGraphs/Btree/BtreeLeaf.h" - -namespace mementar -{ - -template -class BtreeLeafNode : public BtreeNode -{ - //static_assert(std::is_base_of,Tnode>::value, "Tnode must be derived from DllNode"); -public: - BtreeLeafNode(size_t order = 10) : BtreeNode(order) - {} - - ~BtreeLeafNode() {} - - BtreeLeaf* insert(const Tkey& key, const Tdata& data); - bool remove(const Tkey& key, const Tdata& data); - BtreeLeaf* find(const Tkey& key); - BtreeLeaf* findNear(const Tkey& key); - BtreeLeaf* getFirst(); - - virtual void display(size_t depth = 0); -private: - std::vector*> leafs_; - - virtual bool needBalancing(); - virtual void split(); -}; - -template -BtreeLeaf* BtreeLeafNode::insert(const Tkey& key, const Tdata& data) -{ - BtreeLeaf* res = nullptr; - - if(leafs_.size() == 0) - { - this->keys_.push_back(key); - res = new BtreeLeaf(key); - leafs_.push_back(res); - res->setMother(this); - res->push_back(data); - return res; - } - else - { - BtreeLeaf* last = nullptr; - if(leafs_.size()) - last = leafs_.back(); - - if(key > this->keys_.back()) - { - this->keys_.push_back(key); - res = new BtreeLeaf(key); - leafs_.push_back(res); - res->setNextNode(last->getNextNode()); - last->setNextNode(res); - res->setPreviousNode(last); - res->setMother(this); - res->push_back(data); - } - else if(this->keys_.back() == key) - { - last->push_back(data); - } - else - { - for(size_t i = 0; i < this->keys_.size(); i++) - { - if(this->keys_[i] >= key) - { - if(this->keys_[i] == key) - { - leafs_[i]->push_back(data); - } - else - { - res = new BtreeLeaf(key); - // here last is the next node of res - last = leafs_[i]; - res->setNextNode(last); - res->setPreviousNode(last->getPreviousNode()); - if(res->getPreviousNode()) - res->getPreviousNode()->setNextNode(res); - if(res->getNextNode()) - res->getNextNode()->setPreviousNode(res); - this->keys_.insert(this->keys_.begin() + i, key); - this->leafs_.insert(this->leafs_.begin() + i, res); - res->setMother(this); - res->push_back(data); - } - break; - } - } - } - } - - if(needBalancing()) - split(); - - return res; -} - -template -bool BtreeLeafNode::remove(const Tkey& key, const Tdata& data) -{ - for(size_t i = 0; i < this->keys_.size(); i++) - { - if(this->keys_[i] == key) - { - leafs_[i]->remove(data); - if(leafs_[i]->getData().size() == 0) - { - if(leafs_[i]->getPreviousNode() != nullptr) - leafs_[i]->getPreviousNode()->setNextNode(leafs_[i]->getNextNode()); - if(leafs_[i]->getNextNode() != nullptr) - leafs_[i]->getNextNode()->setPreviousNode(leafs_[i]->getPreviousNode()); - delete leafs_[i]; - leafs_.erase(leafs_.begin() + i); - this->keys_.erase(this->keys_.begin() + i); - - if(leafs_.size() == 0) - std::cout << "a node is empty but will not be destroyed" << std::endl; - } - return true; - } - } - return false; -} - -template -BtreeLeaf* BtreeLeafNode::find(const Tkey& key) -{ - for(size_t i = 0; i < this->keys_.size(); i++) - { - if(this->keys_[i] == key) - return leafs_[i]; - } - return nullptr; -} - -template -BtreeLeaf* BtreeLeafNode::findNear(const Tkey& key) -{ - for(size_t i = 0; i < this->keys_.size(); i++) - { - if(this->keys_[i] >= key) - return leafs_[i]; - } - return static_cast*>(leafs_[leafs_.size() - 1]->getNextNode()); -} - -template -BtreeLeaf* BtreeLeafNode::getFirst() -{ - return leafs_[0]; -} - -template -bool BtreeLeafNode::needBalancing() -{ - return (leafs_.size() > this->order_); -} - -template -void BtreeLeafNode::split() -{ - BtreeLeafNode* new_node = new BtreeLeafNode(this->order_); - - size_t half_order = this->order_/2; - for(size_t i = 0; i < half_order; i++) - { - new_node->leafs_.insert(new_node->leafs_.begin(), leafs_.back()); - leafs_.pop_back(); - new_node->leafs_[i]->setMother(new_node); - - new_node->keys_.insert(new_node->keys_.begin(), this->keys_.back()); - this->keys_.pop_back(); - } - - if(this->mother_ != nullptr) - { - this->mother_->insert(new_node, new_node->keys_[0]); - } - else - { - BtreeNode* new_mother = new BtreeNode(this->order_); - new_mother->setLevel(this->level_ + 1); - new_mother->insert(this, this->keys_[0]); - new_mother->insert(new_node, new_node->keys_[0]); - } -} - -template -void BtreeLeafNode::display(size_t depth) -{ - for(size_t i = 0; i < this->keys_.size(); i++) - { - for(size_t j = 0; j < depth; j++) - std::cout << "\t"; - //std::vector datas = ; - std::cout << this->keys_[i] << " => "; - for(auto data : leafs_[i]->getData()) - std::cout << data << " : "; - std::cout << std::endl; - } -} - -} // namespace mementar - -#endif // MEMENTAR_BTREELEAFNODE_H diff --git a/include/mementar/core/memGraphs/Btree/BtreeNode.h b/include/mementar/core/memGraphs/Btree/BtreeNode.h index ba89da6..2ca621b 100644 --- a/include/mementar/core/memGraphs/Btree/BtreeNode.h +++ b/include/mementar/core/memGraphs/Btree/BtreeNode.h @@ -3,212 +3,35 @@ #include -#include "mementar/core/memGraphs/Btree/BtreeLeaf.h" +namespace mementar { -namespace mementar -{ +template +class BtreeLeafBase; -template +template class BtreeNode { - //static_assert(std::is_base_of,Tnode>::value, "Tnode must be derived from DllNode"); public: - BtreeNode(size_t order = 10) - { - order_ = order; - level_ = 1; - mother_ = nullptr; - } - - virtual ~BtreeNode() + ~BtreeNode() { for(auto child : childs_) delete child; - } - - virtual BtreeLeaf* insert(const Tkey& key, const Tdata& data); - void insert(BtreeNode* new_node, const Tkey& key); - virtual bool remove(const Tkey& key, const Tdata& data); - virtual BtreeLeaf* find(const Tkey& key); - virtual BtreeLeaf* findNear(const Tkey& key); - virtual BtreeLeaf* getFirst(); - void setMother(BtreeNode* mother) { mother_ = mother; } - BtreeNode* getMother() { return mother_; } + for(auto leaf : leafs_) + delete leaf; + } - void setLevel(size_t level) { level_ = level; } - size_t getLevel() { return level_; } + bool isLeafNode() { return leafs_.size() != 0; } - size_t getNbChilds() { return childs_.size(); } + void setMother(BtreeNode* mother) { mother_ = mother; } + BtreeNode* getMother() { return mother_; } - virtual void display(size_t depth = 0); -protected: std::vector keys_; - std::vector*> childs_; - BtreeNode* mother_; - size_t order_; - size_t level_; - - virtual bool needBalancing(); - virtual void split(); + BtreeNode* mother_; + std::vector*> childs_; + std::vector*> leafs_; }; -template -BtreeLeaf* BtreeNode::insert(const Tkey& key, const Tdata& data) -{ - size_t index; - for(index = 0; index < this->keys_.size(); index++) - { - if(key < this->keys_[index]) - break; - } - return childs_[index]->insert(key, data); -} - -template -void BtreeNode::insert(BtreeNode* new_node, const Tkey& key) -{ - if(childs_.size() == 0) - { - childs_.push_back(new_node); - new_node->setMother(this); - return; - } - else - { - if(this->keys_.size() == 0) - { - this->keys_.push_back(key); - childs_.push_back(new_node); - new_node->setMother(this); - } - else if(key > this->keys_[this->keys_.size() - 1]) - { - this->keys_.push_back(key); - childs_.push_back(new_node); - new_node->setMother(this); - } - else - { - for(size_t i = 0; i < this->keys_.size(); i++) - { - if(key < this->keys_[i]) - { - this->keys_.insert(this->keys_.begin() + i, key); - this->childs_.insert(this->childs_.begin() + i + 1, new_node); - new_node->setMother(this); - break; - } - } - } - } - - if(needBalancing()) - split(); -} - -template -bool BtreeNode::remove(const Tkey& key, const Tdata& data) -{ - size_t index = this->keys_.size(); - for(size_t i = 0; i < this->keys_.size(); i++) - { - if(this->keys_[i] > key) - { - index = i; - break; - } - } - return this->childs_[index]->remove(key, data); - - if(this->keys_.size() == 0) - std::cout << "a node is empty but will not be destroyed" << std::endl; -} - -template -BtreeLeaf* BtreeNode::find(const Tkey& key) -{ - for(size_t i = 0; i < this->keys_.size(); i++) - { - if(this->keys_[i] > key) - return this->childs_[i]->find(key); - } - return this->childs_[this->keys_.size()]->find(key); -} - -template -BtreeLeaf* BtreeNode::findNear(const Tkey& key) -{ - for(size_t i = 0; i < this->keys_.size(); i++) - { - if(this->keys_[i] > key) - return this->childs_[i]->findNear(key); - } - return this->childs_[this->keys_.size()]->findNear(key); -} - -template -BtreeLeaf* BtreeNode::getFirst() -{ - return this->childs_[0]->getFirst(); -} - -template -bool BtreeNode::needBalancing() -{ - return (childs_.size() > order_); -} - -template -void BtreeNode::split() -{ - BtreeNode* new_node = new BtreeNode(order_); - - size_t half_order = order_/2 - 1; - for(size_t i = 0; i < half_order; i++) - { - new_node->childs_.insert(new_node->childs_.begin(), childs_.back()); - childs_.pop_back(); - new_node->childs_[i]->setMother(new_node); - - new_node->keys_.insert(new_node->keys_.begin(), keys_.back()); - keys_.pop_back(); - } - - new_node->childs_.insert(new_node->childs_.begin(), childs_.back()); - childs_.pop_back(); - new_node->childs_[half_order]->setMother(new_node); - - if(mother_ != nullptr) - { - mother_->insert(new_node, keys_.back()); - keys_.pop_back(); - } - else - { - BtreeNode* new_mother = new BtreeNode(order_); - new_mother->setLevel(this->level_ + 1); - new_mother->insert(this, keys_.back()); - new_mother->insert(new_node, keys_.back()); - keys_.pop_back(); - } -} - -template -void BtreeNode::display(size_t depth) -{ - size_t depth_1 = depth + 1; - - for(size_t i = 0; i < keys_.size(); i++) - { - childs_[i]->display(depth_1); - for(size_t j = 0; j < depth; j++) - std::cout << "\t"; - std::cout << keys_[i] << std::endl; - } - childs_[keys_.size()]->display(depth_1); -} - } // namespace mementar #endif // MEMENTAR_BTREENODE_H diff --git a/include/mementar/core/memGraphs/DoublyLinkedList/DllCargoNode.h b/include/mementar/core/memGraphs/DoublyLinkedList/DllCargoNode.h deleted file mode 100644 index ae5b2df..0000000 --- a/include/mementar/core/memGraphs/DoublyLinkedList/DllCargoNode.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef MEMENTAR_DLLCARGONODE_H -#define MEMENTAR_DLLCARGONODE_H - -#include "mementar/core/memGraphs/DoublyLinkedList/DllNode.h" - -namespace mementar { - -class DllLinkedElement; - -class DllCargoNode : public DllNode -{ -public: - DllCargoNode(); - virtual ~DllCargoNode() {} - - virtual void push_back(DllLinkedElement* data); - virtual void remove(DllLinkedElement* data); - -protected: - void unlinkDll(size_t i); -}; - -} // namespace mementar - -#endif // MEMENTAR_DLLCARGONODE_H diff --git a/include/mementar/core/memGraphs/DoublyLinkedList/DllLinkedElement.h b/include/mementar/core/memGraphs/DoublyLinkedList/DllLinkedElement.h deleted file mode 100644 index ae4f1a9..0000000 --- a/include/mementar/core/memGraphs/DoublyLinkedList/DllLinkedElement.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef MEMENTAR_DLLLINKEDELEMENT_H -#define MEMENTAR_DLLLINKEDELEMENT_H - -#include "mementar/core/memGraphs/DoublyLinkedList/DllCargoNode.h" - -#include - -namespace mementar { - -class DllLinkedElement -{ - friend DllCargoNode; -public: - DllLinkedElement(); - - DllCargoNode* getPreviousDllNode(); - DllCargoNode* getNextDllNode(); - - std::vector getPreviousDllData(); - std::vector getNextDllData(); - - virtual bool operator==(const DllLinkedElement*) = 0; - virtual void print(std::ostream& os) const { os << this; } - friend std::ostream& operator<<(std::ostream& os, DllLinkedElement* elem) { elem->print(os); return os;} - -private: - DllCargoNode* dll_node_; -}; - -} // namespace mementar - -#endif // MEMENTAR_DLLLINKEDELEMENT_H diff --git a/include/mementar/core/memGraphs/DoublyLinkedList/DllNode.h b/include/mementar/core/memGraphs/DoublyLinkedList/DllNode.h deleted file mode 100644 index b9e4f90..0000000 --- a/include/mementar/core/memGraphs/DoublyLinkedList/DllNode.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef MEMENTAR_DLLNODE_H -#define MEMENTAR_DLLNODE_H - -#include -#include -#include - -namespace mementar { - -template -class DllNode -{ -std::false_type is_dllnode_impl(...); -template -std::true_type is_dllnode_impl(DllNode*); -template -using is_dllnode = decltype(is_dllnode_impl(std::declval())); - -public: - DllNode() - { - prev_ = nullptr; - next_ = nullptr; - } - - virtual ~DllNode() {} - - virtual void push_back(const Tdata& data) { payload_.push_back(data); } - virtual void remove(const Tdata& data) - { - for(size_t i = 0; i < payload_.size();) - { - if(payload_[i] == data) - payload_.erase(payload_.begin() + i); - else - i++; - } - } - - std::vector getData() const { return payload_; } - void getData(std::vector& data) { data = payload_; } - - inline DllNode* getPreviousNode() { return prev_; } - inline DllNode* getNextNode() { return next_; } - - virtual void setPreviousNode(DllNode* prev) { prev_ = prev; } - virtual void setNextNode(DllNode* next) { next_ = next; } - -protected: - DllNode* prev_; - DllNode* next_; - std::vector payload_; -}; - -} // namespace mementar - -#endif // MEMENTAR_DLLNODE_H diff --git a/include/mementar/core/memGraphs/EventLinkedList/EllElement.h b/include/mementar/core/memGraphs/EventLinkedList/EllElement.h deleted file mode 100644 index a702d68..0000000 --- a/include/mementar/core/memGraphs/EventLinkedList/EllElement.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef MEMENTAR_ELLELEMENT_H -#define MEMENTAR_ELLELEMENT_H - -#include "mementar/core/memGraphs/DoublyLinkedList/DllLinkedElement.h" -#include "mementar/core/memGraphs/EventLinkedList/EllNode.h" - -namespace mementar { - -class EllElement : public DllLinkedElement -{ - friend EllNode; -public: - EllElement(); - ~EllElement() {} - - EllElement* getPreviousEllElement() { return prev_elem_; } - EllElement* getNextEllElement() { return next_elem_; } - - virtual bool operator==(const DllLinkedElement*) = 0; - virtual bool isEventPart(const DllLinkedElement* other) = 0; - virtual void print(std::ostream& os) const { os << this; } - -private: - EllElement* prev_elem_; - EllElement* next_elem_; - - std::vector to_link_prev; - std::vector to_link_next; -}; - -} // namespace mementar - -#endif // MEMENTAR_ELLELEMENT_H diff --git a/include/mementar/core/memGraphs/EventLinkedList/EllNode.h b/include/mementar/core/memGraphs/EventLinkedList/EllNode.h deleted file mode 100644 index c5461dc..0000000 --- a/include/mementar/core/memGraphs/EventLinkedList/EllNode.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef MEMENTAR_ELLNODE_H -#define MEMENTAR_ELLNODE_H - -#include "mementar/core/memGraphs/DoublyLinkedList/DllCargoNode.h" - -#include - -namespace mementar { - -class EllElement; - -class EllNode : public DllCargoNode -{ -public: - EllNode(); - ~EllNode() {} - - void push_back(EllElement* data); - void remove(EllElement* data); -private: - - void link(EllElement* data); - - EllElement* getPrev(EllElement* data); - std::vector getPrevs(EllElement* data); - - EllElement* getNext(EllElement* data); - std::vector getNexts(EllElement* data); - - void linkPrev(EllElement* current, EllElement* prev, EllElement* next); - void linkNext(EllElement* current, EllElement* next, EllElement* prev); - - void unlink(EllElement* current_data); - - void unlinkPrev(EllElement* current, std::vector prev, EllElement* next); - void unlinkNext(EllElement* current, std::vector next, EllElement* prev); -}; - -} // namespace mementar - -#endif // MEMENTAR_ELLNODE_H diff --git a/include/mementar/core/memGraphs/ExtendedBtree/DlBtree.h b/include/mementar/core/memGraphs/ExtendedBtree/DlBtree.h new file mode 100644 index 0000000..4287346 --- /dev/null +++ b/include/mementar/core/memGraphs/ExtendedBtree/DlBtree.h @@ -0,0 +1,116 @@ +#ifndef MEMENTAR_DLBTREE_H +#define MEMENTAR_DLBTREE_H + +#include + +#include "mementar/core/memGraphs/Btree/BplusTree.h" + +namespace mementar { + +template +class LinkedData +{ +public: + using LeafType = Tleaf; + + LinkedData(Tvalue value) : value_(value) + { + leaf_ = nullptr; + } + + LeafType* getNextLeaf() + { + if(leaf_ == nullptr) + return nullptr; + else + return static_cast(leaf_->getNextLeaf()); + } + + LeafType* getPreviousLeaf() + { + if(leaf_ == nullptr) + return nullptr; + else + return static_cast(leaf_->getPreviousLeaf()); + } + + friend std::ostream& operator<<(std::ostream& os, const LinkedData& data) + { + os << data.value_; + return os; + } + + bool operator==(const LinkedData& other) const + { + return value_ == other.value_; + } + + Tvalue value_; + LeafType* leaf_; +}; + +template +class DataLinkedLeaf : public BplusLeaf +{ +public: + using LeafType = typename Tdata::LeafType; + + void insert(LeafType* leaf, Tdata data) + { + this->payload_.emplace_back(data); + this->payload_.back().leaf_ = leaf; + } + void remove(LeafType* leaf, Tdata data) + { + (void)leaf; + for(size_t i = 0; i < this->payload_.size();) + { + if(this->payload_[i] == data) + { + this->payload_[i].leaf_ = nullptr; + this->payload_.erase(this->payload_.begin() + i); + } + else + i++; + } + } +}; + +template +class DataLinkedLeaf : public BplusLeaf +{ +public: + using LeafType = typename Tdata::LeafType; + + void insert(LeafType* leaf, Tdata* data) + { + this->payload_.emplace_back(data); + data->leaf_ = leaf; + } + void remove(LeafType* leaf, Tdata* data) + { + (void)leaf; + for(size_t i = 0; i < this->payload_.size();) + { + if(this->payload_[i] == *data) + { + this->payload_[i].leaf_ = nullptr; + this->payload_.erase(this->payload_.begin() + i); + } + else + i++; + } + } +}; + +template +class DlLeaf : public DataLinkedLeaf>> +{ +}; + +template +using DlBtree = Btree, N>; + +} // namespace mementar + +#endif // MEMENTAR_DLBTREE_H diff --git a/include/mementar/core/memGraphs/ExtendedBtree/EventLinkedLeaf.h b/include/mementar/core/memGraphs/ExtendedBtree/EventLinkedLeaf.h new file mode 100644 index 0000000..0d584d3 --- /dev/null +++ b/include/mementar/core/memGraphs/ExtendedBtree/EventLinkedLeaf.h @@ -0,0 +1,345 @@ +#ifndef MEMENTAR_EVENTLINKEDLEAF_H +#define MEMENTAR_EVENTLINKEDLEAF_H + +#include "mementar/core/memGraphs/ExtendedBtree/DlBtree.h" + +namespace mementar { + +template +class EventLinkedLeaf; + +template +class LinkedEvent +{ + template + friend class EventLinkedLeaf; + +public: + LinkedEvent() + { + prev_elem_ = nullptr; + next_elem_ = nullptr; + leaf_ = nullptr; + } + + SelfType* getNext() { return next_elem_; } + SelfType* getPrevious() { return prev_elem_; } + + Tleaf* getLeaf() + { + if(leaf_ == nullptr) + return nullptr; + else + return static_cast(leaf_); + } + + Tleaf* getNextLeaf() + { + if(leaf_ == nullptr) + return nullptr; + else + return static_cast(leaf_->getNextLeaf()); + } + + Tleaf* getPreviousLeaf() + { + if(leaf_ == nullptr) + return nullptr; + else + return static_cast(leaf_->getPreviousLeaf()); + } + + Tleaf* leaf_; + +protected: + SelfType* prev_elem_; + SelfType* next_elem_; + + std::vector to_link_prev; + std::vector to_link_next; +}; + +template +class EventLinkedLeaf : public DataLinkedLeaf +{ + using DLF = DataLinkedLeaf; +public: + void insert(typename DLF::LeafType* leaf, Tdata data) + { + DLF::insert(leaf, data); + link(this->payload_.back()); + } + + void remove(typename DLF::LeafType* leaf, Tdata data) + { + (void)leaf; + for(size_t i = 0; i < this->payload_.size();) + { + if(this->payload_[i] == data) + { + unlink(this->payload_[i]); + this->payload_[i]->leaf_ = nullptr; + this->payload_.erase(this->payload_.begin() + i); + } + else + i++; + } + } +private: + void link(Tdata data); + void unlink(Tdata current_data); + + Tdata getPrev(Tdata data); + std::vector getPrevs(Tdata data); + + Tdata getNext(Tdata data); + std::vector getNexts(Tdata data); + + void linkPrev(Tdata current, Tdata prev, Tdata next); + void linkNext(Tdata current, Tdata next, Tdata prev); + + void unlinkPrev(Tdata current, const std::vector& prev, Tdata next); + void unlinkNext(Tdata current, const std::vector& next, Tdata prev); +}; + +template +void EventLinkedLeaf::link(Tdata data) +{ + auto next = getNext(data); + auto prev = getPrev(data); + + linkPrev(data, prev, next); + linkNext(data, next, prev); +} + +template +void EventLinkedLeaf::unlink(Tdata current_data) +{ + std::vector prev = getPrevs(current_data); + std::vector next = getNexts(current_data); + + unlinkPrev(current_data, prev, next.size() ? next[0] : nullptr); + unlinkNext(current_data, next, prev.size() ? prev[0] : nullptr); + + current_data->prev_elem_ = nullptr; + current_data->next_elem_ = nullptr; + + current_data->to_link_prev.clear(); + current_data->to_link_next.clear(); +} + +template +Tdata EventLinkedLeaf::getPrev(Tdata data) +{ + Tdata res = nullptr; + + auto prev_node = static_cast*>(data->getPreviousLeaf()); + while(prev_node != nullptr) + { + for(auto& ld : prev_node->payload_) + { + if(data->isPartOf(*ld)) + return ld; + } + prev_node = static_cast*>(prev_node->getPreviousLeaf()); + } + + return res; +} + +template +std::vector EventLinkedLeaf::getPrevs(Tdata data) +{ + std::vector res; + + auto prev_node = static_cast*>(data->getPreviousLeaf()); + if(prev_node == nullptr) + return res; + + for(;;) + { + for(auto& ld : prev_node->payload_) + { + if(data->isPartOf(*ld)) + { + res.push_back(ld); + if(ld->prev_elem_ != nullptr) + if(ld->prev_elem_->next_elem_->operator==(*ld)) + return res; + break; + } + } + + prev_node = static_cast*>(prev_node->getPreviousLeaf()); + if(prev_node == nullptr) + return res; + } +} + +template +Tdata EventLinkedLeaf::getNext(Tdata data) +{ + Tdata res = nullptr; + + auto next_node = static_cast*>(data->getNextLeaf()); + while(next_node != nullptr) + { + for(auto ld : next_node->payload_) + { + if(data->isPartOf(*ld)) + return ld; + } + next_node = static_cast*>(next_node->getNextLeaf()); + } + + return res; +} + +template +std::vector EventLinkedLeaf::getNexts(Tdata data) +{ + std::vector res; + + auto next_node = static_cast*>(data->getNextLeaf()); + if(next_node == nullptr) + return res; + + for(;;) + { + for(auto& ld : next_node->payload_) + { + if(data->isPartOf(*ld)) + { + res.push_back(ld); + if(ld->next_elem_ != nullptr) + if(ld->next_elem_->prev_elem_->operator==(*ld)) + return res; + break; + } + } + + next_node = static_cast*>(next_node->getNextLeaf()); + if(next_node == nullptr) + return res; + } +} + +template +void EventLinkedLeaf::linkPrev(Tdata current, Tdata prev, Tdata next) +{ + if(prev == nullptr) + return; + + if(current->operator==(*prev)) + { + if(next == nullptr) + { + current->to_link_next = prev->to_link_next; + prev->to_link_next.clear(); + current->to_link_next.push_back(prev); + } + current->prev_elem_ = prev->prev_elem_; + } + else + { + current->prev_elem_ = prev; + prev->next_elem_ = current; + if(prev->to_link_next.size()) + { + for(auto& d : prev->to_link_next) + d->next_elem_ = current; + prev->to_link_next.clear(); + } + } +} + +template +void EventLinkedLeaf::linkNext(Tdata current, Tdata next, Tdata prev) +{ + if(next == nullptr) + return; + + if(current->operator==(*next)) + { + if(prev == nullptr) + { + current->to_link_prev = next->to_link_prev; + next->to_link_prev.clear(); + current->to_link_prev.push_back(next); + } + current->next_elem_ = next->next_elem_; + } + else + { + current->next_elem_ = next; + next->prev_elem_ = current; + if(next->to_link_prev.size()) + { + for(auto& d : next->to_link_prev) + d->prev_elem_ = current; + next->to_link_prev.clear(); + } + } +} + +template +void EventLinkedLeaf::unlinkPrev(Tdata current, const std::vector& prev, Tdata next) +{ + if(prev.size()) + { + if(!current->operator==(*prev[0])) + { + if((next != nullptr) && !current->operator==(*next)) + { + for(auto& p : prev) + p->next_elem_ = current->next_elem_; + } + else + { + for(auto& p : prev) + p->next_elem_ = next; + } + } + } + else if(current->to_link_prev.size()) + { + if((next != nullptr) && current->operator==(*next)) + { + next->to_link_prev = std::move(current->to_link_prev); + next->to_link_prev.pop_back(); + } + } +} + +template +void EventLinkedLeaf::unlinkNext(Tdata current, const std::vector& next, Tdata prev) +{ + if(next.size()) + { + if(!current->operator==(*next[0])) + { + if((prev != nullptr) && !current->operator==(*prev)) + { + for(auto& n : next) + n->prev_elem_ = current->prev_elem_; + } + else + { + for(auto& n : next) + n->prev_elem_ = prev; + } + } + } + else if(current->to_link_next.size()) + { + if((prev != nullptr) && current->operator==(*prev)) + { + prev->to_link_next = std::move(current->to_link_next); + prev->to_link_next.pop_back(); + } + } +} + +} // namespace mementar + +#endif // MEMENTAR_EVENTLINKEDLEAF_H diff --git a/include/mementar/core/memGraphs/Graphs/ActionGraph.h b/include/mementar/core/memGraphs/Graphs/ActionGraph.h index c4626c1..326f764 100644 --- a/include/mementar/core/memGraphs/Graphs/ActionGraph.h +++ b/include/mementar/core/memGraphs/Graphs/ActionGraph.h @@ -2,25 +2,36 @@ #define MEMENTAR_ACTIONGRAPH_H #include "mementar/core/memGraphs/Graphs/Graph.h" -#include "mementar/core/memGraphs/Graphs/EventGraph.h" -#include "mementar/core/memGraphs/Branchs/ContextualizedEvent.h" +#include "mementar/core/memGraphs/Graphs/FactGraph.h" +#include "mementar/core/memGraphs/Branchs/ContextualizedFact.h" #include "mementar/core/memGraphs/Branchs/types/Action.h" #include #include #include +#include namespace mementar { class ActionGraph : public Graph { public: - ActionGraph(EventGraph* event_graph); + ActionGraph(FactGraph* fact_graph); ~ActionGraph(); void add(Action* action); bool setEnd(const std::string& action_name, const SoftPoint& end); + bool exist(const std::string& action_name); + std::unordered_set getPending(); + bool isPending(const std::string& action_name); + SoftPoint::Ttime getStartStamp(const std::string& action_name); + SoftPoint::Ttime getEndStamp(const std::string& action_name); + SoftPoint::Ttime getDuration(const std::string& action_name); + std::string getStartFact(const std::string& action_name); + std::string getEndFact(const std::string& action_name); + std::unordered_set getFactsDuring(const std::string& action_name); + std::vector get() { return all_actions_; @@ -32,16 +43,17 @@ class ActionGraph : public Graph return all_actions_; } - std::vector getPending(); - std::vector getPendingSafe() + std::vector getPendingPtr(); + std::vector getPendingPtrSafe() { std::shared_lock lock(Graph::mutex_); - return getPending(); + return getPendingPtr(); } + Action* find(const std::string& action_name); private: - EventGraph* event_graph_; + FactGraph* fact_graph_; std::vector all_actions_; std::map pending_actions_; }; diff --git a/include/mementar/core/memGraphs/Graphs/EventGraph.h b/include/mementar/core/memGraphs/Graphs/EventGraph.h deleted file mode 100644 index e09a0ae..0000000 --- a/include/mementar/core/memGraphs/Graphs/EventGraph.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef MEMENTAR_EVENTGRAPH_H -#define MEMENTAR_EVENTGRAPH_H - -#include "mementar/core/memGraphs/Graphs/Graph.h" -#include "mementar/core/memGraphs/Branchs/ContextualizedEvent.h" - -#include "mementar/core/memGraphs/Btree/Btree.h" - -namespace mementar { - -class EventGraph : public Graph -{ -public: - - ~EventGraph(); - - void add(ContextualizedEvent* event); - - std::vector get() - { - return all_events_; - } - - std::vector getSafe() - { - std::shared_lock lock(Graph::mutex_); - - return all_events_; - } - - Btree* getTimeline() { return &timeline; } - -private: - std::vector all_events_; - Btree timeline; -}; - -} // namespace mementar - -#endif // MEMENTAR_EVENTGRAPH_H diff --git a/include/mementar/core/memGraphs/Graphs/FactGraph.h b/include/mementar/core/memGraphs/Graphs/FactGraph.h new file mode 100644 index 0000000..e5c1631 --- /dev/null +++ b/include/mementar/core/memGraphs/Graphs/FactGraph.h @@ -0,0 +1,43 @@ +#ifndef MEMENTAR_FACTGRAPH_H +#define MEMENTAR_FACTGRAPH_H + +#include "mementar/core/memGraphs/Graphs/Graph.h" +#include "mementar/core/memGraphs/Branchs/ContextualizedFact.h" + +#include "mementar/core/memGraphs/ExtendedBtree/EventLinkedLeaf.h" + +namespace mementar { + +class FactGraph : public Graph +{ + using ElBTree = Btree, 10>; +public: + + ~FactGraph(); + + void add(ContextualizedFact* fact); + + std::vector get() + { + return all_facts_; + } + + std::vector getSafe() + { + std::shared_lock lock(Graph::mutex_); + + return all_facts_; + } + + ElBTree* getTimeline() { return &timeline_; } + + ContextualizedFact* findRecent(const Triplet& triplet, SoftPoint::Ttime until = SoftPoint::default_time); + +private: + std::vector all_facts_; + ElBTree timeline_; +}; + +} // namespace mementar + +#endif // MEMENTAR_FACTGRAPH_H diff --git a/include/mementar/core/memGraphs/Timeline.h b/include/mementar/core/memGraphs/Timeline.h index 751b315..614c0b8 100644 --- a/include/mementar/core/memGraphs/Timeline.h +++ b/include/mementar/core/memGraphs/Timeline.h @@ -1,7 +1,7 @@ #ifndef MEMENTAR_TIMELINE_H #define MEMENTAR_TIMELINE_H -#include "mementar/core/memGraphs/Graphs/EventGraph.h" +#include "mementar/core/memGraphs/Graphs/FactGraph.h" #include "mementar/core/memGraphs/Graphs/ActionGraph.h" namespace mementar { @@ -9,11 +9,14 @@ namespace mementar { class Timeline { public: - Timeline() : actions(&events) {} + Timeline() : actions(&facts) { init_ = true; } - EventGraph events; + FactGraph facts; ActionGraph actions; + + bool isInit() { return init_; } private: + bool init_; }; } // namespace mementar diff --git a/include/mementar/graphical/Display.h b/include/mementar/graphical/Display.h index b2d2c45..2474b1d 100644 --- a/include/mementar/graphical/Display.h +++ b/include/mementar/graphical/Display.h @@ -26,27 +26,27 @@ namespace mementar class Display { public: - static void Error(const std::string& text) + static void error(const std::string& text) { std::cout << COLOR_RED << "[ERROR]" << text << COLOR_OFF << std::endl; } - static void Warning(const std::string& text) + static void warning(const std::string& text) { std::cout << COLOR_ORANGE << "[WARNING]" << text << COLOR_OFF << std::endl; } - static void Info(const std::string& text) + static void info(const std::string& text) { std::cout << COLOR_BLUE << text << COLOR_OFF << std::endl; } - static void Debug(const std::string& text) + static void debug(const std::string& text) { std::cout << text << std::endl; } - static void Percent(size_t percent) + static void percent(size_t percent) { std::cout << "=>" << std::setw(3) << percent << "%\r" << std::flush; } diff --git a/include/mementar/graphical/mementarGUI/CallBackTimer.h b/include/mementar/graphical/mementarGUI/CallBackTimer.h new file mode 100644 index 0000000..3a756f8 --- /dev/null +++ b/include/mementar/graphical/mementarGUI/CallBackTimer.h @@ -0,0 +1,56 @@ +#ifndef MEMENTAR_CALLBACKTIMER_H +#define MEMENTAR_CALLBACKTIMER_H + +#include +#include +#include + +class CallBackTimer +{ +public: + CallBackTimer() + :execute_(false) + {} + + ~CallBackTimer() + { + if(execute_.load(std::memory_order_acquire)) + stop(); + } + + void stop() + { + execute_.store(false, std::memory_order_release); + if(th_.joinable()) + th_.join(); + } + + void start(int interval, std::function func) + { + if(execute_.load(std::memory_order_acquire)) + stop(); + + execute_.store(true, std::memory_order_release); + th_ = std::thread([this, interval, func]() + { + while (execute_.load(std::memory_order_acquire)) + { + func(); + std::this_thread::sleep_for( + std::chrono::milliseconds(interval)); + } + }); + } + + bool isRunning() const noexcept + { + return (execute_.load(std::memory_order_acquire) && + th_.joinable()); + } + +private: + std::atomic execute_; + std::thread th_; +}; + +#endif // MEMENTAR_CALLBACKTIMER_H diff --git a/include/mementar/graphical/mementarGUI/DarkStyle.h b/include/mementar/graphical/mementarGUI/DarkStyle.h new file mode 100644 index 0000000..4b34a92 --- /dev/null +++ b/include/mementar/graphical/mementarGUI/DarkStyle.h @@ -0,0 +1,40 @@ +/* +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### +*/ + +#ifndef _DarkStyle_HPP +#define _DarkStyle_HPP + +#include +#include +#include +#include +#include + +class DarkStyle : public QProxyStyle +{ + Q_OBJECT + +public: + DarkStyle(); + explicit DarkStyle(QStyle *style); + + QStyle *baseStyle() const; + + void polish(QPalette &palette) override; + void polish(QApplication *app) override; + +private: + QStyle *styleBase(QStyle *style = NULL) const; +}; + +#endif // _DarkStyle_HPP diff --git a/include/mementar/graphical/mementarGUI/QCheckBoxExtended.h b/include/mementar/graphical/mementarGUI/QCheckBoxExtended.h new file mode 100644 index 0000000..5e1ebea --- /dev/null +++ b/include/mementar/graphical/mementarGUI/QCheckBoxExtended.h @@ -0,0 +1,27 @@ +#ifndef MEMENTAR_QCHECKBOXEXTENDED_H +#define MEMENTAR_QCHECKBOXEXTENDED_H + +#include + +class QCheckBoxExtended : public QCheckBox +{ + Q_OBJECT +public: + explicit QCheckBoxExtended(QWidget *parent=0); + explicit QCheckBoxExtended(const QString& text, QWidget *parent=0); + virtual ~QCheckBoxExtended() {} + +protected: + void hoverEnter(QHoverEvent *event); + void hoverLeave(QHoverEvent *event); + void hoverMove(QHoverEvent *event); + bool event(QEvent *event); + +Q_SIGNALS: + void hoverEnter(); + void hoverLeave(); + +public slots: +}; + +#endif // MEMENTAR_QCHECKBOXEXTENDED_H diff --git a/include/mementar/graphical/mementarGUI/QLineEditExtended.h b/include/mementar/graphical/mementarGUI/QLineEditExtended.h new file mode 100644 index 0000000..16f9a2a --- /dev/null +++ b/include/mementar/graphical/mementarGUI/QLineEditExtended.h @@ -0,0 +1,26 @@ +#ifndef MEMENTAR_QLINEEDITEXTENDED_H +#define MEMENTAR_QLINEEDITEXTENDED_H + +#include + +class QLineEditExtended : public QLineEdit +{ + Q_OBJECT +public: + explicit QLineEditExtended(QWidget *parent=0); + virtual ~QLineEditExtended() {} + +protected: + void hoverEnter(QHoverEvent *event); + void hoverLeave(QHoverEvent *event); + void hoverMove(QHoverEvent *event); + bool event(QEvent *event); + +Q_SIGNALS: + void hoverEnter(); + void hoverLeave(); + +public slots: +}; + +#endif // MEMENTAR_QLINEEDITEXTENDED_H diff --git a/include/mementar/graphical/mementarGUI/QPushButtonExtended.h b/include/mementar/graphical/mementarGUI/QPushButtonExtended.h new file mode 100644 index 0000000..45393fe --- /dev/null +++ b/include/mementar/graphical/mementarGUI/QPushButtonExtended.h @@ -0,0 +1,26 @@ +#ifndef MEMENTAR_QPUSHBUTTONEXTENDED_H +#define MEMENTAR_QPUSHBUTTONEXTENDED_H + +#include + +class QPushButtonExtended : public QPushButton +{ + Q_OBJECT +public: + explicit QPushButtonExtended(QWidget *parent=0); + virtual ~QPushButtonExtended() {} + +protected: + void hoverEnter(QHoverEvent *event); + void hoverLeave(QHoverEvent *event); + void hoverMove(QHoverEvent *event); + bool event(QEvent *event); + +Q_SIGNALS: + void hoverEnter(); + void hoverLeave(); + +public slots: +}; + +#endif // MEMENTAR_QPUSHBUTTONEXTENDED_H diff --git a/include/mementar/graphical/mementarGUI/mementargui.h b/include/mementar/graphical/mementarGUI/mementargui.h new file mode 100644 index 0000000..dc1c397 --- /dev/null +++ b/include/mementar/graphical/mementarGUI/mementargui.h @@ -0,0 +1,83 @@ +#ifndef MEMENTAR_MEMENTARGUI_H +#define MEMENTAR_MEMENTARGUI_H + +#include +#include "include/mementar/graphical/mementarGUI/QCheckBoxExtended.h" +#include "include/mementar/graphical/mementarGUI/CallBackTimer.h" +#include + +#include +#include +#include + +#include "std_msgs/String.h" + +namespace Ui { +class mementarGUI; +} + +class mementarGUI : public QMainWindow +{ + Q_OBJECT + +public: + explicit mementarGUI(QWidget *parent = 0); + ~mementarGUI(); + + void init(ros::NodeHandle* n); + void wait(); + void start(); + +private: + Ui::mementarGUI *ui; + ros::NodeHandle* n_; + + std::map facts_publishers_; + std::map actions_publishers_; + std::map feeder_notifications_subs_; + std::string feeder_notifications_; + + int time_source_; + std::atomic current_time_; + CallBackTimer timer_; + + void displayInstancesList(); + void displayErrorInfo(const std::string& text); + + std::string vector2string(const std::vector& vect); + std::string vector2html(const std::vector& vect); + + void updateTime(); + +public slots: + void actionButtonHoverEnterSlot(); + void actionButtonHoverLeaveSlot(); + + void actionButtonClickedSlot(); + + void nameEditingFinishedSlot(); + void currentTabChangedSlot(int); + + void displayInstancesListSlot(); + void addInstanceSlot(); + void deleteInstanceSlot(); + void saveInstanceSlot(); + void drawInstanceSlot(); + void InstanceNameAddDelChangedSlot(const QString&); + void InstanceNameChangedSlot(const QString&); + void timesourceChangedSlot(int index); + void currentTimeEditingFinishedSlot(); + + void feederCallback(const std_msgs::String& msg); + void feederAddSlot(); + void feederDelSlot(); + void feederCommitSlot(); + void feederCheckoutSlot(); + void createPublisher(const std::string& onto_ns); + +signals: + void feederSetHtmlSignal(QString); + void setTimeSignal(QString); +}; + +#endif // MEMENTAR_MEMENTARGUI_H diff --git a/include/mementar/graphical/timeline/ActionReader.h b/include/mementar/graphical/timeline/ActionReader.h index 206fbea..9559d13 100644 --- a/include/mementar/graphical/timeline/ActionReader.h +++ b/include/mementar/graphical/timeline/ActionReader.h @@ -7,7 +7,7 @@ #include -#include "mementar/core/memGraphs/Graphs/EventGraph.h" +#include "mementar/core/memGraphs/Graphs/FactGraph.h" namespace mementar { @@ -27,7 +27,7 @@ class ActionReader public: ActionReader(); - void read(EventGraph* graph, CvFont* font); + void read(FactGraph* graph, CvFont* font); std::map actions_; size_t max_level_; diff --git a/include/mementar/graphical/timeline/EventReader.h b/include/mementar/graphical/timeline/FactReader.h similarity index 63% rename from include/mementar/graphical/timeline/EventReader.h rename to include/mementar/graphical/timeline/FactReader.h index 23320dc..5e36f88 100644 --- a/include/mementar/graphical/timeline/EventReader.h +++ b/include/mementar/graphical/timeline/FactReader.h @@ -6,25 +6,25 @@ #include -#include "mementar/core/memGraphs/Graphs/EventGraph.h" +#include "mementar/core/memGraphs/Graphs/FactGraph.h" namespace mementar { -struct event_t +struct fact_t { - event_t(SoftPoint::Ttime time) : time_point(time) {} + fact_t(SoftPoint::Ttime time) : time_point(time) {} std::string data; SoftPoint time_point; }; -class EventReader +class FactReader { public: - void read(EventGraph* graph, CvFont* font); + void read(FactGraph* graph, CvFont* font); - std::vector events; + std::vector facts; size_t max_text_size_; private: diff --git a/include/mementar/graphical/timeline/TimelineDrawer.h b/include/mementar/graphical/timeline/TimelineDrawer.h index f8df8ff..1bf1d1d 100644 --- a/include/mementar/graphical/timeline/TimelineDrawer.h +++ b/include/mementar/graphical/timeline/TimelineDrawer.h @@ -8,7 +8,7 @@ #include "mementar/core/memGraphs/Timeline.h" #include "mementar/graphical/timeline/ActionReader.h" -#include "mementar/graphical/timeline/EventReader.h" +#include "mementar/graphical/timeline/FactReader.h" namespace mementar { @@ -16,13 +16,13 @@ class TimelineDrawer { public: - void draw(const std::string& file_name, Timeline* timeline, ActionReader* actions, EventReader* events); + bool draw(const std::string& file_name, Timeline* timeline); private: IplImage* image_; - void drawVector(size_t start, size_t end, size_t pose); - void drawAction(const action_t& action, size_t line_pose, size_t max_level, size_t start_time); - void drawEvent(const event_t& event, size_t line_pose, size_t start_time); + void drawVector(size_t start, size_t end, size_t pose, CvFont* font); + void drawAction(const action_t& action, size_t line_pose, size_t max_level, size_t start_time, CvFont* font); + void drawEvent(const fact_t& event, size_t line_pose, size_t start_time, CvFont* font); size_t getTextSize(const std::string& txt, CvFont* font); void drawElipseStart(size_t x, size_t y); diff --git a/include/mementar/utils/String.h b/include/mementar/utils/String.h new file mode 100644 index 0000000..36b82cc --- /dev/null +++ b/include/mementar/utils/String.h @@ -0,0 +1,27 @@ +#ifndef MEMENTAR_STRING_H +#define MEMENTAR_STRING_H + +#include +#include + +namespace mementar { + + inline std::vector split(const std::string& text, const std::string& delim) + { + std::vector res; + std::string tmp_text = text; + while(tmp_text.find(delim) != std::string::npos) + { + size_t pos = tmp_text.find(delim); + std::string part = tmp_text.substr(0, pos); + tmp_text = tmp_text.substr(pos + delim.size(), tmp_text.size() - pos - delim.size()); + if(part != "") + res.push_back(part); + } + res.push_back(tmp_text); + return res; + } + +} // namespace mementar + +#endif // MEMENTAR_STRING_H diff --git a/launch/mementar.launch b/launch/mementar.launch index 6193563..4b6959d 100644 --- a/launch/mementar.launch +++ b/launch/mementar.launch @@ -1,5 +1,6 @@ + - + diff --git a/launch/mementar_full.launch b/launch/mementar_full.launch new file mode 100644 index 0000000..43ec468 --- /dev/null +++ b/launch/mementar_full.launch @@ -0,0 +1,7 @@ + + + + + + + diff --git a/launch/mementar_multi.launch b/launch/mementar_multi.launch index 5319be5..5a3adb9 100644 --- a/launch/mementar_multi.launch +++ b/launch/mementar_multi.launch @@ -1,5 +1,6 @@ + - + diff --git a/launch/mementar_multi_full.launch b/launch/mementar_multi_full.launch new file mode 100644 index 0000000..89d7d04 --- /dev/null +++ b/launch/mementar_multi_full.launch @@ -0,0 +1,7 @@ + + + + + + + diff --git a/launch/mementar_ontologenius.launch b/launch/mementar_ontologenius.launch new file mode 100644 index 0000000..fc1dd99 --- /dev/null +++ b/launch/mementar_ontologenius.launch @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/msg/MementarAction.msg b/msg/MementarAction.msg new file mode 100644 index 0000000..c14269b --- /dev/null +++ b/msg/MementarAction.msg @@ -0,0 +1,3 @@ +string name +time start_stamp +time end_stamp diff --git a/msg/MementarExplanation.msg b/msg/MementarExplanation.msg new file mode 100644 index 0000000..43d7255 --- /dev/null +++ b/msg/MementarExplanation.msg @@ -0,0 +1,2 @@ +string fact +string cause diff --git a/package.xml b/package.xml index e3fb494..a774967 100644 --- a/package.xml +++ b/package.xml @@ -23,6 +23,7 @@ pluginlib qtbase5-dev rostest + ontologenius message_runtime diagnostic_msgs @@ -30,6 +31,7 @@ roscpp std_msgs pluginlib + ontologenius + + + + 0 + + + + + + Action + + + + + + + + + Parameter + + + + + + + <html><head/><body><p> Enter your parameters here.</p></body></html> + + + + + + + + + + + + PointingHandCursor + + + <html><head/><body><p><span style=" font-weight:600; font-style:italic;">exist</span> allows you to test whether the action provided in parameter exists in this timeline</p></body></html> + + + exist + + + + + + + PointingHandCursor + + + <html><head/><body><p><span style=" font-weight:600; font-style:italic;">getPending</span> will give you all the pending actions (i.e. started but not yet finished)</p></body></html> + + + getPending + + + + + + + PointingHandCursor + + + <html><head/><body><p><span style=" font-weight:600; font-style:italic;">isPending</span> allows you to test whether the action provided in parameter is pending (i.e. started but not yet finished)</p></body></html> + + + isPending + + + + + + + + + + + + PointingHandCursor + + + <html><head/><body><p><span style=" font-weight:600; font-style:italic;">getStartStamp</span> returns the timestamp of the start of the action provided in parameter</p></body></html> + + + getStartStamp + + + + + + + PointingHandCursor + + + <html><head/><body><p><span style=" font-weight:600; font-style:italic;">getEndStamp</span> returns the timestamp of the end of the action provided in parameter</p></body></html> + + + getEndStamp + + + + + + + PointingHandCursor + + + <html><head/><body><p><span style=" font-weight:600; font-style:italic;">getDuration</span> returns the duraction of the action provided in parameter</p></body></html> + + + getDuration + + + + + + + + + + + + PointingHandCursor + + + <html><head/><body><p><span style=" font-weight:600; font-style:italic;">getStartFact</span> returns the identifier of the fact representing the start of the action provided as a parameter</p></body></html> + + + getStartFact + + + + + + + PointingHandCursor + + + <html><head/><body><p><span style=" font-weight:600; font-style:italic;">getEndFact</span> returns the identifier of the fact representing the end of the action provided as a parameter</p></body></html> + + + getEndFact + + + + + + + PointingHandCursor + + + <html><head/><body><p><span style=" font-weight:600; font-style:italic;">getFactsDuring</span> returns the identifiers of all the facts that took place during the execution of the action provided in parameter</p></body></html> + + + getFactsDuring + + + + + + + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + Qt::NoTextInteraction + + + + + + + + + + + + Feeder + + + + + + + + + + + + 130 + 30 + + + + + 130 + 30 + + + + + 0 + 0 + + + + Subject / Action : + + + + + + + + + + + + + + + + + + + + 130 + 30 + + + + + 130 + 30 + + + + + 0 + 0 + + + + Property : + + + + + + + + + + + + + + + + + + + + 130 + 30 + + + + + 130 + 30 + + + + + 0 + 0 + + + + Object : + + + + + + + + + + + + + + + + ADD / START + + + + + + + + REMOVE / END + + + + + + + + QFrame::Plain + + + 100 + + + Qt::Horizontal + + + + + + + + + + + + + Commit + + + + + + + + Checkout + + + + + + + + + + + + 350 + 16777215 + + + + true + + + 1 + + + Qt::NoTextInteraction + + + + + + + + + + + Manager + + + + + + + + + + 0 + 0 + + + + This second can only be used with the "mementar_multi" executable + + + true + + + Qt::AlignCenter + + + + + + + + ADD(name) / COPY(dest=src) + + + + + + + + DELETE(name) + + + + + + + + + + + + + + + + + + QFrame::Plain + + + 100 + + + Qt::Horizontal + + + + + + + + + + + + + + + + + 20 + 20 + + + + + :/darkstyle/icon_save.png + + + + + + + + + + + + + + + + + + + + + 20 + 20 + + + + + :/darkstyle/icon_draw.png + + + + + + + + + + + + + + + + + + 20 + 20 + + + + + :/darkstyle/icon_refresh.png + + + + + + + + + + + + + 250 + 16777215 + + + + true + + + 1 + + + Qt::NoTextInteraction + + + + + + + + + + + + + + + + + + + + + + 150 + 0 + + + + + 200 + 200 + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> + p, li { white-space: pre-wrap; } + </style></head><body style=" font-family:'Noto Sans'; font-size:9pt; font-weight:400; font-style:normal;"> + <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + + + + + + Name + + + + 50 + 16777215 + + + + + + + + + 145 + 16777215 + + + + + + + + + + + + + + 80 + 16777215 + + + + + Ros + + + + + Epoch + + + + + Manual + + + + + + + + + 145 + 16777215 + + + + + + + + + + + + + + + 0 + 0 + + + + Qt::Vertical + + + + + + + + + 16777215 + 260 + + + + true + + + + + + + + + + + + + + + + + QPushButtonExtended + QPushButton +
include/mementar/graphical/mementarGUI/QPushButtonExtended.h
+
+ + QCheckBoxExtended + QCheckBox +
include/mementar/graphical/mementarGUI/QCheckBoxExtended.h
+
+ + QLineEditExtended + QLineEdit +
include/mementar/graphical/mementarGUI/QLineEditExtended.h
+
+
+ + +