From 07611ad812a6865b3b0f482d4b50c3ad164a29a1 Mon Sep 17 00:00:00 2001 From: Fabian Peller-Konrad <fabian.peller-konrad@kit.edu> Date: Fri, 22 Oct 2021 09:55:52 +0200 Subject: [PATCH] ltm implementation for disk memory, new interfaces, connection to query_proc --- .../RobotAPI/libraries/armem/CMakeLists.txt | 73 +++-- .../armem/core/wm/aron_conversions.cpp | 59 ++-- .../armem/core/wm/aron_conversions.h | 7 +- .../armem/server/MemoryToIceAdapter.cpp | 12 +- .../armem/server/MemoryToIceAdapter.h | 2 +- .../armem/server/ltm/LongtermMemoryBase.cpp | 100 ------- .../armem/server/ltm/LongtermMemoryBase.h | 69 ----- .../server/ltm/detail/BufferedMemoryBase.cpp | 7 + .../server/ltm/detail/BufferedMemoryBase.h | 45 +++ .../server/ltm/detail/CoreSegmentBase.cpp | 6 + .../armem/server/ltm/detail/CoreSegmentBase.h | 56 ++++ .../armem/server/ltm/detail/EntityBase.cpp | 10 + .../armem/server/ltm/detail/EntityBase.h | 58 ++++ .../server/ltm/detail/EntitySnapshotBase.cpp | 14 + .../server/ltm/detail/EntitySnapshotBase.h | 36 +++ .../armem/server/ltm/detail/LUTMemoryBase.cpp | 6 + .../armem/server/ltm/detail/LUTMemoryBase.h | 47 +++ .../armem/server/ltm/detail/MemoryBase.cpp | 6 + .../armem/server/ltm/detail/MemoryBase.h | 55 ++++ .../armem/server/ltm/detail/MemoryItem.cpp | 28 ++ .../armem/server/ltm/detail/MemoryItem.h | 27 ++ .../server/ltm/detail/ProviderSegmentBase.cpp | 11 + .../server/ltm/detail/ProviderSegmentBase.h | 56 ++++ .../armem/server/ltm/disk/CoreSegment.cpp | 100 +++++++ .../armem/server/ltm/disk/CoreSegment.h | 33 ++ .../armem/server/ltm/disk/Entity.cpp | 148 +++++++++ .../libraries/armem/server/ltm/disk/Entity.h | 43 +++ .../armem/server/ltm/disk/EntitySnapshot.cpp | 131 ++++++++ .../armem/server/ltm/disk/EntitySnapshot.h | 28 ++ .../armem/server/ltm/disk/Memory.cpp | 142 +++++++++ .../libraries/armem/server/ltm/disk/Memory.h | 34 +++ .../armem/server/ltm/disk/MemoryManager.cpp | 119 -------- .../armem/server/ltm/disk/MemoryManager.h | 39 --- .../armem/server/ltm/disk/ProviderSegment.cpp | 101 +++++++ .../armem/server/ltm/disk/ProviderSegment.h | 33 ++ .../armem/server/ltm/disk/detail/Data.cpp | 7 + .../armem/server/ltm/disk/detail/Data.h | 65 ++++ .../server/ltm/disk/detail/DiskStorage.cpp | 40 +++ .../server/ltm/disk/detail/DiskStorage.h | 25 ++ .../armem/server/ltm/disk/operations.cpp | 281 ------------------ .../armem/server/ltm/disk/operations.h | 36 --- .../mongodb/ConnectionManager.cpp | 0 .../{ => legacy}/mongodb/ConnectionManager.h | 0 .../{ => legacy}/mongodb/MemoryManager.cpp | 0 .../ltm/{ => legacy}/mongodb/MemoryManager.h | 2 +- .../ltm/{ => legacy}/mongodb/operations.cpp | 0 .../ltm/{ => legacy}/mongodb/operations.h | 0 .../libraries/armem/server/ltm/operations.cpp | 22 -- .../libraries/armem/server/ltm/operations.h | 13 - .../libraries/armem/server/plugins/Plugin.cpp | 10 +- .../libraries/armem/server/plugins/Plugin.h | 1 - .../query_proc/base/BaseQueryProcessorBase.h | 1 - .../base/CoreSegmentQueryProcessorBase.h | 13 +- .../base/EntityQueryProcessorBase.h | 61 ++-- .../base/MemoryQueryProcessorBase.h | 16 +- .../base/ProviderSegmentQueryProcessorBase.h | 17 +- .../libraries/armem/server/query_proc/ltm.h | 32 -- .../detail/CoreSegmentQueryProcessorBase.cpp | 1 + .../detail/CoreSegmentQueryProcessorBase.h | 36 +++ .../ltm/detail/EntityQueryProcessorBase.cpp | 9 + .../ltm/detail/EntityQueryProcessorBase.h | 35 +++ .../ltm/detail/MemoryQueryProcessorBase.cpp | 1 + .../ltm/detail/MemoryQueryProcessorBase.h | 33 ++ .../ProviderSegmentQueryProcessorBase.cpp | 1 + .../ProviderSegmentQueryProcessorBase.h | 33 ++ .../armem/server/query_proc/{ => ltm}/ltm.cpp | 0 .../armem/server/query_proc/ltm/ltm.h | 65 ++++ .../detail/CoreSegmentQueryProcessorBase.cpp | 6 + .../wm/detail/CoreSegmentQueryProcessorBase.h | 39 +++ .../wm/detail/EntityQueryProcessorBase.cpp | 9 + .../wm/detail/EntityQueryProcessorBase.h | 38 +++ .../wm/detail/MemoryQueryProcessorBase.cpp | 7 + .../wm/detail/MemoryQueryProcessorBase.h | 35 +++ .../ProviderSegmentQueryProcessorBase.cpp | 6 + .../ProviderSegmentQueryProcessorBase.h | 35 +++ .../armem/server/query_proc/{ => wm}/wm.cpp | 3 +- .../armem/server/query_proc/{ => wm}/wm.h | 72 ++++- .../armem/test/ArMemLTMBenchmark.cpp | 118 ++++++++ .../libraries/armem/test/ArMemQueryTest.cpp | 2 +- .../libraries/armem/test/CMakeLists.txt | 1 + .../libraries/armem_gui/MemoryViewer.cpp | 8 +- .../armem_gui/disk/ControlWidget.cpp | 17 +- 82 files changed, 2131 insertions(+), 862 deletions(-) delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.cpp delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/BufferedMemoryBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/BufferedMemoryBase.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/LUTMemoryBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/LUTMemoryBase.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.cpp delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.h create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/detail/DiskStorage.cpp create mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/detail/DiskStorage.h delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/operations.cpp delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/disk/operations.h rename source/RobotAPI/libraries/armem/server/ltm/{ => legacy}/mongodb/ConnectionManager.cpp (100%) rename source/RobotAPI/libraries/armem/server/ltm/{ => legacy}/mongodb/ConnectionManager.h (100%) rename source/RobotAPI/libraries/armem/server/ltm/{ => legacy}/mongodb/MemoryManager.cpp (100%) rename source/RobotAPI/libraries/armem/server/ltm/{ => legacy}/mongodb/MemoryManager.h (95%) rename source/RobotAPI/libraries/armem/server/ltm/{ => legacy}/mongodb/operations.cpp (100%) rename source/RobotAPI/libraries/armem/server/ltm/{ => legacy}/mongodb/operations.h (100%) delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/operations.cpp delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/operations.h delete mode 100644 source/RobotAPI/libraries/armem/server/query_proc/ltm.h create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.h create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.h create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/MemoryQueryProcessorBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/MemoryQueryProcessorBase.h create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.h rename source/RobotAPI/libraries/armem/server/query_proc/{ => ltm}/ltm.cpp (100%) create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/ltm/ltm.h create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.h create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/wm/detail/EntityQueryProcessorBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/wm/detail/EntityQueryProcessorBase.h create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/wm/detail/MemoryQueryProcessorBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/wm/detail/MemoryQueryProcessorBase.h create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.cpp create mode 100644 source/RobotAPI/libraries/armem/server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.h rename source/RobotAPI/libraries/armem/server/query_proc/{ => wm}/wm.cpp (89%) rename source/RobotAPI/libraries/armem/server/query_proc/{ => wm}/wm.h (54%) create mode 100644 source/RobotAPI/libraries/armem/test/ArMemLTMBenchmark.cpp diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt index c589f0b3a..0f4a137d1 100644 --- a/source/RobotAPI/libraries/armem/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem/CMakeLists.txt @@ -83,13 +83,22 @@ set(LIB_FILES server/MemoryRemoteGui.cpp server/RemoteGuiAronDataVisitor.cpp - server/ltm/operations.cpp - server/ltm/LongtermMemoryBase.cpp - server/ltm/disk/operations.cpp - server/ltm/disk/MemoryManager.cpp - server/ltm/mongodb/MemoryManager.cpp - server/ltm/mongodb/operations.cpp - server/ltm/mongodb/ConnectionManager.cpp + server/ltm/detail/MemoryItem.cpp + server/ltm/detail/MemoryBase.cpp + server/ltm/detail/BufferedMemoryBase.cpp + server/ltm/detail/LUTMemoryBase.cpp + server/ltm/detail/CoreSegmentBase.cpp + server/ltm/detail/ProviderSegmentBase.cpp + server/ltm/detail/EntityBase.cpp + server/ltm/detail/EntitySnapshotBase.cpp + + server/ltm/disk/detail/Data.cpp + server/ltm/disk/detail/DiskStorage.cpp + server/ltm/disk/Memory.cpp + server/ltm/disk/CoreSegment.cpp + server/ltm/disk/ProviderSegment.cpp + server/ltm/disk/Entity.cpp + server/ltm/disk/EntitySnapshot.cpp server/wm/memory_definitions.cpp server/wm/ice_conversions.cpp @@ -108,8 +117,17 @@ set(LIB_FILES server/query_proc/base/CoreSegmentQueryProcessorBase.cpp server/query_proc/base/MemoryQueryProcessorBase.cpp - server/query_proc/ltm.cpp - server/query_proc/wm.cpp + server/query_proc/ltm/detail/EntityQueryProcessorBase.cpp + server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.cpp + server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.cpp + server/query_proc/ltm/detail/MemoryQueryProcessorBase.cpp + server/query_proc/ltm/ltm.cpp + + server/query_proc/wm/detail/EntityQueryProcessorBase.cpp + server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.cpp + server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.cpp + server/query_proc/wm/detail/MemoryQueryProcessorBase.cpp + server/query_proc/wm/wm.cpp mns/MemoryNameSystem.cpp @@ -198,14 +216,22 @@ set(LIB_HEADERS server/MemoryRemoteGui.h server/RemoteGuiAronDataVisitor.h - - server/ltm/operations.h - server/ltm/LongtermMemoryBase.h - server/ltm/disk/operations.h - server/ltm/disk/MemoryManager.h - server/ltm/mongodb/MemoryManager.h - server/ltm/mongodb/operations.h - server/ltm/mongodb/ConnectionManager.h + server/ltm/detail/MemoryItem.h + server/ltm/detail/MemoryBase.h + server/ltm/detail/BufferedMemoryBase.h + server/ltm/detail/LUTMemoryBase.h + server/ltm/detail/CoreSegmentBase.h + server/ltm/detail/ProviderSegmentBase.h + server/ltm/detail/EntityBase.h + server/ltm/detail/EntitySnapshotBase.h + + server/ltm/disk/detail/Data.h + server/ltm/disk/detail/DiskStorage.h + server/ltm/disk/Memory.h + server/ltm/disk/CoreSegment.h + server/ltm/disk/ProviderSegment.h + server/ltm/disk/Entity.h + server/ltm/disk/EntitySnapshot.h server/wm/memory_definitions.h server/wm/ice_conversions.h @@ -228,8 +254,17 @@ set(LIB_HEADERS server/query_proc/base/CoreSegmentQueryProcessorBase.h server/query_proc/base/MemoryQueryProcessorBase.h - server/query_proc/ltm.h - server/query_proc/wm.h + server/query_proc/ltm/detail/EntityQueryProcessorBase.h + server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.h + server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.h + server/query_proc/ltm/detail/MemoryQueryProcessorBase.h + server/query_proc/ltm/ltm.h + + server/query_proc/wm/detail/EntityQueryProcessorBase.h + server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.h + server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.h + server/query_proc/wm/detail/MemoryQueryProcessorBase.h + server/query_proc/wm/wm.h mns.h diff --git a/source/RobotAPI/libraries/armem/core/wm/aron_conversions.cpp b/source/RobotAPI/libraries/armem/core/wm/aron_conversions.cpp index 04dadb72a..91b1a6584 100644 --- a/source/RobotAPI/libraries/armem/core/wm/aron_conversions.cpp +++ b/source/RobotAPI/libraries/armem/core/wm/aron_conversions.cpp @@ -5,65 +5,60 @@ namespace armarx::armem { - - constexpr const char* DATA_WRAPPER_DATA_FIELD = "__ARON_DATA"; constexpr const char* DATA_WRAPPER_TIME_STORED_FIELD = "__WRITER_METADATA__TIME_STORED"; constexpr const char* DATA_WRAPPER_TIME_CREATED_FIELD = "__ENTITY_METADATA__TIME_CREATED"; constexpr const char* DATA_WRAPPER_TIME_SENT_FIELD = "__ENTITY_METADATA__TIME_SENT"; constexpr const char* DATA_WRAPPER_TIME_ARRIVED_FIELD = "__ENTITY_METADATA__TIME_ARRIVED"; constexpr const char* DATA_WRAPPER_CONFIDENCE_FIELD = "__ENTITY_METADATA__CONFIDENCE"; - } -void armarx::armem::from_aron(const aron::data::DictPtr& dataWrapped, wm::EntityInstance& e) +void armarx::armem::from_aron(const aron::data::DictPtr& metadata, const aron::data::DictPtr& data, wm::EntityInstance& e) { - wm::EntityInstanceMetadata& metadata = e.metadata(); + ARMARX_CHECK_NOT_NULL(metadata); + // Todo: What if data is null? + + wm::EntityInstanceMetadata& m = e.metadata(); - if (dataWrapped->hasElement(DATA_WRAPPER_DATA_FIELD)) - { - e.data() = aron::data::Dict::DynamicCastAndCheck(dataWrapped->getElement(DATA_WRAPPER_DATA_FIELD)); - } + e.data() = data; - auto timeCreated = aron::data::Long::DynamicCastAndCheck(dataWrapped->getElement(DATA_WRAPPER_TIME_CREATED_FIELD)); - metadata.timeCreated = Time::microSeconds(timeCreated->toAronLongPtr()->value); + auto timeCreated = aron::data::Long::DynamicCastAndCheck(metadata->getElement(DATA_WRAPPER_TIME_CREATED_FIELD)); + m.timeCreated = Time::microSeconds(timeCreated->toAronLongPtr()->value); - auto timeSent = aron::data::Long::DynamicCastAndCheck(dataWrapped->getElement(DATA_WRAPPER_TIME_SENT_FIELD)); - metadata.timeSent = Time::microSeconds(timeSent->toAronLongPtr()->value); + auto timeSent = aron::data::Long::DynamicCastAndCheck(metadata->getElement(DATA_WRAPPER_TIME_SENT_FIELD)); + m.timeSent = Time::microSeconds(timeSent->toAronLongPtr()->value); - auto timeArrived = aron::data::Long::DynamicCastAndCheck(dataWrapped->getElement(DATA_WRAPPER_TIME_ARRIVED_FIELD)); - metadata.timeArrived = Time::microSeconds(timeArrived->toAronLongPtr()->value); + auto timeArrived = aron::data::Long::DynamicCastAndCheck(metadata->getElement(DATA_WRAPPER_TIME_ARRIVED_FIELD)); + m.timeArrived = Time::microSeconds(timeArrived->toAronLongPtr()->value); - auto confidence = aron::data::Double::DynamicCastAndCheck(dataWrapped->getElement(DATA_WRAPPER_CONFIDENCE_FIELD)); - metadata.confidence = static_cast<float>(confidence->toAronDoublePtr()->value); + auto confidence = aron::data::Double::DynamicCastAndCheck(metadata->getElement(DATA_WRAPPER_CONFIDENCE_FIELD)); + m.confidence = static_cast<float>(confidence->toAronDoublePtr()->value); } -void armarx::armem::to_aron(aron::data::DictPtr& a, const wm::EntityInstance& e) +void armarx::armem::to_aron(aron::data::DictPtr& metadata, aron::data::DictPtr& data, const wm::EntityInstance& e) { - if (e.data()) - { - a->addElement(DATA_WRAPPER_DATA_FIELD, e.data()); - } + data = e.data(); + metadata = std::make_shared<aron::data::Dict>(); auto timeWrapped = std::make_shared<aron::data::Long>(); timeWrapped->setValue(Time::now().toMicroSeconds()); - a->addElement(DATA_WRAPPER_TIME_STORED_FIELD, timeWrapped); + metadata->addElement(DATA_WRAPPER_TIME_STORED_FIELD, timeWrapped); - const wm::EntityInstanceMetadata& metadata = e.metadata(); + const wm::EntityInstanceMetadata& m = e.metadata(); auto timeCreated = std::make_shared<aron::data::Long>(); - timeCreated->setValue(metadata.timeCreated.toMicroSeconds()); - a->addElement(DATA_WRAPPER_TIME_CREATED_FIELD, timeCreated); + timeCreated->setValue(m.timeCreated.toMicroSeconds()); + metadata->addElement(DATA_WRAPPER_TIME_CREATED_FIELD, timeCreated); auto timeSent = std::make_shared<aron::data::Long>(); - timeSent->setValue(metadata.timeSent.toMicroSeconds()); - a->addElement(DATA_WRAPPER_TIME_SENT_FIELD, timeSent); + timeSent->setValue(m.timeSent.toMicroSeconds()); + metadata->addElement(DATA_WRAPPER_TIME_SENT_FIELD, timeSent); auto timeArrived = std::make_shared<aron::data::Long>(); - timeArrived->setValue(metadata.timeArrived.toMicroSeconds()); - a->addElement(DATA_WRAPPER_TIME_ARRIVED_FIELD, timeArrived); + timeArrived->setValue(m.timeArrived.toMicroSeconds()); + metadata->addElement(DATA_WRAPPER_TIME_ARRIVED_FIELD, timeArrived); auto confidence = std::make_shared<aron::data::Double>(); - confidence->setValue(static_cast<double>(metadata.confidence)); - a->addElement(DATA_WRAPPER_CONFIDENCE_FIELD, confidence); + confidence->setValue(static_cast<double>(m.confidence)); + metadata->addElement(DATA_WRAPPER_CONFIDENCE_FIELD, confidence); } diff --git a/source/RobotAPI/libraries/armem/core/wm/aron_conversions.h b/source/RobotAPI/libraries/armem/core/wm/aron_conversions.h index 21429da7f..d5de002ba 100644 --- a/source/RobotAPI/libraries/armem/core/wm/aron_conversions.h +++ b/source/RobotAPI/libraries/armem/core/wm/aron_conversions.h @@ -7,6 +7,9 @@ namespace armarx::armem { - void from_aron(const aron::data::DictPtr&, wm::EntityInstance&); - void to_aron(aron::data::DictPtr&, const wm::EntityInstance&); + /// convert from metadata and data aron instance + void from_aron(const aron::data::DictPtr& metadata, const aron::data::DictPtr& data, wm::EntityInstance&); + + /// convert to metadata and aron instance + void to_aron(aron::data::DictPtr& metadata, aron::data::DictPtr& data, const wm::EntityInstance&); } diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp index 625d76b96..eb79ed3bf 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp +++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp @@ -1,7 +1,7 @@ #include "MemoryToIceAdapter.h" -#include "query_proc/wm.h" -#include "query_proc/ltm.h" +#include "query_proc/wm/wm.h" +#include "query_proc/ltm/ltm.h" #include <RobotAPI/libraries/armem/server/wm/ice_conversions.h> @@ -243,11 +243,8 @@ namespace armarx::armem::server input.withData ? armem::DataMode::WithData : armem::DataMode::NoData); armem::wm::Memory wmResult = wmServerProcessor.process(input.memoryQueries, *workingMemory); - armem::wm::Memory cacheAndLut = longtermMemory->getCache(); - cacheAndLut.append(longtermMemory->getLUT()); - - query_proc::ltm::MemoryQueryProcessor ltmProcessor; - armem::wm::Memory ltmResult = ltmProcessor.process(input, cacheAndLut); + query_proc::ltm_server::MemoryQueryProcessor ltmProcessor; + armem::wm::Memory ltmResult = ltmProcessor.process(input, *longtermMemory); armem::query::data::Result result; if (not ltmResult.empty()) @@ -330,6 +327,7 @@ namespace armarx::armem::server armem::wm::Memory m; fromIce(queryResult.memory, m); longtermMemory->append(m); + longtermMemory->storeBuffer(); } return output; diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h index 7e45ab6f1..33e788ff5 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h +++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h @@ -4,7 +4,7 @@ #include <RobotAPI/interface/armem/client/MemoryListenerInterface.h> #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> -#include <RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.h> +#include <RobotAPI/libraries/armem/server/ltm/disk/Memory.h> #include <RobotAPI/libraries/armem/client/Query.h> #include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> diff --git a/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.cpp b/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.cpp deleted file mode 100644 index 0eff25718..000000000 --- a/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "LongtermMemoryBase.h" - -#include <ArmarXCore/core/logging/Logging.h> -#include <ArmarXCore/core/time/TimeUtil.h> - -#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> - - -namespace armarx::armem::server::ltm -{ - - MemoryBase::MemoryBase(const std::string& s) - { - std::lock_guard l(ltm_mutex); - setName(s); - } - - void MemoryBase::setName(const std::string& name) - { - std::lock_guard l(ltm_mutex); - cache.name() = name; - lut.name() = name; - } - - - armem::wm::Memory MemoryBase::getCache() const - { - std::lock_guard l(ltm_mutex); - return cache; - } - - armem::wm::Memory MemoryBase::getLUT() const - { - std::lock_guard l(ltm_mutex); - return lut; - } - - armem::wm::Memory MemoryBase::convert() - { - std::lock_guard l(ltm_mutex); - armem::wm::Memory tmp = cache; - tmp.append(lut); - convert(tmp); - return tmp; - } - - template <class ...Args> - void MemoryBase::_append(const armem::base::MemoryBase<Args...>& memory) - { - TIMING_START(LTM_Append); - ARMARX_INFO << "Append memory with name '" << memory.name() << "' into the cache of the LTM with name '" << cache.name() << "'"; - - std::lock_guard l(ltm_mutex); - cache.append(memory); - - TIMING_END_STREAM(LTM_Append, ARMARX_DEBUG); - } - - - void MemoryBase::append(const armem::wm::Memory& memory) - { - this->_append(memory); - } - - - void MemoryBase::append(const armem::server::wm::Memory& memory) - { - this->_append(memory); - } - - void MemoryBase::moveCacheToLUTAndClearCache() - { - cache.forEachInstance([](armem::wm::EntityInstance & i) - { - i.data() = nullptr; - }); - - lut.append(cache); - cache.clear(); - } - - void MemoryBase::checkUpdateLatestSnapshot(const armem::wm::EntitySnapshot& newSnapshot) - { - if (auto it = latestSnapshots.find(newSnapshot.id().getEntityID()); it != latestSnapshots.end()) - { - auto& ptr = it->second; - if (ptr->id().timestamp < newSnapshot.id().timestamp) - { - ptr = &newSnapshot; - } - // else ignore ==> no update - } - else - { - // no entry yet - latestSnapshots.emplace(newSnapshot.id().getEntityID().str(), &newSnapshot); - } - } - -} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.h deleted file mode 100644 index 0514eec76..000000000 --- a/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include <map> -#include <mutex> -#include <optional> -#include <string> - -#include <RobotAPI/libraries/armem/core/MemoryID.h> -#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> -#include <RobotAPI/libraries/armem/server/forward_declarations.h> - - -namespace armarx::armem::server::ltm -{ - /// @brief Interface functions for the longterm memory classes - class MemoryBase - { - public: - MemoryBase() = default; - MemoryBase(const std::string&); - - void append(const armem::wm::Memory& memory); - void append(const armem::server::wm::Memory& memory); - - /// reload the lut content from the long-term memory - virtual void reload() = 0; - - /// convert the references of the input into a wm::Memory - virtual void convert(armem::wm::Memory&) = 0; - - /// convert the references of the cache and the LUT into a wm::Memory - armem::wm::Memory convert(); - - /// encode the content in the cache and store it in the long-term memory - virtual void encodeAndStore() = 0; - - /// set the name of this memory - void setName(const std::string& name); - - armem::wm::Memory getCache() const; - armem::wm::Memory getLUT() const; - - protected: - void moveCacheToLUTAndClearCache(); - void checkUpdateLatestSnapshot(const armem::wm::EntitySnapshot& newSnapshot); - - protected: - mutable std::recursive_mutex ltm_mutex; - - /// Internal memory for data consolidated from wm to ltm (cache) - /// The to-put-to-ltm cache (contains data in plain text) - armem::wm::Memory cache; - - /// Internal memory for indexes (lut) - /// It contains indexes to all memory entries (TODO!) - armem::wm::Memory lut; - - /// A map from entityID to its latest snapshot stored. - /// When adding a new snapshot we compare it to the last one stored without querying the long-term memory - std::map<MemoryID, const armem::wm::EntitySnapshot*> latestSnapshots; - - - private: - - template <class ...Args> - void _append(const armem::base::MemoryBase<Args...>& memory); - - }; -} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/BufferedMemoryBase.cpp b/source/RobotAPI/libraries/armem/server/ltm/detail/BufferedMemoryBase.cpp new file mode 100644 index 000000000..864266ce8 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/BufferedMemoryBase.cpp @@ -0,0 +1,7 @@ +#include "BufferedMemoryBase.h" + +namespace armarx::armem::server::ltm +{ + + +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/BufferedMemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/BufferedMemoryBase.h new file mode 100644 index 000000000..aabceb4c0 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/BufferedMemoryBase.h @@ -0,0 +1,45 @@ +#pragma once + +#include "MemoryBase.h" + +namespace armarx::armem::server::ltm +{ + template <class _CoreSegmentT> + class BufferedMemoryBase : virtual public MemoryBase<_CoreSegmentT> + { + public: + using MemoryBase<_CoreSegmentT>::MemoryBase; + BufferedMemoryBase(const MemoryID&) = delete; // remove non-default constructor + + armem::wm::Memory getBuffer() const + { + std::lock_guard l(this->ltm_mutex); + return buffer; + } + + void storeBuffer() + { + this->store(buffer); + buffer.clear(); + } + + void setMemoryID(const MemoryID& id) override + { + MemoryBase<_CoreSegmentT>::setMemoryID(id); + buffer.name() = this->name(); + } + + void append(const armem::wm::Memory& memory) override + { + std::lock_guard l(this->ltm_mutex); + buffer.append(memory); + } + + protected: + + /// Internal memory for data consolidated from wm to ltm (buffer) + /// The to-put-to-ltm buffer (contains data in plain text) + armem::wm::Memory buffer; + + }; +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.cpp b/source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.cpp new file mode 100644 index 000000000..cdeac5414 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.cpp @@ -0,0 +1,6 @@ +#include "CoreSegmentBase.h" + +namespace armarx::armem::server::ltm +{ + +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.h new file mode 100644 index 000000000..807d45f20 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/CoreSegmentBase.h @@ -0,0 +1,56 @@ +#pragma once + +#include <functional> + +// BaseClass +#include "MemoryItem.h" + +#include "ProviderSegmentBase.h" + +#include <RobotAPI/libraries/armem/core/MemoryID.h> +#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/core/wm/aron_conversions.h> + +namespace armarx::armem::server::ltm +{ + /// @brief Interface functions for the longterm memory classes + template <class _ProviderSegmentT> + class CoreSegmentBase : public MemoryItem + { + public: + using ProviderSegmentT = _ProviderSegmentT; + + using MemoryItem::MemoryItem; + + /// return the full sub-ltm as a wm::CoreSegment with only references + /// the ltm may be huge, use with caution + virtual armem::wm::CoreSegment loadAll() = 0; + + /// convert the references of the input into a wm::Memory + virtual void convert(armem::wm::CoreSegment&) = 0; + + /// encode the content of a wm::Memory and store + virtual void store(const armem::wm::CoreSegment&) = 0; + + /// iterate over all provider segments of this ltm + virtual bool forEachProviderSegment(std::function<void(ProviderSegmentT&)>&& func) const = 0; + + /// find provider segment + virtual std::shared_ptr<ProviderSegmentT> findProviderSegment(const std::string&) const = 0; + + /// get aron type + aron::type::ObjectPtr aronType() const + { + return nullptr; + } + + /// get level name + static std::string getLevelName() + { + return "LT-CoreSegment"; + } + + protected: + mutable std::recursive_mutex ltm_mutex; + }; +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.cpp b/source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.cpp new file mode 100644 index 000000000..a0f93fc47 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.cpp @@ -0,0 +1,10 @@ +#include "EntityBase.h" + +#include <ArmarXCore/core/logging/Logging.h> +#include <ArmarXCore/core/time/TimeUtil.h> + +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> + +namespace armarx::armem::server::ltm +{ +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.h new file mode 100644 index 000000000..49dcbbee0 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/EntityBase.h @@ -0,0 +1,58 @@ +#pragma once + +#include <functional> + +// BaseClass +#include "MemoryItem.h" + +#include "EntitySnapshotBase.h" + +#include <RobotAPI/libraries/armem/core/MemoryID.h> +#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/core/wm/aron_conversions.h> + +namespace armarx::armem::server::ltm +{ + /// @brief Interface functions for the longterm memory classes + template <class _EntitySnapshotT> + class EntityBase : public MemoryItem + { + public: + using EntitySnapshotT = _EntitySnapshotT; + + using MemoryItem::MemoryItem; + + /// return the full sub-ltm as a wm::Entity with only references + /// the ltm may be huge, use with caution + virtual armem::wm::Entity loadAll() = 0; + + /// convert the references of the input into a wm::Memory + virtual void convert(armem::wm::Entity&) = 0; + + /// encode the content of a wm::Memory and store + virtual void store(const armem::wm::Entity&) = 0; + + /// iterate over all entity snapshots of this ltm + virtual bool forEachSnapshot(std::function<void(EntitySnapshotT&)>&& func) const = 0; + virtual bool forEachSnapshotInIndexRange(long first, long last, std::function<void(EntitySnapshotT&)>&& func) const = 0; + virtual bool forEachSnapshotInTimeRange(const Time& min, const Time& max, std::function<void(EntitySnapshotT&)>&& func) const = 0; + virtual bool forEachSnapshotBeforeOrAt(const Time& time, std::function<void(EntitySnapshotT&)>&& func) const = 0; + virtual bool forEachSnapshotBefore(const Time& time, std::function<void(EntitySnapshotT&)>&& func) const = 0; + + /// find entity snapshot segment + virtual std::shared_ptr<EntitySnapshotT> findSnapshot(const Time&) const = 0; + virtual std::shared_ptr<EntitySnapshotT> findLatestSnapshot() const = 0; + virtual std::shared_ptr<EntitySnapshotT> findLatestSnapshotBefore(const Time& time) const = 0; + virtual std::shared_ptr<EntitySnapshotT> findLatestSnapshotBeforeOrAt(const Time& time) const = 0; + virtual std::shared_ptr<EntitySnapshotT> findFirstSnapshotAfter(const Time& time) const = 0; + virtual std::shared_ptr<EntitySnapshotT> findFirstSnapshotAfterOrAt(const Time& time) const = 0; + + static std::string getLevelName() + { + return "LT-Entity"; + } + + protected: + mutable std::recursive_mutex ltm_mutex; + }; +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.cpp b/source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.cpp new file mode 100644 index 000000000..1b053d008 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.cpp @@ -0,0 +1,14 @@ +#include "EntitySnapshotBase.h" + +#include <ArmarXCore/core/logging/Logging.h> +#include <ArmarXCore/core/time/TimeUtil.h> + +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> + +namespace armarx::armem::server::ltm +{ + std::string EntitySnapshotBase::getLevelName() + { + return "LT-EntitySnapshot"; + } +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.h new file mode 100644 index 000000000..027ac262f --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/EntitySnapshotBase.h @@ -0,0 +1,36 @@ +#pragma once + +#include <functional> + +// BaseClass +#include "MemoryItem.h" + +#include <RobotAPI/libraries/armem/core/MemoryID.h> +#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/core/wm/aron_conversions.h> + +namespace armarx::armem::server::ltm +{ + /// @brief Interface functions for the longterm memory classes + class EntitySnapshotBase : public MemoryItem + { + public: + + using MemoryItem::MemoryItem; + + /// return the full sub-ltm as a wm::EntitySnapshot with only references + /// the ltm may be huge, use with caution + virtual armem::wm::EntitySnapshot loadAll() const = 0; + + /// convert the references of the input into a wm::Memory + virtual void convert(armem::wm::EntitySnapshot&) const = 0; + + /// encode the content of a wm::Memory and store + virtual void store(const armem::wm::EntitySnapshot&) const = 0; + + static std::string getLevelName(); + + protected: + mutable std::recursive_mutex ltm_mutex; + }; +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/LUTMemoryBase.cpp b/source/RobotAPI/libraries/armem/server/ltm/detail/LUTMemoryBase.cpp new file mode 100644 index 000000000..1078e776d --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/LUTMemoryBase.cpp @@ -0,0 +1,6 @@ +#include "LUTMemoryBase.h" + +namespace armarx::armem::server::ltm +{ + +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/LUTMemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/LUTMemoryBase.h new file mode 100644 index 000000000..49d05ab2b --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/LUTMemoryBase.h @@ -0,0 +1,47 @@ +#pragma once + +#include "MemoryBase.h" + +namespace armarx::armem::server::ltm +{ + template <class _CoreSegmentT> + class LUTMemoryBase : virtual public MemoryBase<_CoreSegmentT> + { + public: + using MemoryBase<_CoreSegmentT>::MemoryBase; + + armem::wm::Memory getLUT() const + { + std::lock_guard l(this->ltm_mutex); + return lut; + } + + void setMemoryID(const MemoryID& id) override + { + MemoryBase<_CoreSegmentT>::setMemoryID(id); + lut.name() = this->name(); + } + + protected: + static bool EntitySnapshotHasData(const armem::wm::EntitySnapshot& e) + { + // check whether all data is nullptr + bool allDataIsNull = e.size() > 0; + e.forEachInstance([&allDataIsNull](armem::wm::EntityInstance & e) + { + if (e.data()) + { + allDataIsNull = false; + return false; // means break + } + return true; + }); + return !allDataIsNull; + } + + protected: + + armem::wm::Memory lut; + + }; +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.cpp b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.cpp new file mode 100644 index 000000000..3375b372d --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.cpp @@ -0,0 +1,6 @@ +#include "MemoryBase.h" + +namespace armarx::armem::server::ltm +{ + +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h new file mode 100644 index 000000000..919619488 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryBase.h @@ -0,0 +1,55 @@ +#pragma once + +#include <functional> + +// BaseClass +#include "MemoryItem.h" + +#include "CoreSegmentBase.h" + +#include <RobotAPI/libraries/armem/core/MemoryID.h> +#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/core/wm/aron_conversions.h> + +namespace armarx::armem::server::ltm +{ + /// @brief Interface functions for the longterm memory classes + template <class _CoreSegmentT> + class MemoryBase : public MemoryItem + { + public: + using CoreSegmentT = _CoreSegmentT; + + using MemoryItem::MemoryItem; + + /// return the full ltm as a wm::Memory with only references + /// the ltm may be huge, use with caution + virtual armem::wm::Memory loadAll() = 0; + + /// append a wm::Memory instance to the ltm + virtual void append(const armem::wm::Memory& memory) = 0; + + /// convert the references of the input into a wm::Memory + virtual void convert(armem::wm::Memory&) = 0; + + /// encode the content of a wm::Memory and store + virtual void store(const armem::wm::Memory&) = 0; + + /// iterate over all core segments of this ltm + virtual bool forEachCoreSegment(std::function<void(CoreSegmentT&)>&& func) const = 0; + + /// find core segment + virtual std::shared_ptr<CoreSegmentT> findCoreSegment(const std::string&) const = 0; + + /// get level name + static std::string getLevelName() + { + return "LT-Memory"; + } + + protected: + mutable std::recursive_mutex ltm_mutex; + + + }; +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.cpp b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.cpp new file mode 100644 index 000000000..0187962b3 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.cpp @@ -0,0 +1,28 @@ +#include "MemoryItem.h" + +#include <ArmarXCore/core/logging/Logging.h> +#include <ArmarXCore/core/time/TimeUtil.h> + +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> + +namespace armarx::armem::server::ltm +{ + MemoryItem::MemoryItem(const MemoryID& id) : _id(id) + { + } + + void MemoryItem::setMemoryID(const MemoryID& id) + { + _id = id; + } + + MemoryID MemoryItem::id() const + { + return _id; + } + + std::string MemoryItem::name() const + { + return _id.getLeafItem(); + } +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.h b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.h new file mode 100644 index 000000000..7309bbd59 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/MemoryItem.h @@ -0,0 +1,27 @@ +#pragma once + +#include <map> +#include <mutex> +#include <optional> +#include <string> + +#include <RobotAPI/libraries/armem/core/MemoryID.h> + +namespace armarx::armem::server::ltm +{ + /// @brief Interface functions for the longterm memory classes + class MemoryItem + { + public: + MemoryItem() = default; + MemoryItem(const MemoryID&); + + MemoryID id() const; + std::string name() const; + + virtual void setMemoryID(const MemoryID&); + + private: + MemoryID _id; + }; +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.cpp b/source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.cpp new file mode 100644 index 000000000..15a2cc306 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.cpp @@ -0,0 +1,11 @@ +#include "ProviderSegmentBase.h" + +#include <ArmarXCore/core/logging/Logging.h> +#include <ArmarXCore/core/time/TimeUtil.h> + +#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> + +namespace armarx::armem::server::ltm +{ + +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.h b/source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.h new file mode 100644 index 000000000..9294a6c19 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/detail/ProviderSegmentBase.h @@ -0,0 +1,56 @@ +#pragma once + +#include <functional> + +// BaseClass +#include "MemoryItem.h" + +#include "EntityBase.h" + +#include <RobotAPI/libraries/armem/core/MemoryID.h> +#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> +#include <RobotAPI/libraries/armem/core/wm/aron_conversions.h> + +namespace armarx::armem::server::ltm +{ + /// @brief Interface functions for the longterm memory classes + template <class _EntityT> + class ProviderSegmentBase : public MemoryItem + { + public: + using EntityT = _EntityT; + + using MemoryItem::MemoryItem; + + /// return the full sub-ltm as a wm::ProviderSegment with only references + /// the ltm may be huge, use with caution + virtual armem::wm::ProviderSegment loadAll() = 0; + + /// convert the references of the input into a wm::Memory + virtual void convert(armem::wm::ProviderSegment&) = 0; + + /// encode the content of a wm::Memory and store + virtual void store(const armem::wm::ProviderSegment&) = 0; + + /// iterate over all core segments of this ltm + virtual bool forEachEntity(std::function<void(EntityT&)>&& func) const = 0; + + /// find entity segment + virtual std::shared_ptr<EntityT> findEntity(const std::string&) const = 0; + + aron::type::ObjectPtr aronType() const + { + return nullptr; + } + + static std::string getLevelName() + { + return "LT-ProviderSegment"; + } + + protected: + + protected: + mutable std::recursive_mutex ltm_mutex; + }; +} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp new file mode 100644 index 000000000..5de81875d --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp @@ -0,0 +1,100 @@ +// Header +#include "CoreSegment.h" + +// ArmarX +#include <ArmarXCore/core/time/TimeUtil.h> +#include <ArmarXCore/core/logging/Logging.h> + +namespace armarx::armem::server::ltm::disk +{ + namespace + { + MemoryID getMemoryIDFromPath(const std::filesystem::path& p) + { + util::ensureFolderExists(p); + + MemoryID m; + m.memoryName = p.parent_path().filename(); + m.coreSegmentName = p.filename(); + return m; + } + } + + CoreSegment::CoreSegment(const std::filesystem::path& p) : + CoreSegmentBase(getMemoryIDFromPath(p)), + DiskStorage(p) + { + } + + bool CoreSegment::forEachProviderSegment(std::function<void(ProviderSegment&)>&& func) const + { + if (!checkPath()) + { + return false; + } + + std::filesystem::path p = path; + util::ensureFolderExists(p, false); + + for (const auto& subdir : std::filesystem::directory_iterator(p)) + { + std::filesystem::path subdirPath = subdir.path(); + ProviderSegment c(subdirPath); + func(c); + } + return true; + } + + std::shared_ptr<ProviderSegment> CoreSegment::findProviderSegment(const std::string& n) const + { + if (!checkPath()) + { + return {}; + } + + std::filesystem::path p = path; + util::ensureFolderExists(p, false); + + std::filesystem::path subpath = p / n; + util::ensureFolderExists(subpath, false); + auto c = std::make_shared<ProviderSegment>(subpath); + return c; + } + + std::string CoreSegment::getExpectedFolderName() const + { + return name(); + } + + armem::wm::CoreSegment CoreSegment::loadAll() + { + armem::wm::CoreSegment e(id()); + + forEachProviderSegment([&e](ProviderSegment& x) { + auto s = x.loadAll(); + e.addProviderSegment(s); + }); + + return e; + } + + void CoreSegment::convert(armem::wm::CoreSegment& c) + { + c.forEachProviderSegment([this](armem::wm::ProviderSegment& e) + { + util::ensureFolderExists(std::filesystem::path(path) / e.id().providerSegmentName, false); + ProviderSegment c(std::filesystem::path(path) / e.id().providerSegmentName); + c.convert(e); + }); + } + + void CoreSegment::store(const armem::wm::CoreSegment& c) + { + c.forEachProviderSegment([this](const armem::wm::ProviderSegment& e) + { + util::ensureFolderExists(std::filesystem::path(path) / e.id().providerSegmentName); + ProviderSegment c(std::filesystem::path(path) / e.id().providerSegmentName); + c.store(e); + }); + } +} diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h new file mode 100644 index 000000000..1ec95bd79 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h @@ -0,0 +1,33 @@ +#pragma once + +#include <filesystem> + +// Base Class +#include "../detail/CoreSegmentBase.h" +#include "detail/DiskStorage.h" + +#include "ProviderSegment.h" + +namespace armarx::armem::server::ltm::disk +{ + class CoreSegment : + public CoreSegmentBase<ProviderSegment>, + public DiskStorage + { + public: + using CoreSegmentBase::CoreSegmentBase; + CoreSegment(const std::filesystem::path&); + + armem::wm::CoreSegment loadAll() override; + void convert(armem::wm::CoreSegment&) override; + void store(const armem::wm::CoreSegment&) override; + + bool forEachProviderSegment(std::function<void(ProviderSegment&)>&& func) const override; + + std::shared_ptr<ProviderSegment> findProviderSegment(const std::string&) const override; + + protected: + std::string getExpectedFolderName() const override; + }; + +} // namespace armarx::armem::server::ltm::disk diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp new file mode 100644 index 000000000..5ddabc38e --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp @@ -0,0 +1,148 @@ +// Header +#include "Entity.h" + +// ArmarX +#include <ArmarXCore/core/time/TimeUtil.h> +#include <ArmarXCore/core/logging/Logging.h> + +namespace armarx::armem::server::ltm::disk +{ + + namespace + { + MemoryID getMemoryIDFromPath(const std::filesystem::path& p) + { + util::ensureFolderExists(p); + + MemoryID m; + m.memoryName = p.parent_path().parent_path().parent_path().filename(); + m.coreSegmentName = p.parent_path().parent_path().filename(); + m.providerSegmentName = p.parent_path().filename(); + m.entityName = p.filename(); + return m; + } + } + + Entity::Entity(const std::filesystem::path& p) : + EntityBase(getMemoryIDFromPath(p)), + DiskStorage(p) + { + } + + std::string Entity::getExpectedFolderName() const + { + return name(); + } + + bool Entity::forEachSnapshot(std::function<void(EntitySnapshot&)>&& func) const + { + if (!checkPath()) + { + return false; + } + + std::filesystem::path p = path; + util::ensureFolderExists(p, false); + + for (const auto& subdir : std::filesystem::directory_iterator(p)) + { + std::filesystem::path subdirPath = subdir.path(); + EntitySnapshot c(subdirPath); + func(c); + } + return true; + } + + bool Entity::forEachSnapshotInIndexRange(long first, long last, std::function<void(EntitySnapshot&)>&& func) const + { + return true; + } + + bool Entity::forEachSnapshotInTimeRange(const Time& min, const Time& max, std::function<void(EntitySnapshot&)>&& func) const + { + return true; + } + + bool Entity::forEachSnapshotBeforeOrAt(const Time& time, std::function<void(EntitySnapshot&)>&& func) const + { + return true; + } + + bool Entity::forEachSnapshotBefore(const Time& time, std::function<void(EntitySnapshot&)>&& func) const + { + return true; + } + + std::shared_ptr<EntitySnapshot> Entity::findSnapshot(const Time& n) const + { + if (!checkPath()) + { + return {}; + } + + std::filesystem::path p = path; + util::ensureFolderExists(p, false); + + std::filesystem::path subpath = p / std::to_string(n.toMicroSeconds()); + util::ensureFolderExists(subpath, false); + auto c = std::make_shared<EntitySnapshot>(subpath); + return c; + } + + std::shared_ptr<EntitySnapshot> Entity::findLatestSnapshot() const + { + return {}; + } + + std::shared_ptr<EntitySnapshot> Entity::findLatestSnapshotBefore(const Time& time) const + { + return {}; + } + + std::shared_ptr<EntitySnapshot> Entity::findLatestSnapshotBeforeOrAt(const Time& time) const + { + return {}; + } + + std::shared_ptr<EntitySnapshot> Entity::findFirstSnapshotAfter(const Time& time) const + { + return {}; + } + + std::shared_ptr<EntitySnapshot> Entity::findFirstSnapshotAfterOrAt(const Time& time) const + { + return {}; + } + + armem::wm::Entity Entity::loadAll() + { + armem::wm::Entity e(id()); + + forEachSnapshot([&e](EntitySnapshotBase& x) { + auto s = x.loadAll(); + e.addSnapshot(s); + }); + + return e; + } + + void Entity::convert(armem::wm::Entity& p) + { + p.forEachSnapshot([this](armem::wm::EntitySnapshot& e) + { + util::ensureFolderExists(std::filesystem::path(path) / std::to_string(e.id().timestamp.toMicroSeconds()), false); + EntitySnapshot c(std::filesystem::path(path) / std::to_string(e.id().timestamp.toMicroSeconds())); + c.store(e); + }); + } + + void Entity::store(const armem::wm::Entity& c) + { + c.forEachSnapshot([this](armem::wm::EntitySnapshot& e) + { + util::ensureFolderExists(std::filesystem::path(path) / std::to_string(e.id().timestamp.toMicroSeconds())); + EntitySnapshot c(std::filesystem::path(path) / std::to_string(e.id().timestamp.toMicroSeconds())); + c.store(e); + }); + } +} diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h new file mode 100644 index 000000000..3d0aacfb3 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h @@ -0,0 +1,43 @@ +#pragma once + +#include <filesystem> + +// Base Class +#include "../detail/EntityBase.h" +#include "detail/DiskStorage.h" + +#include "EntitySnapshot.h" + +namespace armarx::armem::server::ltm::disk +{ + /// @brief A memory storing data in mongodb (needs 'armarx memory start' to start the mongod instance) + class Entity : + public EntityBase<EntitySnapshot>, + public DiskStorage + { + public: + using EntityBase::EntityBase; + Entity(const std::filesystem::path&); + + armem::wm::Entity loadAll() override; + void convert(armem::wm::Entity&) override; + void store(const armem::wm::Entity&) override; + + bool forEachSnapshot(std::function<void(EntitySnapshot&)>&& func) const override; + bool forEachSnapshotInIndexRange(long first, long last, std::function<void(EntitySnapshot&)>&& func) const override; + bool forEachSnapshotInTimeRange(const Time& min, const Time& max, std::function<void(EntitySnapshot&)>&& func) const override; + bool forEachSnapshotBeforeOrAt(const Time& time, std::function<void(EntitySnapshot&)>&& func) const override; + bool forEachSnapshotBefore(const Time& time, std::function<void(EntitySnapshot&)>&& func) const override; + + std::shared_ptr<EntitySnapshot> findSnapshot(const Time&) const override; + std::shared_ptr<EntitySnapshot> findLatestSnapshot() const override; + std::shared_ptr<EntitySnapshot> findLatestSnapshotBefore(const Time& time) const override; + std::shared_ptr<EntitySnapshot> findLatestSnapshotBeforeOrAt(const Time& time) const override; + std::shared_ptr<EntitySnapshot> findFirstSnapshotAfter(const Time& time) const override; + std::shared_ptr<EntitySnapshot> findFirstSnapshotAfterOrAt(const Time& time) const override; + + protected: + std::string getExpectedFolderName() const override; + }; + +} // namespace armarx::armem::server::ltm::disk diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp new file mode 100644 index 000000000..204769226 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp @@ -0,0 +1,131 @@ +// Header +#include "EntitySnapshot.h" + +// STD / STL +#include <iostream> +#include <fstream> + +// ArmarX +#include <ArmarXCore/core/time/TimeUtil.h> +#include <ArmarXCore/core/logging/Logging.h> +#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> +#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h> + +namespace armarx::armem::server::ltm::disk +{ + + namespace + { + MemoryID getMemoryIDFromPath(const std::filesystem::path& p) + { + util::ensureFolderExists(p); + + MemoryID m; + m.memoryName = p.parent_path().parent_path().parent_path().parent_path().filename(); + m.coreSegmentName = p.parent_path().parent_path().parent_path().filename(); + m.providerSegmentName = p.parent_path().parent_path().filename(); + m.entityName = p.parent_path().filename(); + m.timestamp = IceUtil::Time::microSeconds(std::stol(p.filename())); + return m; + } + } + + EntitySnapshot::EntitySnapshot(const std::filesystem::path& p) : + EntitySnapshotBase(getMemoryIDFromPath(p)), + DiskStorage(p) + { + } + + std::string EntitySnapshot::getExpectedFolderName() const + { + return name(); + } + + armem::wm::EntitySnapshot EntitySnapshot::loadAll() const + { + std::filesystem::path p = path; + util::ensureFolderExists(p, false); + + armem::wm::EntitySnapshot e(id()); + + for (unsigned int i = 0; i < 1000; ++i) // 1000 is max size for instances in a single timestamp + { + if (!util::checkIfFolderExists(p / std::to_string(i))) + { + break; + } + + // add instance. Do not set data, since we only return references + e.addInstance(); + } + return e; + } + + void EntitySnapshot::convert(armem::wm::EntitySnapshot& e) const + { + // Get data from disk + std::filesystem::path p = path; + util::ensureFolderExists(p, false); + + for (unsigned int i = 0; i < e.size(); ++i) + { + util::ensureFolderExists(p / std::to_string(i), false); + + std::filesystem::path data = p / std::to_string(i) / constantes::DATA_FILENAME; + std::filesystem::path metadata = p / std::to_string(i) / constantes::METADATA_FILENAME; + + util::ensureFileExists(data); + + auto& ins = e.getInstance(i); + + std::ifstream dataifs(data); + std::string datafilecontent((std::istreambuf_iterator<char>(dataifs)), (std::istreambuf_iterator<char>())); + nlohmann::json datajson = nlohmann::json::parse(datafilecontent); + auto dataaron = aron::converter::AronNlohmannJSONConverter::ConvertFromNlohmannJSONObject(datajson); + + std::ifstream metadataifs(metadata); + std::string metadatafilecontent((std::istreambuf_iterator<char>(metadataifs)), (std::istreambuf_iterator<char>())); + nlohmann::json metadatajson = nlohmann::json::parse(metadatafilecontent); + auto metadataaron = aron::converter::AronNlohmannJSONConverter::ConvertFromNlohmannJSONObject(metadatajson); + + from_aron(metadataaron, dataaron, ins); + } + } + + void EntitySnapshot::store(const armem::wm::EntitySnapshot& e) const + { + std::filesystem::path p = path; + util::ensureFolderExists(p); + + for (unsigned int i = 0; i < e.size(); ++i) + { + util::ensureFolderExists(p / std::to_string(i)); + + std::filesystem::path data = p / std::to_string(i) / constantes::DATA_FILENAME; + std::filesystem::path metadata = p / std::to_string(i) / constantes::METADATA_FILENAME; + + if (util::checkIfFileExists(data) or util::checkIfFileExists(metadata)) + { + continue; + } + + auto& ins = e.getInstance(i); + + auto dataaron = std::make_shared<aron::data::Dict>(); + auto metadataaron = std::make_shared<aron::data::Dict>(); + to_aron(metadataaron, dataaron, ins); + nlohmann::json datajson = aron::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(dataaron); + nlohmann::json metadatajson = aron::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(metadataaron); + + std::ofstream dataofs; + dataofs.open(data); + dataofs << datajson.dump(2); + dataofs.close(); + + std::ofstream metadataofs; + metadataofs.open(metadata); + metadataofs << metadatajson.dump(2); + metadataofs.close(); + } + } +} diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.h b/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.h new file mode 100644 index 000000000..50d01d254 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.h @@ -0,0 +1,28 @@ +#pragma once + +#include <filesystem> + +// Base Class +#include "../detail/EntitySnapshotBase.h" +#include "detail/DiskStorage.h" + +namespace armarx::armem::server::ltm::disk +{ + + class EntitySnapshot : + public EntitySnapshotBase, + public DiskStorage + { + public: + using EntitySnapshotBase::EntitySnapshotBase; + EntitySnapshot(const std::filesystem::path&); + + armem::wm::EntitySnapshot loadAll() const override; + void convert(armem::wm::EntitySnapshot&) const override; + void store(const armem::wm::EntitySnapshot&) const override; + + protected: + std::string getExpectedFolderName() const override; + }; + +} // namespace armarx::armem::server::ltm::disk diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp new file mode 100644 index 000000000..b75a3f557 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp @@ -0,0 +1,142 @@ +// Header +#include "Memory.h" + +// ArmarX +#include <ArmarXCore/core/time/TimeUtil.h> +#include <ArmarXCore/core/logging/Logging.h> + +namespace armarx::armem::server::ltm::disk +{ + namespace + { + MemoryID getMemoryIDFromPath(const std::filesystem::path& p) + { + util::ensureFolderExists(p); + + MemoryID m; + m.memoryName = p.filename(); + return m; + } + } + + Memory::Memory() : + BufferedMemoryBase(), + DiskStorage() + { + setMemoryID(MemoryID("Test", "")); + + /*std::string armarx_home = std::string(getenv("HOME")) + "/.armarx"; + if (getenv("ARMARX_DEFAULTS_DIR")) + { + armarx_home = getenv("ARMARX_DEFAULTS_DIR"); + } + path = armarx_home + "/armem/disk/data/db";*/ + path = "/tmp/MemoryExport/" + getExpectedFolderName(); + } + + Memory::Memory(const std::filesystem::path& p) : + BufferedMemoryBase(), + DiskStorage(p) + { + setMemoryID(getMemoryIDFromPath(p)); + } + + std::string Memory::getExpectedFolderName() const + { + return id().memoryName; + } + + bool Memory::forEachCoreSegment(std::function<void(CoreSegment&)>&& func) const + { + if (!checkPath()) + { + return false; + } + + std::filesystem::path p = path; + util::ensureFolderExists(p, false); + + for (const auto& subdir : std::filesystem::directory_iterator(p)) + { + std::filesystem::path subdirPath = subdir.path(); + CoreSegment c(subdirPath); + func(c); + } + return true; + } + + std::shared_ptr<CoreSegment> Memory::findCoreSegment(const std::string& n) const + { + if (!checkPath()) + { + return {}; + } + + std::filesystem::path p = path; + util::ensureFolderExists(p, false); + + std::filesystem::path subpath = p / n; + util::ensureFolderExists(subpath, false); + auto c = std::make_shared<CoreSegment>(subpath); + return c; + } + + armem::wm::Memory Memory::loadAll() + { + TIMING_START(LTM_Memory_Load); + + armem::wm::Memory m(id()); + + forEachCoreSegment([&m](CoreSegment& x) { + auto s = x.loadAll(); + m.addCoreSegment(s); + }); + + TIMING_END_STREAM(LTM_Memory_Load, ARMARX_DEBUG); + return m; + } + + void Memory::convert(armem::wm::Memory& m) + { + TIMING_START(LTM_Memory_Convert); + + if (!checkPath()) + { + return; + } + + std::lock_guard l(ltm_mutex); + m.forEachCoreSegment([this](armem::wm::CoreSegment& e) + { + util::ensureFolderExists(std::filesystem::path(path) / e.id().coreSegmentName, false); + CoreSegment c(std::filesystem::path(path) / e.id().coreSegmentName); + c.convert(e); + }); + + TIMING_END_STREAM(LTM_Memory_Convert, ARMARX_DEBUG); + } + + void Memory::store(const armem::wm::Memory& m) + { + TIMING_START(LTM_Memory_Store); + + if (!checkPath()) + { + return; + } + + std::lock_guard l(ltm_mutex); + + m.forEachCoreSegment([this](const armem::wm::CoreSegment& e) + { + util::ensureFolderExists(std::filesystem::path(path) / e.id().coreSegmentName); + CoreSegment c(std::filesystem::path(path) / e.id().coreSegmentName); + c.store(e); + }); + + // Finaly clear cache and put reference to lut + buffer.clear(); + + TIMING_END_STREAM(LTM_Memory_Store, ARMARX_DEBUG); + } +} diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h new file mode 100644 index 000000000..a32719de2 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h @@ -0,0 +1,34 @@ +#pragma once + +#include <filesystem> + +// Base Class +#include "../detail/BufferedMemoryBase.h" +#include "detail/DiskStorage.h" + +#include "CoreSegment.h" + +namespace armarx::armem::server::ltm::disk +{ + /// @brief A memory storing data in mongodb (needs 'armarx memory start' to start the mongod instance) + class Memory : + public BufferedMemoryBase<CoreSegment>, + public DiskStorage + { + public: + using BufferedMemoryBase::BufferedMemoryBase; + Memory(); + Memory(const std::filesystem::path&); + + armem::wm::Memory loadAll() override; + void convert(armem::wm::Memory&) override; + void store(const armem::wm::Memory&) override; + + bool forEachCoreSegment(std::function<void(CoreSegment&)>&& func) const override; + + std::shared_ptr<CoreSegment> findCoreSegment(const std::string&) const override; + + protected: + std::string getExpectedFolderName() const override; + }; +} // namespace armarx::armem::server::ltm::disk diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.cpp deleted file mode 100644 index f503dc066..000000000 --- a/source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// Header -#include "MemoryManager.h" - -// ArmarX -#include <ArmarXCore/core/time/TimeUtil.h> -#include <ArmarXCore/core/logging/Logging.h> -#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> -#include <RobotAPI/libraries/armem/core/wm/aron_conversions.h> -#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h> - -#include "operations.h" - -namespace armarx::armem::server::ltm::disk -{ - Memory::Memory() : - MemoryBase() - { - std::string armarx_home = std::string(getenv("HOME")) + "/.armarx"; - if (getenv("ARMARX_DEFAULTS_DIR")) - { - armarx_home = getenv("ARMARX_DEFAULTS_DIR"); - } - memoryPathString = armarx_home + "/diskmemory/data/db"; - } - - Memory::Memory(const std::string& s) : - MemoryBase(s) - { - std::string armarx_home = std::string(getenv("HOME")) + "/.armarx"; - if (getenv("ARMARX_DEFAULTS_DIR")) - { - armarx_home = getenv("ARMARX_DEFAULTS_DIR"); - } - memoryPathString = armarx_home + "/diskmemory/data/db"; - } - - Memory::Memory(const std::filesystem::path& p) : - MemoryBase(p.filename()), - memoryPath(p) - { - } - - bool Memory::checkPath() const - { - // Check connection: - if (!std::filesystem::exists(memoryPath)) - { - std::filesystem::create_directories(memoryPath); - return true; - } - else if (!std::filesystem::is_directory(memoryPath) || memoryPath.filename() != cache.name()) - { - ARMARX_WARNING << deactivateSpam("LTM_PathError_" + cache.name()) - << "The entered path is not valid. Please use a path leading to a memory folder with name: " << cache.name() << "." - << "\n\n"; - return false; - } - - return true; - } - - void Memory::reload() - { - memoryPath = std::filesystem::path(memoryPathString); - - TIMING_START(LTM_Reload); - - if (!checkPath()) - { - return; - } - - std::lock_guard l(ltm_mutex); - armem::wm::Memory temp(lut.id()); - util::load(memoryPath, temp); - - lut.append(temp); - - TIMING_END_STREAM(LTM_Reload, ARMARX_DEBUG); - } - - void Memory::convert(armem::wm::Memory& m) - { - memoryPath = std::filesystem::path(memoryPathString); - - TIMING_START(LTM_Convert); - if (!checkPath()) - { - return; - } - - std::lock_guard l(ltm_mutex); - util::convert(memoryPath, m); - - TIMING_END_STREAM(LTM_Convert, ARMARX_DEBUG); - } - - void Memory::encodeAndStore() - { - memoryPath = std::filesystem::path(memoryPathString); - - TIMING_START(LTM_Encode); - if (!checkPath()) - { - return; - } - - std::lock_guard l(ltm_mutex); - util::store(memoryPath, cache); - - // what to do with clear text data after encoding? - // TODO! - - // Finaly clear cache and put reference to lut - moveCacheToLUTAndClearCache(); - - TIMING_END_STREAM(LTM_Encode, ARMARX_DEBUG); - } -} diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.h b/source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.h deleted file mode 100644 index 66a6a3e42..000000000 --- a/source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include <filesystem> -#include <mutex> -#include <optional> - -#include <RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.h> - - -namespace armarx::armem::server::ltm::disk -{ - /// @brief A memory storing data in mongodb (needs 'armarx memory start' to start the mongod instance) - class Memory : public MemoryBase - { - using Base = MemoryBase; - - public: - using Base::convert; - - Memory(); - Memory(const std::string&); - Memory(const std::filesystem::path&); - - void reload() override; - void convert(armem::wm::Memory&) override; - void encodeAndStore() override; - - private: - bool checkPath() const; - - public: - std::string memoryPathString; - - private: - std::filesystem::path memoryPath; - - }; - -} // namespace armarx::armem::server::ltm::disk diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp new file mode 100644 index 000000000..bc3310c11 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp @@ -0,0 +1,101 @@ +// Header +#include "ProviderSegment.h" + +// ArmarX +#include <ArmarXCore/core/time/TimeUtil.h> +#include <ArmarXCore/core/logging/Logging.h> + +namespace armarx::armem::server::ltm::disk +{ + namespace + { + MemoryID getMemoryIDFromPath(const std::filesystem::path& p) + { + util::ensureFolderExists(p); + + MemoryID m; + m.memoryName = p.parent_path().parent_path().filename(); + m.coreSegmentName = p.parent_path().filename(); + m.providerSegmentName = p.filename(); + return m; + } + } + + ProviderSegment::ProviderSegment(const std::filesystem::path& p) : + ProviderSegmentBase(getMemoryIDFromPath(p)), + DiskStorage(p) + { + } + + bool ProviderSegment::forEachEntity(std::function<void(Entity&)>&& func) const + { + if (!checkPath()) + { + return false; + } + + std::filesystem::path p = path; + util::ensureFolderExists(p, false); + + for (const auto& subdir : std::filesystem::directory_iterator(p)) + { + std::filesystem::path subdirPath = subdir.path(); + Entity c(subdirPath); + func(c); + } + return true; + } + + std::shared_ptr<Entity> ProviderSegment::findEntity(const std::string& n) const + { + if (!checkPath()) + { + return {}; + } + + std::filesystem::path p = path; + util::ensureFolderExists(p, false); + + std::filesystem::path subpath = p / n; + util::ensureFolderExists(subpath, false); + auto c = std::make_shared<Entity>(subpath); + return c; + } + + std::string ProviderSegment::getExpectedFolderName() const + { + return name(); + } + + armem::wm::ProviderSegment ProviderSegment::loadAll() + { + armem::wm::ProviderSegment e(id()); + + forEachEntity([&e](Entity& x) { + auto s = x.loadAll(); + e.addEntity(s); + }); + + return e; + } + + void ProviderSegment::convert(armem::wm::ProviderSegment& p) + { + p.forEachEntity([this](armem::wm::Entity& e) + { + util::ensureFolderExists(std::filesystem::path(path) / e.id().entityName, false); + Entity c(std::filesystem::path(path) / e.id().entityName); + c.convert(e); + }); + } + + void ProviderSegment::store(const armem::wm::ProviderSegment& p) + { + p.forEachEntity([this](const armem::wm::Entity& e) + { + util::ensureFolderExists(std::filesystem::path(path) / e.id().entityName); + Entity c(std::filesystem::path(path) / e.id().entityName); + c.store(e); + }); + } +} diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h new file mode 100644 index 000000000..265902756 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h @@ -0,0 +1,33 @@ +#pragma once + +#include <filesystem> + +// Base Class +#include "../detail/ProviderSegmentBase.h" +#include "detail/DiskStorage.h" + +#include "Entity.h" + +namespace armarx::armem::server::ltm::disk +{ + class ProviderSegment : + public ProviderSegmentBase<Entity>, + public DiskStorage + { + public: + using ProviderSegmentBase::ProviderSegmentBase; + ProviderSegment(const std::filesystem::path&); + + armem::wm::ProviderSegment loadAll() override; + void convert(armem::wm::ProviderSegment&) override; + void store(const armem::wm::ProviderSegment&) override; + + bool forEachEntity(std::function<void(Entity&)>&& func) const override; + + std::shared_ptr<Entity> findEntity(const std::string&) const override; + + protected: + std::string getExpectedFolderName() const override; + }; + +} // namespace armarx::armem::server::ltm::disk diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.cpp new file mode 100644 index 000000000..d6eef0874 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.cpp @@ -0,0 +1,7 @@ +// Header +#include "Data.h" + +namespace armarx::armem::server::ltm::disk +{ + +} diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.h b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.h new file mode 100644 index 000000000..f5dc9078f --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.h @@ -0,0 +1,65 @@ +#pragma once + +#include <filesystem> + +#include "../../../../core/error.h" + +namespace armarx::armem::server::ltm::disk +{ + namespace constantes + { + const std::string TYPE_FILENAME = "type.aron.json"; + const std::string DATA_FILENAME = "data.aron.json"; + const std::string METADATA_FILENAME = "metadata.aron.json"; + } + + namespace util + { + // check whether a string is a number (e.g. timestamp folders) + inline bool isNumber(const std::string& s) + { + for (char const& ch : s) + { + if (std::isdigit(ch) == 0) + { + return false; + } + } + return true; + } + + inline bool checkIfFolderExists(const std::filesystem::path& p) + { + return std::filesystem::exists(p) and std::filesystem::is_directory(p); + } + + inline void ensureFolderExists(const std::filesystem::path& p, bool createIfNotExistent = true) + { + if (!std::filesystem::exists(p)) + { + if (createIfNotExistent) + { + std::filesystem::create_directory(p); + } + } + if (!std::filesystem::is_directory(p)) + { + throw error::ArMemError("Could not find folder: " + p.string()); + } + } + + inline bool checkIfFileExists(const std::filesystem::path& p) + { + return std::filesystem::exists(p) and std::filesystem::is_regular_file(p); + } + + inline void ensureFileExists(const std::filesystem::path& p) + { + if (!std::filesystem::exists(p) || !std::filesystem::is_regular_file(p)) + { + // not found + throw error::ArMemError("Could not find file: " + p.string()); + } + } + } +} // namespace armarx::armem::server::ltm::disk diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/detail/DiskStorage.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/DiskStorage.cpp new file mode 100644 index 000000000..21ebd7aef --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/DiskStorage.cpp @@ -0,0 +1,40 @@ +// Header +#include "DiskStorage.h" + +// ArmarX +#include <ArmarXCore/core/time/TimeUtil.h> +#include <ArmarXCore/core/logging/Logging.h> + +namespace armarx::armem::server::ltm::disk +{ + DiskStorage::DiskStorage(const std::filesystem::path& p) : + path(p.string()) + { + } + + bool DiskStorage::checkPath() const + { + std::filesystem::path memoryP(path); + + // Check connection: + if (!std::filesystem::exists(path)) + { + std::filesystem::create_directories(path); + return true; + } + else if (std::string expectedFolderName = getExpectedFolderName(); !std::filesystem::is_directory(path) || memoryP.filename() != expectedFolderName) + { + ARMARX_WARNING << deactivateSpam("LTM_PathError_" + expectedFolderName) + << "The entered path is not valid. Please use a path leading to a memory folder with name: " << expectedFolderName << "." + << "\n\n"; + return false; + } + + return true; + } + + void DiskStorage::setPath(const std::string& p) + { + path = p; + } +} diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/detail/DiskStorage.h b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/DiskStorage.h new file mode 100644 index 000000000..201322615 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/DiskStorage.h @@ -0,0 +1,25 @@ +#pragma once + +#include <filesystem> + +#include "Data.h" + +namespace armarx::armem::server::ltm::disk +{ + class DiskStorage + { + public: + DiskStorage() = default; + DiskStorage(const std::filesystem::path&); + + void setPath(const std::string&); + + protected: + bool checkPath() const; + + virtual std::string getExpectedFolderName() const = 0; + + public: + std::string path; + }; +} // namespace armarx::armem::server::ltm::disk diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/operations.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/operations.cpp deleted file mode 100644 index 34c675762..000000000 --- a/source/RobotAPI/libraries/armem/server/ltm/disk/operations.cpp +++ /dev/null @@ -1,281 +0,0 @@ -#include "operations.h" - -// STD / STL -#include <iostream> -#include <fstream> - -// Simox -#include <SimoxUtility/json.h> - -#include "../operations.h" -#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h> -#include <RobotAPI/libraries/armem/core/wm/aron_conversions.h> - -namespace armarx::armem::server::ltm::disk::util -{ - - namespace fs = std::filesystem; - - namespace - { - // check whether a string is a number (timestamp folders) - bool isNumber(const std::string& s) - { - for (char const& ch : s) - { - if (std::isdigit(ch) == 0) - { - return false; - } - } - return true; - } - - void ensureFolderExists(const fs::path& p) - { - if (!fs::exists(p)) - { - // not found - fs::create_directory(p); - } - if (!fs::is_directory(p)) - { - throw error::ArMemError("Could not create the folder: " + p.string()); - } - } - } - - void load(const std::filesystem::path& directory, armem::wm::Memory& m) - { - for (const auto& d : std::filesystem::directory_iterator(directory)) - { - if (!d.is_directory()) - { - continue; - } - - std::string k = d.path().filename(); - if (m.hasCoreSegment(k)) - { - throw error::ArMemError("Somehow the (memory) container already contains the key k = " + k + ". This should not happen."); - } - auto& cSeg = m.addCoreSegment(k); - load((directory / k), cSeg); - } - } - - void load(const std::filesystem::path& directory, armem::wm::CoreSegment& c) - { - for (const auto& d : std::filesystem::directory_iterator(directory)) - { - if (!d.is_directory()) - { - continue; - } - - std::string k = d.path().filename(); - if (c.hasProviderSegment(k)) - { - throw error::ArMemError("Somehow the (core) container already contains the key k = " + k + ". This should not happen."); - } - auto& pSeg = c.addProviderSegment(k); - load((directory / k), pSeg); - } - } - - void load(const std::filesystem::path& directory, armem::wm::ProviderSegment& p) - { - for (const auto& d : std::filesystem::directory_iterator(directory)) - { - if (!d.is_directory()) - { - continue; - } - - std::string k = d.path().filename(); - if (p.hasEntity(k)) - { - throw error::ArMemError("Somehow the (provider) container already contains the key k = " + k + ". This should not happen."); - } - auto& eSeg = p.addEntity(k); - load((directory / k), eSeg); - } - } - - void load(const std::filesystem::path& directory, armem::wm::Entity& e) - { - for (const auto& d : std::filesystem::directory_iterator(directory)) - { - if (!d.is_directory()) - { - continue; - } - - std::string k = d.path().filename(); - if (!isNumber(k)) - { - continue; - } - - auto ts = armem::Time::microSeconds(std::stol(k)); - // TODO catch exceptions? - - if (e.hasSnapshot(ts)) - { - throw error::ArMemError("Somehow the (entity) container already contains the key k = " + k + ". This should not happen."); - } - - auto& sSeg = e.addSnapshot(ts); - for (unsigned int i = 0; i < 10000; ++i) // ugly workaround to get the folders in the correct order - { - fs::path p = d / std::to_string(i); - if (!fs::exists(p) || !fs::is_directory(p)) - { - // early stopping - break; - } - - fs::path data = p / constantes::DATA_FILENAME; - if (!fs::exists(data) || !fs::is_regular_file(data)) - { - // do not set data - continue; - } - - // else we have an instance - std::ifstream ifs(data); - std::string file_content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>())); - - nlohmann::json j = nlohmann::json::parse(file_content); - auto aron = aron::converter::AronNlohmannJSONConverter::ConvertFromNlohmannJSONObject(j); - - auto& instance = sSeg.addInstance(); - from_aron(aron, instance); - } - } - } - - void convert(const std::filesystem::path& directory, armem::wm::Memory& m) - { - m.forEachCoreSegment([&directory](armem::wm::CoreSegment & e) - { - convert((directory / e.id().coreSegmentName), e); - }); - } - - void convert(const std::filesystem::path& directory, armem::wm::CoreSegment& c) - { - c.forEachProviderSegment([&directory](armem::wm::ProviderSegment & e) - { - convert((directory / e.id().providerSegmentName), e); - }); - } - - void convert(const std::filesystem::path& directory, armem::wm::ProviderSegment& p) - { - p.forEachEntity([&directory](armem::wm::Entity & e) - { - convert((directory / e.id().entityName), e); - }); - } - - void convert(const std::filesystem::path& directory, armem::wm::Entity& e) - { - e.forEachSnapshot([&directory](armem::wm::EntitySnapshot & e) - { - if (!ltm::util::entityHasData(e)) // an entry from the lut (probably... for now we assume that every entry either has data (cache) or has null (lut)) - { - // Get data from mongodb - auto p = directory / std::to_string(e.id().timestamp.toMicroSeconds()); - - if (fs::exists(p) && fs::is_directory(p)) - { - for (unsigned int i = 0; i < e.size(); ++i) - { - auto data = p / std::to_string(i) / constantes::DATA_FILENAME; - - if (fs::exists(data) && fs::is_regular_file(data)) - { - auto& ins = e.getInstance(i); - - std::ifstream ifs(data); - std::string file_content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>())); - nlohmann::json doc = nlohmann::json::parse(file_content); - - auto aron = aron::converter::AronNlohmannJSONConverter::ConvertFromNlohmannJSONObject(doc); - - wm::EntityInstance tmp(e.id().withInstanceIndex(i)); - from_aron(aron, tmp); - - ins.data() = tmp.data(); - } - } - } - } - }); - } - - void store(const std::filesystem::path& directory, const armem::wm::Memory& m) - { - m.forEachCoreSegment([&directory](armem::wm::CoreSegment & e) - { - fs::path cPath = directory / e.id().coreSegmentName; - ensureFolderExists(cPath); - store(cPath, e); - }); - } - - void store(const std::filesystem::path& directory, const armem::wm::CoreSegment& c) - { - c.forEachProviderSegment([&directory](armem::wm::ProviderSegment & e) - { - fs::path pPath = directory / e.id().providerSegmentName; - ensureFolderExists(pPath); - store(pPath, e); - }); - } - - void store(const std::filesystem::path& directory, const armem::wm::ProviderSegment& p) - { - p.forEachEntity([&directory](armem::wm::Entity & e) - { - fs::path ePath = directory / e.id().entityName; - ensureFolderExists(ePath); - store(ePath, e); - }); - } - void store(const std::filesystem::path& directory, const armem::wm::Entity& e) - { - e.forEachSnapshot([&directory](armem::wm::EntitySnapshot & e) - { - fs::path sPath = directory / std::to_string(e.id().timestamp.toMicroSeconds()); - ensureFolderExists(sPath); - - e.forEachInstance([&sPath](armem::wm::EntityInstance & e) - { - fs::path iPath = sPath / std::to_string(e.id().instanceIndex); - if (fs::exists(iPath)) - { - // if instance already exists, we skip - return; - } - - ensureFolderExists(iPath); - - fs::path data = iPath / constantes::DATA_FILENAME; - fs::remove(data); // Should not be the case. Anyway, if it happens, create new file! - - std::ofstream ofs; - ofs.open(data); - - auto aron = std::make_shared<aron::data::Dict>(); - to_aron(aron, e); - nlohmann::json j = aron::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(aron); - - ofs << j.dump(2); - ofs.close(); - }); - }); - } - -} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/operations.h b/source/RobotAPI/libraries/armem/server/ltm/disk/operations.h deleted file mode 100644 index 5e930ff7b..000000000 --- a/source/RobotAPI/libraries/armem/server/ltm/disk/operations.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include <filesystem> - -#include <RobotAPI/libraries/armem/core/forward_declarations.h> -#include <RobotAPI/libraries/armem/server/forward_declarations.h> - - -namespace armarx::armem::server::ltm::disk -{ - - namespace constantes - { - const std::string TYPE_FILENAME = "type.aron.ltm.json"; - const std::string DATA_FILENAME = "data.aron.ltm.json"; - } - - namespace util - { - void load(const std::filesystem::path& directory, armem::wm::Memory& memory); - void load(const std::filesystem::path& directory, armem::wm::CoreSegment& memory); - void load(const std::filesystem::path& directory, armem::wm::ProviderSegment& memory); - void load(const std::filesystem::path& directory, armem::wm::Entity& memory); - - void convert(const std::filesystem::path& directory, armem::wm::Memory& memory); - void convert(const std::filesystem::path& directory, armem::wm::CoreSegment& memory); - void convert(const std::filesystem::path& directory, armem::wm::ProviderSegment& memory); - void convert(const std::filesystem::path& directory, armem::wm::Entity& memory); - - void store(const std::filesystem::path& directory, const armem::wm::Memory& memory); - void store(const std::filesystem::path& directory, const armem::wm::CoreSegment& memory); - void store(const std::filesystem::path& directory, const armem::wm::ProviderSegment& memory); - void store(const std::filesystem::path& directory, const armem::wm::Entity& memory); - } - -} // namespace armarx::armem::server::ltm::disk diff --git a/source/RobotAPI/libraries/armem/server/ltm/mongodb/ConnectionManager.cpp b/source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/ConnectionManager.cpp similarity index 100% rename from source/RobotAPI/libraries/armem/server/ltm/mongodb/ConnectionManager.cpp rename to source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/ConnectionManager.cpp diff --git a/source/RobotAPI/libraries/armem/server/ltm/mongodb/ConnectionManager.h b/source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/ConnectionManager.h similarity index 100% rename from source/RobotAPI/libraries/armem/server/ltm/mongodb/ConnectionManager.h rename to source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/ConnectionManager.h diff --git a/source/RobotAPI/libraries/armem/server/ltm/mongodb/MemoryManager.cpp b/source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/MemoryManager.cpp similarity index 100% rename from source/RobotAPI/libraries/armem/server/ltm/mongodb/MemoryManager.cpp rename to source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/MemoryManager.cpp diff --git a/source/RobotAPI/libraries/armem/server/ltm/mongodb/MemoryManager.h b/source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/MemoryManager.h similarity index 95% rename from source/RobotAPI/libraries/armem/server/ltm/mongodb/MemoryManager.h rename to source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/MemoryManager.h index 99a728f8d..6809bb596 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/mongodb/MemoryManager.h +++ b/source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/MemoryManager.h @@ -5,7 +5,7 @@ #include <optional> // Base Class -#include "../LongtermMemoryBase.h" +#include "../MemoryBase.h" // Data # include "ConnectionManager.h" diff --git a/source/RobotAPI/libraries/armem/server/ltm/mongodb/operations.cpp b/source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/operations.cpp similarity index 100% rename from source/RobotAPI/libraries/armem/server/ltm/mongodb/operations.cpp rename to source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/operations.cpp diff --git a/source/RobotAPI/libraries/armem/server/ltm/mongodb/operations.h b/source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/operations.h similarity index 100% rename from source/RobotAPI/libraries/armem/server/ltm/mongodb/operations.h rename to source/RobotAPI/libraries/armem/server/ltm/legacy/mongodb/operations.h diff --git a/source/RobotAPI/libraries/armem/server/ltm/operations.cpp b/source/RobotAPI/libraries/armem/server/ltm/operations.cpp deleted file mode 100644 index 188f0f547..000000000 --- a/source/RobotAPI/libraries/armem/server/ltm/operations.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "operations.h" - -#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> - -namespace armarx::armem::server::ltm::util -{ - bool entityHasData(const armem::wm::EntitySnapshot& e) - { - // check whether all data is nullptr - bool allDataIsNull = e.size() > 0; - e.forEachInstance([&allDataIsNull](armem::wm::EntityInstance & e) - { - if (e.data()) - { - allDataIsNull = false; - return false; // means break - } - return true; - }); - return !allDataIsNull; - } -} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/operations.h b/source/RobotAPI/libraries/armem/server/ltm/operations.h deleted file mode 100644 index b430afdf1..000000000 --- a/source/RobotAPI/libraries/armem/server/ltm/operations.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <RobotAPI/libraries/armem/core/forward_declarations.h> -#include <RobotAPI/libraries/armem/server/forward_declarations.h> - -namespace armarx::armem::server::ltm -{ - namespace util - { - bool entityHasData(const armem::wm::EntitySnapshot& e); - } - -} // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/plugins/Plugin.cpp b/source/RobotAPI/libraries/armem/server/plugins/Plugin.cpp index 93c701eaf..62ea8e632 100644 --- a/source/RobotAPI/libraries/armem/server/plugins/Plugin.cpp +++ b/source/RobotAPI/libraries/armem/server/plugins/Plugin.cpp @@ -43,7 +43,7 @@ namespace armarx::armem::server::plugins properties->optional(longtermMemory.dbsettings.database, prefix + "ltm.dbdatabase", "The name of the database you want to use for this memory. You can have multiple memories in one database.");*/ // stuff if disk memory - properties->optional(longtermMemory.memoryPathString, "ltm.storagepath", "The path to the memory storage."); + properties->optional(longtermMemory.path, "ltm.storagepath", "The path to the memory storage."); } // Publish memory updates topic @@ -60,12 +60,6 @@ namespace armarx::armem::server::plugins registerServer(parent); } iceAdapter.setMemoryListener(memoryTopic); - - // establishing connection to ltm and mongodb - if (longtermMemoryEnabled) - { - longtermMemory.reload(); - } } @@ -81,7 +75,7 @@ namespace armarx::armem::server::plugins void Plugin::setMemoryName(const std::string& memoryName) { workingMemory.name() = memoryName; - longtermMemory.setName(memoryName); + longtermMemory.setMemoryID(workingMemory.id()); } diff --git a/source/RobotAPI/libraries/armem/server/plugins/Plugin.h b/source/RobotAPI/libraries/armem/server/plugins/Plugin.h index 9d443c681..d5c7c0534 100644 --- a/source/RobotAPI/libraries/armem/server/plugins/Plugin.h +++ b/source/RobotAPI/libraries/armem/server/plugins/Plugin.h @@ -3,7 +3,6 @@ #include <RobotAPI/libraries/armem/server/MemoryToIceAdapter.h> #include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> -#include <RobotAPI/libraries/armem/server/ltm/mongodb/MemoryManager.h> #include <RobotAPI/interface/armem/client/MemoryListenerInterface.h> #include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h> diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h index 73c662e04..b4ad4300d 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h @@ -36,7 +36,6 @@ namespace armarx::armem::server::query_proc::base virtual ~BaseQueryProcessorBase() = default; - ResultT process(const QueryT& query, const DataT& data) const { ResultT result { data.id() }; diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h index 0c6199eac..dc84c257a 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h @@ -18,6 +18,8 @@ namespace armarx::armem::server::query_proc::base class CoreSegmentQueryProcessorBase : public BaseQueryProcessorBase<queryTarget, _CoreSegmentT, _ResultCoreSegmentT, armem::query::data::CoreSegmentQuery> { + protected: + using Base = BaseQueryProcessorBase<queryTarget, _CoreSegmentT, _ResultCoreSegmentT, armem::query::data::CoreSegmentQuery>; public: @@ -65,7 +67,7 @@ namespace armarx::armem::server::query_proc::base } } - void process(ResultCoreSegmentT& result, + virtual void process(ResultCoreSegmentT& result, const armem::query::data::core::All& query, const CoreSegmentT& coreSegment) const { @@ -75,18 +77,17 @@ namespace armarx::armem::server::query_proc::base }); } - void process(ResultCoreSegmentT& result, + virtual void process(ResultCoreSegmentT& result, const armem::query::data::core::Single& query, const CoreSegmentT& coreSegment) const { - const ProviderSegmentT* providerSegment = coreSegment.findProviderSegment(query.providerSegmentName); - if (providerSegment) + if (auto providerSegment = coreSegment.findProviderSegment(query.providerSegmentName)) { this->_processResult(result, *providerSegment, query); } } - void process(ResultCoreSegmentT& result, + virtual void process(ResultCoreSegmentT& result, const armem::query::data::core::Regex& query, const CoreSegmentT& coreSegment) const { @@ -102,7 +103,7 @@ namespace armarx::armem::server::query_proc::base } - private: + protected: void _processResult(ResultCoreSegmentT& result, const ProviderSegmentT& providerSegment, diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h index b0210c37e..6179467a7 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h @@ -23,6 +23,8 @@ namespace armarx::armem::server::query_proc::base class EntityQueryProcessorBase : public BaseQueryProcessorBase<queryTarget, _EntityT, _ResultEntityT, armem::query::data::EntityQuery> { + protected: + using Base = BaseQueryProcessorBase<queryTarget, _EntityT, _ResultEntityT, armem::query::data::EntityQuery>; public: @@ -34,6 +36,8 @@ namespace armarx::armem::server::query_proc::base using ResultSnapshotT = typename ResultEntityT::EntitySnapshotT; + public: + using Base::process; virtual void process(ResultEntityT& result, const armem::query::data::EntityQuery& query, @@ -74,37 +78,37 @@ namespace armarx::armem::server::query_proc::base } - void process(ResultEntityT& result, + virtual void process(ResultEntityT& result, const armem::query::data::entity::All& query, const EntityT& entity) const { (void) query; // Copy this entitiy and its contents. - entity.forEachSnapshot([this, &result](const EntitySnapshotT & snapshot) + entity.forEachSnapshot([this, &result](const EntitySnapshotT& snapshot) { - addResultSnapshot(result, snapshot); + this->addResultSnapshot(result, snapshot); }); } - void process(ResultEntityT& result, + virtual void process(ResultEntityT& result, const armem::query::data::entity::Single& query, const EntityT& entity) const { if (query.timestamp < 0) { - if (const ResultSnapshotT* snapshot = entity.findLatestSnapshot()) + if (auto snapshot = entity.findLatestSnapshot()) { - addResultSnapshot(result, *snapshot); + this->addResultSnapshot(result, *snapshot); } } else { const Time time = fromIce<Time>(query.timestamp); - if (const ResultSnapshotT* snapshot = entity.findSnapshot(time)) + if (auto snapshot = entity.findSnapshot(time)) { - addResultSnapshot(result, *snapshot); + this->addResultSnapshot(result, *snapshot); } else { @@ -126,7 +130,7 @@ namespace armarx::armem::server::query_proc::base } - void process(ResultEntityT& result, + virtual void process(ResultEntityT& result, const armem::query::data::entity::TimeRange& query, const EntityT& entity) const { @@ -139,7 +143,7 @@ namespace armarx::armem::server::query_proc::base } - void process(ResultEntityT& result, + virtual void process(ResultEntityT& result, const armem::query::data::entity::IndexRange& query, const EntityT& entity) const { @@ -147,12 +151,12 @@ namespace armarx::armem::server::query_proc::base query.first, query.last, [this, &result](const EntitySnapshotT & snapshot) { - addResultSnapshot(result, snapshot); + this->addResultSnapshot(result, snapshot); }); } - void process(ResultEntityT& result, + virtual void process(ResultEntityT& result, const Time& min, const Time& max, const EntityT& entity, @@ -163,31 +167,31 @@ namespace armarx::armem::server::query_proc::base min, max, [this, &result](const EntitySnapshotT & snapshot) { - addResultSnapshot(result, snapshot); + this->addResultSnapshot(result, snapshot); }); } - void process(ResultEntityT& result, + virtual void process(ResultEntityT& result, const armem::query::data::entity::BeforeOrAtTime& query, const EntityT& entity) const { const Time referenceTimestamp = fromIce<Time>(query.timestamp); - detail::checkReferenceTimestampNonNegative(referenceTimestamp); + base::detail::checkReferenceTimestampNonNegative(referenceTimestamp); - if (auto* beforeOrAt = entity.findLatestSnapshotBeforeOrAt(referenceTimestamp)) + if (auto beforeOrAt = entity.findLatestSnapshotBeforeOrAt(referenceTimestamp)) { - addResultSnapshot(result, *beforeOrAt); + this->addResultSnapshot(result, *beforeOrAt); } } - void process(ResultEntityT& result, + virtual void process(ResultEntityT& result, const armem::query::data::entity::BeforeTime& query, const EntityT& entity) const { const Time referenceTimestamp = fromIce<Time>(query.timestamp); - detail::checkReferenceTimestampNonNegative(referenceTimestamp); + base::detail::checkReferenceTimestampNonNegative(referenceTimestamp); std::vector<const EntitySnapshotT*> befores; entity.forEachSnapshotBefore(referenceTimestamp, [&befores](const EntitySnapshotT & s) @@ -208,17 +212,17 @@ namespace armarx::armem::server::query_proc::base for (size_t r = 0; r < num; ++r) { size_t i = befores.size() - 1 - r; - addResultSnapshot(result, *befores[i]); + this->addResultSnapshot(result, *befores[i]); } } - void process(ResultEntityT& result, + virtual void process(ResultEntityT& result, const armem::query::data::entity::TimeApprox& query, const EntityT& entity) const { const Time referenceTimestamp = fromIce<Time>(query.timestamp); - detail::checkReferenceTimestampNonNegative(referenceTimestamp); + base::detail::checkReferenceTimestampNonNegative(referenceTimestamp); const float referenceTimestampMicroSeconds = referenceTimestamp.toMicroSeconds(); const float epsDuration = fromIce<Time>(query.eps).toMicroSeconds(); @@ -235,13 +239,13 @@ namespace armarx::armem::server::query_proc::base }; // last element before or at timestamp - if (auto* beforeOrAt = entity.findLatestSnapshotBeforeOrAt(referenceTimestamp)) + if (auto beforeOrAt = entity.findLatestSnapshotBeforeOrAt(referenceTimestamp)) { const auto timestampOfMatchBefore = beforeOrAt->id().timestamp; const auto isPerfectMatch = timestampOfMatchBefore == referenceTimestamp; if (isInRange(timestampOfMatchBefore)) { - addResultSnapshot(result, *beforeOrAt); + this->addResultSnapshot(result, *beforeOrAt); } // earsly stop, not necessary to also get the next since the match is perfect @@ -251,13 +255,13 @@ namespace armarx::armem::server::query_proc::base } // first element after or at timestamp (or at because of fewer checks, we can assure that there is not element at) - const auto* after = entity.findFirstSnapshotAfterOrAt(referenceTimestamp); + const auto after = entity.findFirstSnapshotAfterOrAt(referenceTimestamp); if (after) { const auto timestampOfMatchAfter = after->id().timestamp; if (isInRange(timestampOfMatchAfter)) { - addResultSnapshot(result, *after); + this->addResultSnapshot(result, *after); } } } @@ -266,10 +270,7 @@ namespace armarx::armem::server::query_proc::base protected: - void addResultSnapshot(ResultEntityT& result, const EntitySnapshotT& snapshot) const - { - result.addSnapshot(snapshot); - } + virtual void addResultSnapshot(ResultEntityT& result, const EntitySnapshotT& snapshot) const = 0; }; } diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h index 91c41d9f5..85d632639 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h @@ -15,6 +15,8 @@ namespace armarx::armem::server::query_proc::base class MemoryQueryProcessorBase : public BaseQueryProcessorBase<queryTarget, _MemoryT, _ResultMemoryT, armem::query::data::MemoryQuery> { + protected: + using Base = BaseQueryProcessorBase<queryTarget, _MemoryT, _ResultMemoryT, armem::query::data::MemoryQuery>; public: @@ -67,32 +69,32 @@ namespace armarx::armem::server::query_proc::base } } - void process(ResultMemoryT& result, + virtual void process(ResultMemoryT& result, const armem::query::data::memory::All& query, const MemoryT& memory) const { - memory.forEachCoreSegment([this, &result, &query](const CoreSegmentT & coreSegment) + memory.forEachCoreSegment([this, &result, &query](const CoreSegmentT& coreSegment) { this->_processResult(result, coreSegment, query); }); } - void process(ResultMemoryT& result, + virtual void process(ResultMemoryT& result, const armem::query::data::memory::Single& query, const MemoryT& memory) const { - if (const CoreSegmentT* coreSegment = memory.findCoreSegment(query.coreSegmentName)) + if (auto coreSegment = memory.findCoreSegment(query.coreSegmentName)) { this->_processResult(result, *coreSegment, query); } } - void process(ResultMemoryT& result, + virtual void process(ResultMemoryT& result, const armem::query::data::memory::Regex& query, const MemoryT& memory) const { const std::regex regex(query.coreSegmentNameRegex); - memory.forEachCoreSegment([this, &result, &query, ®ex](const CoreSegmentT & coreSegment) + memory.forEachCoreSegment([this, &result, &query, ®ex](const CoreSegmentT& coreSegment) { if (std::regex_search(coreSegment.name(), regex)) { @@ -102,7 +104,7 @@ namespace armarx::armem::server::query_proc::base } - private: + protected: void _processResult(ResultMemoryT& result, const CoreSegmentT& coreSegment, diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h index 46f146694..bc7f92031 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h @@ -16,6 +16,8 @@ namespace armarx::armem::server::query_proc::base class ProviderSegmentQueryProcessorBase : public BaseQueryProcessorBase<queryTarget, _ProviderSegmentT, _ResultProviderSegmentT, armem::query::data::ProviderSegmentQuery> { + protected: + using Base = BaseQueryProcessorBase<queryTarget, _ProviderSegmentT, _ResultProviderSegmentT, armem::query::data::ProviderSegmentQuery>; @@ -40,7 +42,6 @@ namespace armarx::armem::server::query_proc::base { } - using Base::process; virtual void process(ResultProviderSegmentT& result, const armem::query::data::ProviderSegmentQuery& query, @@ -64,32 +65,32 @@ namespace armarx::armem::server::query_proc::base } } - void process(ResultProviderSegmentT& result, + virtual void process(ResultProviderSegmentT& result, const armem::query::data::provider::All& query, const ProviderSegmentT& providerSegment) const { - providerSegment.forEachEntity([this, &result, &query](const EntityT & entity) + providerSegment.forEachEntity([this, &result, &query](const EntityT& entity) { this->_processResult(result, entity, query); }); } - void process(ResultProviderSegmentT& result, + virtual void process(ResultProviderSegmentT& result, const armem::query::data::provider::Single& query, const ProviderSegmentT& providerSegment) const { - if (const EntityT* entity = providerSegment.findEntity(query.entityName)) + if (auto entity = providerSegment.findEntity(query.entityName)) { this->_processResult(result, *entity, query); } } - void process(ResultProviderSegmentT& result, + virtual void process(ResultProviderSegmentT& result, const armem::query::data::provider::Regex& query, const ProviderSegmentT& providerSegment) const { const std::regex regex(query.entityNameRegex); - providerSegment.forEachEntity([this, &result, &query, ®ex](const EntityT & entity) + providerSegment.forEachEntity([this, &result, &query, ®ex](const EntityT& entity) { if (std::regex_search(entity.name(), regex)) { @@ -100,7 +101,7 @@ namespace armarx::armem::server::query_proc::base } - private: + protected: void _processResult(ResultProviderSegmentT& result, const EntityT& entity, diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm.h b/source/RobotAPI/libraries/armem/server/query_proc/ltm.h deleted file mode 100644 index 05734c2e1..000000000 --- a/source/RobotAPI/libraries/armem/server/query_proc/ltm.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.h> -#include <RobotAPI/libraries/armem/server/query_proc/base.h> - - -namespace armarx::armem::server::query_proc::ltm -{ - static const base::QueryTarget queryTarget = query::data::QueryTarget::LTM; - - - class EntityQueryProcessor : - public base::EntityQueryProcessorBase<queryTarget, armem::wm::Entity, armem::wm::Entity> - { - }; - - class ProviderSegmentQueryProcessor : - public base::ProviderSegmentQueryProcessorBase <queryTarget, armem::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor > - { - }; - - class CoreSegmentQueryProcessor : - public base::CoreSegmentQueryProcessorBase <queryTarget, armem::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor> - { - }; - - class MemoryQueryProcessor : - public base::MemoryQueryProcessorBase <queryTarget, armem::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor > - { - }; - -} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.cpp new file mode 100644 index 000000000..63e7ff349 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.cpp @@ -0,0 +1 @@ +#include "CoreSegmentQueryProcessorBase.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.h new file mode 100644 index 000000000..0f06af9da --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.h @@ -0,0 +1,36 @@ +#pragma once + +#include "../../base/CoreSegmentQueryProcessorBase.h" + + +namespace armarx::armem::server::query_proc::ltm::detail +{ + + /** + * @brief Handles memory queries. + */ + template <base::QueryTarget queryTarget, class _CoreSegmentT, class _ResultCoreSegmentT, class _ChildProcessorT> + class CoreSegmentQueryProcessorBase : + public base::CoreSegmentQueryProcessorBase<queryTarget, _CoreSegmentT, _ResultCoreSegmentT, _ChildProcessorT> + { + protected: + + using Base = base::CoreSegmentQueryProcessorBase<queryTarget, _CoreSegmentT, _ResultCoreSegmentT, _ChildProcessorT>; + + + public: + using CoreSegmentT = typename Base::CoreSegmentT; + using ProviderSegmentT = typename Base::ProviderSegmentT; + using ResultCoreSegmentT = typename Base::ResultCoreSegmentT; + using ResultProviderSegmentT = typename Base::ProviderSegmentT; + using ChildProcessorT = typename Base::ChildProcessorT; + + public: + using Base::CoreSegmentQueryProcessorBase; + virtual ~CoreSegmentQueryProcessorBase() = default; + + using Base::process; + + + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.cpp new file mode 100644 index 000000000..e01bbbf5a --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.cpp @@ -0,0 +1,9 @@ +#include "EntityQueryProcessorBase.h" + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + + +namespace armarx::armem::server::query_proc::base +{ + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.h new file mode 100644 index 000000000..405abb2e3 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.h @@ -0,0 +1,35 @@ +#pragma once + +#include "../../base/EntityQueryProcessorBase.h" + + +namespace armarx::armem::server::query_proc::ltm::detail +{ + + template <base::QueryTarget queryTarget, class _EntityT, class _ResultEntityT> + class EntityQueryProcessorBase : + public base::EntityQueryProcessorBase<queryTarget, _EntityT, _ResultEntityT> + { + protected: + + using Base = base::EntityQueryProcessorBase<queryTarget, _EntityT, _ResultEntityT>; + + public: + using EntityT = typename Base::EntityT; + using EntitySnapshotT = typename Base::EntitySnapshotT; + using ResultEntityT = typename Base::ResultEntityT; + using ResultSnapshotT = typename Base::EntitySnapshotT; + + public: + virtual ~EntityQueryProcessorBase() = default; + + using Base::process; + + + protected: + void addResultSnapshot(ResultEntityT& result, const EntitySnapshotT& snapshot) const override + { + result.addSnapshot(snapshot.loadAll()); + } + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/MemoryQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/MemoryQueryProcessorBase.cpp new file mode 100644 index 000000000..c51a6336c --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/MemoryQueryProcessorBase.cpp @@ -0,0 +1 @@ +#include "MemoryQueryProcessorBase.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/MemoryQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/MemoryQueryProcessorBase.h new file mode 100644 index 000000000..a077de9ca --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/MemoryQueryProcessorBase.h @@ -0,0 +1,33 @@ +#pragma once + +#include "../../base/MemoryQueryProcessorBase.h" + + +namespace armarx::armem::server::query_proc::ltm::detail +{ + + template <base::QueryTarget queryTarget, class _MemoryT, class _ResultMemoryT, class _ChildProcessorT> + class MemoryQueryProcessorBase : + public base::MemoryQueryProcessorBase<queryTarget, _MemoryT, _ResultMemoryT, _ChildProcessorT> + { + protected: + + using Base = base::MemoryQueryProcessorBase<queryTarget, _MemoryT, _ResultMemoryT, _ChildProcessorT>; + + public: + + using MemoryT = typename Base::MemoryT; + using CoreSegmentT = typename Base::CoreSegmentT; + using ResultMemoryT = typename Base::ResultMemoryT; + using ResultCoreSegmentT = typename Base::CoreSegmentT; + using ChildProcessorT = typename Base::ChildProcessorT; + + public: + using Base::MemoryQueryProcessorBase; + virtual ~MemoryQueryProcessorBase() = default; + + using Base::process; + + + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.cpp new file mode 100644 index 000000000..67db9e142 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.cpp @@ -0,0 +1 @@ +#include "ProviderSegmentQueryProcessorBase.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.h new file mode 100644 index 000000000..b3512921d --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.h @@ -0,0 +1,33 @@ +#pragma once + +#include "../../base/ProviderSegmentQueryProcessorBase.h" + + +namespace armarx::armem::server::query_proc::ltm::detail +{ + + template <base::QueryTarget queryTarget, class _ProviderSegmentT, class _ResultProviderSegmentT, class _ChildProcessorT> + class ProviderSegmentQueryProcessorBase : + public base::ProviderSegmentQueryProcessorBase<queryTarget, _ProviderSegmentT, _ResultProviderSegmentT, _ChildProcessorT> + { + protected: + + using Base = base::ProviderSegmentQueryProcessorBase<queryTarget, _ProviderSegmentT, _ResultProviderSegmentT, _ChildProcessorT>; + + public: + + using ProviderSegmentT = typename Base::ProviderSegmentT; + using EntityT = typename Base::EntityT; + using ResultProviderSegmentT = typename Base::ResultProviderSegmentT; + using ResultEntityT = typename Base::EntityT; + using ChildProcessorT = typename Base::ChildProcessorT; + + public: + using Base::ProviderSegmentQueryProcessorBase; + virtual ~ProviderSegmentQueryProcessorBase() = default; + + using Base::process; + + + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm.cpp b/source/RobotAPI/libraries/armem/server/query_proc/ltm/ltm.cpp similarity index 100% rename from source/RobotAPI/libraries/armem/server/query_proc/ltm.cpp rename to source/RobotAPI/libraries/armem/server/query_proc/ltm/ltm.cpp diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm/ltm.h b/source/RobotAPI/libraries/armem/server/query_proc/ltm/ltm.h new file mode 100644 index 000000000..eb8a13122 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm/ltm.h @@ -0,0 +1,65 @@ +#pragma once + +#include <RobotAPI/libraries/armem/server/ltm/disk/Memory.h> +#include <RobotAPI/libraries/armem/server/query_proc/base.h> + +#include "detail/MemoryQueryProcessorBase.h" +#include "detail/CoreSegmentQueryProcessorBase.h" +#include "detail/ProviderSegmentQueryProcessorBase.h" +#include "detail/EntityQueryProcessorBase.h" + +namespace armarx::armem::server::query_proc::ltm_server +{ + static const base::QueryTarget queryTarget = query::data::QueryTarget::LTM; + + + class EntityQueryProcessor : + public ltm::detail::EntityQueryProcessorBase<queryTarget, armem::server::ltm::disk::Entity, armem::wm::Entity> + { + protected: + + using Base = ltm::detail::EntityQueryProcessorBase<queryTarget, armem::server::ltm::disk::Entity, armem::wm::Entity>; + + + public: + + using Base::process; + + }; + + class ProviderSegmentQueryProcessor : + public ltm::detail::ProviderSegmentQueryProcessorBase<queryTarget, armem::server::ltm::disk::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor> + { + protected: + + using Base = ltm::detail::ProviderSegmentQueryProcessorBase<queryTarget, armem::server::ltm::disk::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor>; + + + public: + using Base::process; + }; + + class CoreSegmentQueryProcessor : + public ltm::detail::CoreSegmentQueryProcessorBase<queryTarget, armem::server::ltm::disk::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor> + { + protected: + + using Base = ltm::detail::CoreSegmentQueryProcessorBase<queryTarget, armem::server::ltm::disk::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>; + + + public: + using Base::process; + }; + + class MemoryQueryProcessor : + public ltm::detail::MemoryQueryProcessorBase<queryTarget, armem::server::ltm::disk::Memory, armem::wm::Memory, CoreSegmentQueryProcessor> + { + protected: + + using Base = ltm::detail::MemoryQueryProcessorBase<queryTarget, armem::server::ltm::disk::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>; + + public: + using Base::process; + }; + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.cpp new file mode 100644 index 000000000..477263258 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.cpp @@ -0,0 +1,6 @@ +#include "CoreSegmentQueryProcessorBase.h" + +namespace armarx::armem::server::query_proc::wm::detail +{ + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.h new file mode 100644 index 000000000..c9a0ddb51 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../../base/CoreSegmentQueryProcessorBase.h" + + +namespace armarx::armem::server::query_proc::wm::detail +{ + + /** + * @brief Handles memory queries. + */ + template <base::QueryTarget queryTarget, class _CoreSegmentT, class _ResultCoreSegmentT, class _ChildProcessorT> + class CoreSegmentQueryProcessorBase : + public base::CoreSegmentQueryProcessorBase<queryTarget, _CoreSegmentT, _ResultCoreSegmentT, _ChildProcessorT> + { + protected: + + using Base = base::CoreSegmentQueryProcessorBase<queryTarget, _CoreSegmentT, _ResultCoreSegmentT, _ChildProcessorT>; + + + public: + + using CoreSegmentT = typename Base::CoreSegmentT; + using ProviderSegmentT = typename Base::ProviderSegmentT; + using ResultCoreSegmentT = typename Base::ResultCoreSegmentT; + using ResultProviderSegmentT = typename Base::ProviderSegmentT; + using ChildProcessorT = typename Base::ChildProcessorT; + + + public: + + using Base::CoreSegmentQueryProcessorBase; + virtual ~CoreSegmentQueryProcessorBase() = default; + + using Base::process; + + + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/EntityQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/EntityQueryProcessorBase.cpp new file mode 100644 index 000000000..c59233630 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/EntityQueryProcessorBase.cpp @@ -0,0 +1,9 @@ +#include "EntityQueryProcessorBase.h" + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + + +namespace armarx::armem::server::query_proc::wm::detail +{ + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/EntityQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/EntityQueryProcessorBase.h new file mode 100644 index 000000000..a107d6155 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/EntityQueryProcessorBase.h @@ -0,0 +1,38 @@ +#pragma once + +#include "../../base/EntityQueryProcessorBase.h" + + +namespace armarx::armem::server::query_proc::wm::detail +{ + + template <base::QueryTarget queryTarget, class _EntityT, class _ResultEntityT> + class EntityQueryProcessorBase : + public base::EntityQueryProcessorBase<queryTarget, _EntityT, _ResultEntityT> + { + protected: + + using Base = base::EntityQueryProcessorBase<queryTarget, _EntityT, _ResultEntityT>; + + + public: + + using EntityT = typename Base::EntityT; + using EntitySnapshotT = typename Base::EntitySnapshotT; + using ResultEntityT = typename Base::ResultEntityT; + using ResultSnapshotT = typename Base::EntitySnapshotT; + + + public: + virtual ~EntityQueryProcessorBase() = default; + + using Base::process; + + + protected: + void addResultSnapshot(ResultEntityT& result, const EntitySnapshotT& snapshot) const override + { + result.addSnapshot(snapshot); + } + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/MemoryQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/MemoryQueryProcessorBase.cpp new file mode 100644 index 000000000..f72b60033 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/MemoryQueryProcessorBase.cpp @@ -0,0 +1,7 @@ +#include "MemoryQueryProcessorBase.h" + + +namespace armarx::armem::server::query_proc::wm::detail +{ + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/MemoryQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/MemoryQueryProcessorBase.h new file mode 100644 index 000000000..38d7a9ec4 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/MemoryQueryProcessorBase.h @@ -0,0 +1,35 @@ +#pragma once + +#include "../../base/MemoryQueryProcessorBase.h" + + +namespace armarx::armem::server::query_proc::wm::detail +{ + + template <base::QueryTarget queryTarget, class _MemoryT, class _ResultMemoryT, class _ChildProcessorT> + class MemoryQueryProcessorBase : + public base::MemoryQueryProcessorBase<queryTarget, _MemoryT, _ResultMemoryT, _ChildProcessorT> + { + protected: + + using Base = base::MemoryQueryProcessorBase<queryTarget, _MemoryT, _ResultMemoryT, _ChildProcessorT>; + + + public: + + using MemoryT = typename Base::MemoryT; + using CoreSegmentT = typename Base::CoreSegmentT; + using ResultMemoryT = typename Base::ResultMemoryT; + using ResultCoreSegmentT = typename Base::CoreSegmentT; + using ChildProcessorT = typename Base::ChildProcessorT; + + + public: + using Base::MemoryQueryProcessorBase; + virtual ~MemoryQueryProcessorBase() = default; + + using Base::process; + + + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.cpp new file mode 100644 index 000000000..d11b94bcd --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.cpp @@ -0,0 +1,6 @@ +#include "ProviderSegmentQueryProcessorBase.h" + +namespace armarx::armem::server::query_proc::wm::detail +{ + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.h new file mode 100644 index 000000000..759938b2b --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.h @@ -0,0 +1,35 @@ +#pragma once + +#include "../../base/ProviderSegmentQueryProcessorBase.h" + + +namespace armarx::armem::server::query_proc::wm::detail +{ + + template <base::QueryTarget queryTarget, class _ProviderSegmentT, class _ResultProviderSegmentT, class _ChildProcessorT> + class ProviderSegmentQueryProcessorBase : + public base::ProviderSegmentQueryProcessorBase<queryTarget, _ProviderSegmentT, _ResultProviderSegmentT, _ChildProcessorT> + { + protected: + + using Base = base::ProviderSegmentQueryProcessorBase<queryTarget, _ProviderSegmentT, _ResultProviderSegmentT, _ChildProcessorT>; + + + public: + + using ProviderSegmentT = typename Base::ProviderSegmentT; + using EntityT = typename Base::EntityT; + using ResultProviderSegmentT = typename Base::ResultProviderSegmentT; + using ResultEntityT = typename Base::EntityT; + using ChildProcessorT = typename Base::ChildProcessorT; + + + public: + using Base::ProviderSegmentQueryProcessorBase; + virtual ~ProviderSegmentQueryProcessorBase() = default; + + using Base::process; + + + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm.cpp b/source/RobotAPI/libraries/armem/server/query_proc/wm/wm.cpp similarity index 89% rename from source/RobotAPI/libraries/armem/server/query_proc/wm.cpp rename to source/RobotAPI/libraries/armem/server/query_proc/wm/wm.cpp index 0ace705be..b8d25db27 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/wm.cpp +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm/wm.cpp @@ -16,7 +16,8 @@ namespace armarx::armem::server::query_proc::wm { ProviderSegmentQueryProcessor::ProviderSegmentQueryProcessor(DataMode dataMode) : - ProviderSegmentQueryProcessorBase(dataMode), HasDataMode(dataMode) + detail::ProviderSegmentQueryProcessorBase<queryTarget, armem::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor>(dataMode), + HasDataMode(dataMode) { } diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm.h b/source/RobotAPI/libraries/armem/server/query_proc/wm/wm.h similarity index 54% rename from source/RobotAPI/libraries/armem/server/query_proc/wm.h rename to source/RobotAPI/libraries/armem/server/query_proc/wm/wm.h index aa52b4ab2..2d1ff3e35 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/wm.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/wm/wm.h @@ -3,7 +3,11 @@ #include <RobotAPI/libraries/armem/core/DataMode.h> #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h> #include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> -#include <RobotAPI/libraries/armem/server/query_proc/base.h> + +#include "detail/MemoryQueryProcessorBase.h" +#include "detail/CoreSegmentQueryProcessorBase.h" +#include "detail/ProviderSegmentQueryProcessorBase.h" +#include "detail/EntityQueryProcessorBase.h" namespace armarx::armem::server::query_proc::wm @@ -30,15 +34,22 @@ namespace armarx::armem::server::query_proc::wm::detail template <class SourceEntityT> class EntityQueryProcessor : - public base::EntityQueryProcessorBase<queryTarget, SourceEntityT, armem::wm::Entity>, + public EntityQueryProcessorBase<queryTarget, SourceEntityT, armem::wm::Entity>, public HasDataMode { + protected: + + using Base = EntityQueryProcessorBase<queryTarget, SourceEntityT, armem::wm::Entity>; + using Entity = armem::wm::Entity; + + public: EntityQueryProcessor(DataMode dataMode = DataMode::WithData) : HasDataMode(dataMode) {} + using Base::process; protected: @@ -70,41 +81,62 @@ namespace armarx::armem::server::query_proc::wm using EntityQueryProcessor = detail::EntityQueryProcessor<armem::wm::Entity>; - class ProviderSegmentQueryProcessor : - public base::ProviderSegmentQueryProcessorBase<queryTarget, armem::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor >, + public detail::ProviderSegmentQueryProcessorBase<queryTarget, armem::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor>, public detail::HasDataMode { + protected: + + using Base = detail::ProviderSegmentQueryProcessorBase<queryTarget, armem::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor>; + using ProviderSegment = armem::wm::ProviderSegment; + using Entity = armem::wm::Entity; + + public: ProviderSegmentQueryProcessor(DataMode dataMode = DataMode::WithData); + using Base::process; }; class CoreSegmentQueryProcessor : - public base::CoreSegmentQueryProcessorBase <queryTarget, armem::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor >, + public detail::CoreSegmentQueryProcessorBase <queryTarget, armem::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>, public detail::HasDataMode { - using Base = base::CoreSegmentQueryProcessorBase<queryTarget, armem::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>; + protected: + + using Base = wm::detail::CoreSegmentQueryProcessorBase<queryTarget, armem::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>; using CoreSegment = armem::wm::CoreSegment; using ProviderSegment = armem::wm::ProviderSegment; + public: CoreSegmentQueryProcessor(DataMode dataMode = DataMode::WithData); + using Base::process; + }; class MemoryQueryProcessor : - public base::MemoryQueryProcessorBase<queryTarget, armem::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>, + public detail::MemoryQueryProcessorBase<queryTarget, armem::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>, public detail::HasDataMode { + protected: + + using Base = detail::MemoryQueryProcessorBase<queryTarget, armem::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>; + using Memory = armem::wm::Memory; + using CoreSegment = armem::wm::CoreSegment; + + public: MemoryQueryProcessor(DataMode dataMode = DataMode::WithData); + using Base::process; + }; } @@ -117,9 +149,15 @@ namespace armarx::armem::server::query_proc::wm_server class ProviderSegmentQueryProcessor : - public base::ProviderSegmentQueryProcessorBase<wm::queryTarget, server::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor >, + public wm::detail::ProviderSegmentQueryProcessorBase<wm::queryTarget, server::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor>, public wm::detail::HasDataMode { + protected: + + using Base = wm::detail::ProviderSegmentQueryProcessorBase<wm::queryTarget, server::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor>; + using ProviderSegment = server::wm::ProviderSegment; + using Entity = server::wm::Entity; + public: ProviderSegmentQueryProcessor(DataMode dataMode = DataMode::WithData); @@ -128,18 +166,20 @@ namespace armarx::armem::server::query_proc::wm_server class CoreSegmentQueryProcessor : - public base::CoreSegmentQueryProcessorBase <wm::queryTarget, server::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor >, + public wm::detail::CoreSegmentQueryProcessorBase <wm::queryTarget, server::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>, public wm::detail::HasDataMode { - using Base = base::CoreSegmentQueryProcessorBase<wm::queryTarget, server::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>; + protected: + + using Base = wm::detail::CoreSegmentQueryProcessorBase<wm::queryTarget, server::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>; using CoreSegment = server::wm::CoreSegment; using ProviderSegment = server::wm::ProviderSegment; + public: CoreSegmentQueryProcessor(DataMode dataMode = DataMode::WithData); - using Base::process; /// Locks the core segment, then delegates back to `CoreSegmentQueryProcessorBase`. @@ -152,13 +192,21 @@ namespace armarx::armem::server::query_proc::wm_server class MemoryQueryProcessor : - public base::MemoryQueryProcessorBase<wm::queryTarget, server::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>, + public wm::detail::MemoryQueryProcessorBase<wm::queryTarget, server::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>, public wm::detail::HasDataMode { + protected: + + using Base = wm::detail::MemoryQueryProcessorBase<wm::queryTarget, server::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>; + using Memory = server::wm::Memory; + using CoreSegment = server::wm::CoreSegment; + public: MemoryQueryProcessor(DataMode dataMode = DataMode::WithData); + using Base::process; + }; } diff --git a/source/RobotAPI/libraries/armem/test/ArMemLTMBenchmark.cpp b/source/RobotAPI/libraries/armem/test/ArMemLTMBenchmark.cpp new file mode 100644 index 000000000..a5d1b1a81 --- /dev/null +++ b/source/RobotAPI/libraries/armem/test/ArMemLTMBenchmark.cpp @@ -0,0 +1,118 @@ +/* + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @package RobotAPI::ArmarXObjects::armem + * @author Simon Ottenhaus ( simon dot ottenhaus at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#define BOOST_TEST_MODULE RobotAPI::ArmarXLibraries::armem + +#define ARMARX_BOOST_TEST + +#include <RobotAPI/Test.h> +#include <RobotAPI/libraries/armem/server/ltm/disk/Memory.h> +#include <RobotAPI/libraries/armem/core/error.h> + +#include <RobotAPI/libraries/aron/core/data/variant/All.h> +#include <RobotAPI/libraries/aron/core/type/variant/All.h> + +#include <ArmarXCore/core/time/StopWatch.h> + + +#include <filesystem> +#include <iostream> + +namespace armem = armarx::armem; +namespace aron = armarx::aron; +namespace fs = std::filesystem; + +namespace ArMemLTMBenchmark +{ + struct Fixture + { + fs::path storagePath = "/tmp/TestMemoryExport"; + + Fixture() + { + clearStoragePath(); + } + ~Fixture() + { + //clearStoragePath(); + } + + void clearStoragePath() + { + if (fs::exists(storagePath)) + { + fs::remove_all(storagePath); + } + BOOST_TEST_INFO("Storage path: " << storagePath); + BOOST_REQUIRE(!fs::exists(storagePath)); + } + + void run(const std::string& memoryName, const std::string& memberNamePrefix) + { + + } + }; +} + +BOOST_FIXTURE_TEST_SUITE(ArMemLTMBenchmark, Fixture) + + +BOOST_AUTO_TEST_CASE(test_memory_export__benchmark) +{ + int num_exports = 10; + armem::server::ltm::disk::Memory ltm; + ltm.setMemoryID(ltm.id().withMemoryName("Test")); + + auto data = std::make_shared<aron::data::Dict>(); + //auto member1 = std::make_shared<aron::data::Int>(42); + //auto member2 = std::make_shared<aron::data::String>("Hallo Welt"); + //data->addElement("Member1", member1); + //data->addElement("Member2", member2); + + std::vector<int> dimensions = {1280, 720, 3}; + std::string type = "0"; + std::vector<unsigned char> d(1280*720*3, 0); + data->addElement("image", std::make_shared<aron::data::NDArray>(dimensions, type, d)); + + armem::wm::Memory wm("Test"); + auto& core = wm.addCoreSegment("CoreS"); + auto& prov = core.addProviderSegment("ProvS"); + auto& en = prov.addEntity("EntityS"); + + TIMING_START(LTM_Export__Benchmark); + + for (unsigned int i = 0; i < num_exports; ++i) + { + en.clear(); + auto& snap = en.addSnapshot(IceUtil::Time::now()); + auto& ins = snap.addInstance(); + ins.data() = data; + + ltm.append(wm); + ltm.storeBuffer(); + } + + TIMING_END(LTM_Export__Benchmark); +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp index 13d050572..191cfb625 100644 --- a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp +++ b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp @@ -28,7 +28,7 @@ #include <RobotAPI/interface/armem/query.h> #include <RobotAPI/libraries/armem/core/error.h> #include <RobotAPI/libraries/armem/core/base/detail/negative_index_semantics.h> -#include <RobotAPI/libraries/armem/server/query_proc/wm.h> +#include <RobotAPI/libraries/armem/server/query_proc/wm/wm.h> #include <ArmarXCore/core/exceptions/LocalException.h> diff --git a/source/RobotAPI/libraries/armem/test/CMakeLists.txt b/source/RobotAPI/libraries/armem/test/CMakeLists.txt index 43b756504..a80618cee 100644 --- a/source/RobotAPI/libraries/armem/test/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem/test/CMakeLists.txt @@ -6,6 +6,7 @@ armarx_add_test(ArMemForEachTest ArMemForEachTest.cpp "${LIBS}") armarx_add_test(ArMemGetFindTest ArMemGetFindTest.cpp "${LIBS}") armarx_add_test(ArMemIceConversionsTest ArMemIceConversionsTest.cpp "${LIBS}") armarx_add_test(ArMemLTMTest ArMemLTMTest.cpp "${LIBS}") +armarx_add_test(ArMemLTMBenchmark ArMemLTMBenchmark.cpp "${LIBS}") armarx_add_test(ArMemMemoryTest ArMemMemoryTest.cpp "${LIBS}") armarx_add_test(ArMemMemoryIDTest ArMemMemoryIDTest.cpp "${LIBS}") armarx_add_test(ArMemQueryBuilderTest ArMemQueryBuilderTest.cpp "${LIBS}") diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp index 54dc9f56f..9ce928459 100644 --- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp +++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp @@ -3,8 +3,8 @@ #include <RobotAPI/libraries/armem/core/wm/ice_conversions.h> #include <RobotAPI/libraries/armem_gui/gui_utils.h> -#include <RobotAPI/libraries/armem/server/query_proc/wm.h> -#include <RobotAPI/libraries/armem/server/query_proc/ltm.h> +#include <RobotAPI/libraries/armem/server/query_proc/wm/wm.h> +#include <RobotAPI/libraries/armem/server/query_proc/ltm/ltm.h> #include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h> @@ -185,7 +185,7 @@ namespace armarx::armem::gui void MemoryViewer::storeInLTM() { - TIMING_START(MemoryStore) + TIMING_START(MemoryStore); for (auto& [name, reader] : memoryReaders) { @@ -194,7 +194,7 @@ namespace armarx::armem::gui reader.readAndStore(input); } - TIMING_END_STREAM(MemoryStore, ARMARX_VERBOSE) + TIMING_END_STREAM(MemoryStore, ARMARX_VERBOSE); } diff --git a/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp b/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp index 406dcfdf6..0e0f620d2 100644 --- a/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp +++ b/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp @@ -1,8 +1,7 @@ #include "ControlWidget.h" -#include <RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.h> -#include <RobotAPI/libraries/armem/server/ltm/disk/operations.h> -#include <RobotAPI/libraries/armem/server/query_proc/ltm.h> +#include <RobotAPI/libraries/armem/server/ltm/disk/Memory.h> +#include <RobotAPI/libraries/armem/server/query_proc/ltm/ltm.h> #include <ArmarXCore/core/exceptions/local/ExpressionException.h> @@ -103,9 +102,9 @@ namespace armarx::armem::gui::disk { std::filesystem::create_directories(path / name); - armem::server::ltm::disk::Memory manager((path / name)); - manager.reload(); - manager.append(data); + armem::server::ltm::disk::Memory memory((path / name)); + memory.append(data); + memory.storeBuffer(); numStored++; } @@ -147,11 +146,9 @@ namespace armarx::armem::gui::disk { if (dir.is_directory()) { - std::string memoryName = dir.path().filename(); armem::server::ltm::disk::Memory ltm(dir.path()); - ltm.reload(); - armem::wm::Memory memory = ltm.convert(); - memoryData[memoryName] = std::move(memory); + armem::wm::Memory memory = ltm.loadAll(); + memoryData[memory.name()] = std::move(memory); numLoaded++; } -- GitLab