diff --git a/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp b/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp index 003ef9fb5496b92814ad68cd9904987498460c46..fe96801cd8b5c58d19fe01aa73e02d0e0b3cb867 100644 --- a/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp +++ b/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp @@ -16,12 +16,17 @@ namespace armarx::armem::error } - InvalidArgument::InvalidArgument(const std::string& argument, const std::string& function, const std::string& message) : + InvalidArgument::InvalidArgument(const std::string& argument, + const std::string& function, + const std::string& message) : ArMemError(makeMsg(argument, function, message)) { } - std::string InvalidArgument::makeMsg(const std::string& argument, const std::string& function, const std::string& message) + std::string + InvalidArgument::makeMsg(const std::string& argument, + const std::string& function, + const std::string& message) { std::stringstream ss; ss << "Invalid value for argument '" << argument << "' in function " << function << "()"; @@ -38,24 +43,37 @@ namespace armarx::armem::error ContainerNameMismatch::ContainerNameMismatch(const std::string& gottenName, - const std::string& ownTerm, const std::string& containerName) : + const std::string& ownTerm, + const std::string& containerName) : ArMemError(makeMsg(gottenName, ownTerm, containerName)) - {} + { + } - std::string ContainerNameMismatch::makeMsg(const std::string& gottenName, const std::string& containerTerm, const std::string& containerName) + std::string + ContainerNameMismatch::makeMsg(const std::string& gottenName, + const std::string& containerTerm, + const std::string& containerName) { std::stringstream ss; - ss << "Name '" << gottenName << "' does not match name of " << containerTerm << " '" << containerName << "'."; + ss << "Name '" << gottenName << "' does not match name of " << containerTerm << " '" + << containerName << "'."; return ss.str(); } - ContainerEntryAlreadyExists::ContainerEntryAlreadyExists(const std::string& existingTerm, const std::string& existingName, const std::string& ownTerm, const std::string& ownName) : + ContainerEntryAlreadyExists::ContainerEntryAlreadyExists(const std::string& existingTerm, + const std::string& existingName, + const std::string& ownTerm, + const std::string& ownName) : ArMemError(makeMsg(existingTerm, existingName, ownTerm, ownName)) { } - std::string ContainerEntryAlreadyExists::makeMsg(const std::string& existingTerm, const std::string& existingName, const std::string& ownTerm, const std::string& ownName) + std::string + ContainerEntryAlreadyExists::makeMsg(const std::string& existingTerm, + const std::string& existingName, + const std::string& ownTerm, + const std::string& ownName) { std::stringstream ss; ss << simox::alg::capitalize_words(existingTerm) << " with name '" << existingName << "' " @@ -64,16 +82,21 @@ namespace armarx::armem::error } - MissingEntry::MissingEntry(const std::string& missingTerm, const std::string& missingName, - const std::string& containerTerm, const std::string& containerName, + MissingEntry::MissingEntry(const std::string& missingTerm, + const std::string& missingName, + const std::string& containerTerm, + const std::string& containerName, size_t size) : ArMemError(makeMsg(missingTerm, missingName, containerTerm, containerName, size)) { } - std::string MissingEntry::makeMsg(const std::string& missingTerm, const std::string& missingName, - const std::string& containerTerm, const std::string& containerName, - size_t size) + std::string + MissingEntry::makeMsg(const std::string& missingTerm, + const std::string& missingName, + const std::string& containerTerm, + const std::string& containerName, + size_t size) { std::stringstream ss; ss << "No " << missingTerm << " with name '" << missingName << "' " @@ -82,15 +105,19 @@ namespace armarx::armem::error } - - MissingData::MissingData(const std::string& missingTerm, const std::string& missingName, - const std::string& ownTerm, const std::string& ownName) : + MissingData::MissingData(const std::string& missingTerm, + const std::string& missingName, + const std::string& ownTerm, + const std::string& ownName) : ArMemError(makeMsg(missingTerm, missingName, ownTerm, ownName)) { } - std::string MissingData::makeMsg(const std::string& missingTerm, const std::string& missingName, - const std::string& ownTerm, const std::string& ownName) + std::string + MissingData::makeMsg(const std::string& missingTerm, + const std::string& missingName, + const std::string& ownTerm, + const std::string& ownName) { std::stringstream ss; ss << "No " << missingTerm << " data at '" << missingName << "' " @@ -104,7 +131,8 @@ namespace armarx::armem::error { } - std::string ParseIntegerError::makeMsg(std::string string, std::string semanticName) + std::string + ParseIntegerError::makeMsg(std::string string, std::string semanticName) { std::stringstream ss; ss << "Failed to parse " << semanticName << " '" << string << "' as integer."; @@ -112,13 +140,13 @@ namespace armarx::armem::error } - InvalidMemoryID::InvalidMemoryID(const MemoryID& id, const std::string& message) : ArMemError(makeMsg(id, message)) { } - std::string InvalidMemoryID::makeMsg(const MemoryID& id, const std::string& message) + std::string + InvalidMemoryID::makeMsg(const MemoryID& id, const std::string& message) { std::stringstream ss; ss << "Invalid memory ID " << id << ": " << message; @@ -126,13 +154,14 @@ namespace armarx::armem::error } - - EntityHistoryEmpty::EntityHistoryEmpty(const std::string& entityName, const std::string& message) : + EntityHistoryEmpty::EntityHistoryEmpty(const std::string& entityName, + const std::string& message) : ArMemError(makeMsg(entityName, message)) { } - std::string EntityHistoryEmpty::makeMsg(const std::string& entityName, const std::string& message) + std::string + EntityHistoryEmpty::makeMsg(const std::string& entityName, const std::string& message) { std::stringstream ss; ss << "History of entity '" << entityName << "' is empty"; @@ -148,13 +177,13 @@ namespace armarx::armem::error } - UnknownQueryType::UnknownQueryType(const std::string& term, const std::string& typeName) : ArMemError(makeMsg(term, typeName)) { } - std::string UnknownQueryType::makeMsg(const std::string& term, const std::string& typeName) + std::string + UnknownQueryType::makeMsg(const std::string& term, const std::string& typeName) { std::stringstream ss; ss << "Unknown " << term << " query type '" << typeName << "'."; @@ -162,64 +191,22 @@ namespace armarx::armem::error } - PathNotARegularFile::PathNotARegularFile(const std::string& path, const std::string& message) : - ArMemError(makeMsg(path, message)) - { - } - - std::string PathNotARegularFile::makeMsg(const std::string& path, const std::string& message) - { - std::stringstream ss; - ss << "The path '" << path << "' is not a regular file. Expecting a regular file there."; - if (message.size() > 0) - { - ss << " " << message; - } - else - { - ss << "."; - } - return ss.str(); - } - - PathNotADirectory::PathNotADirectory(const std::string& path, const std::string& message) : - ArMemError(makeMsg(path, message)) - { - } - - std::string PathNotADirectory::makeMsg(const std::string& path, const std::string& message) + IOError::IOError(const std::string& path, const std::string& message) : + ArMemError(makeMsg(path, message)), path(path) { - std::stringstream ss; - ss << "The path '" << path << "' is not a directory. Expecting a directory there."; - if (message.size() > 0) - { - ss << " " << message; - } - else - { - ss << "."; - } - return ss.str(); } - PathDoesNotExist::PathDoesNotExist(const std::string& path, const std::string& message) : - ArMemError(makeMsg(path, message)) - { - } - std::string PathDoesNotExist::makeMsg(const std::string& path, const std::string& message) + std::string + IOError::makeMsg(const std::string& path, const std::string& message) { std::stringstream ss; - ss << "The path '" << path << "' does not exist. Expecting a valid path."; + ss << "IOError on path \"" << path << "\"."; if (message.size() > 0) { - ss << " " << message; - } - else - { - ss << "."; + ss << "\n" << message; } return ss.str(); } -} +} // namespace armarx::armem::error diff --git a/source/RobotAPI/libraries/armem/core/error/ArMemError.h b/source/RobotAPI/libraries/armem/core/error/ArMemError.h index 219d489fad038da1098d724bddd9e2bc74b0a5d7..eb41318810e4f3512693ad71dce25f91282ec7b8 100644 --- a/source/RobotAPI/libraries/armem/core/error/ArMemError.h +++ b/source/RobotAPI/libraries/armem/core/error/ArMemError.h @@ -173,43 +173,22 @@ namespace armarx::armem::error }; - /** - * @brief Indicates that a path does not point to a directory. - */ - class PathNotADirectory : public ArMemError - { - public: - - PathNotADirectory(const std::string& path, const std::string& message = ""); - - static std::string makeMsg(const std::string& path, const std::string& message = ""); - - }; /** - * @brief Indicates that a path does not point to a regular file. + * @brief Indicates that something went wrong when accessing the filesystem. */ - class PathNotARegularFile : public ArMemError + class IOError : public ArMemError { public: - PathNotARegularFile(const std::string& path, const std::string& message = ""); + IOError(const std::string& path, const std::string& message = ""); static std::string makeMsg(const std::string& path, const std::string& message = ""); - }; - /** - * @brief Indicates that a path does not exist. - */ - class PathDoesNotExist : public ArMemError - { - public: - - PathDoesNotExist(const std::string& path, const std::string& message = ""); - - static std::string makeMsg(const std::string& path, const std::string& message = ""); + std::string path; }; + } diff --git a/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.cpp b/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.cpp index 2e8c64d64121eccc007cad7ba2d55c2e361b94e2..53e6f0169ab5ccb459ff730d67651836e78d5ec1 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.cpp +++ b/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.cpp @@ -1,20 +1,23 @@ -// Header #include "LongtermMemoryBase.h" -// ArmarX -#include <ArmarXCore/core/time/TimeUtil.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 { - void LongtermMemoryBase::setName(const std::string& name) + void + LongtermMemoryBase::setName(const std::string& name) { cache.name() = name; lut.name() = name; } - armem::wm::Memory LongtermMemoryBase::getCacheAndLutNotConverted() const + + armem::wm::Memory + LongtermMemoryBase::getCacheAndLutNotConverted() const { std::lock_guard l(cache_mutex); std::lock_guard l2(lut_mutex); @@ -32,23 +35,43 @@ namespace armarx::armem::server::ltm return m; } - void LongtermMemoryBase::append(const armem::wm::Memory& m) + + template <class ...Args> + void LongtermMemoryBase::_append(const armem::base::MemoryBase<Args...>& memory) { TIMING_START(LTM_Append); - ARMARX_INFO << "Append memory with name '" << m.name() << "' into the LTM with name '" << cache.name() << "'"; + ARMARX_INFO << "Append memory with name '" << memory.name() << "' into the LTM with name '" + << cache.name() << "'"; std::lock_guard l(cache_mutex); - cache.append(m); + cache.append(memory); encodeAndStore(); TIMING_END(LTM_Append); } - void LongtermMemoryBase::checkUpdateLatestSnapshot(const armem::wm::EntitySnapshot& newSnapshot) + + void + LongtermMemoryBase::append(const armem::wm::Memory& memory) + { + this->_append(memory); + } + + + void + LongtermMemoryBase::append(const armem::server::wm::Memory& memory) + { + this->_append(memory); + } + + + void + LongtermMemoryBase::checkUpdateLatestSnapshot(const armem::wm::EntitySnapshot& newSnapshot) { // update map of latestSnapshots - if (auto it = latestSnapshots.find(newSnapshot.id().getEntityID().str()); it != latestSnapshots.end()) + if (auto it = latestSnapshots.find(newSnapshot.id().getEntityID().str()); + it != latestSnapshots.end()) { auto ptr = it->second; if (ptr->id().timestamp > newSnapshot.id().timestamp) @@ -64,7 +87,9 @@ namespace armarx::armem::server::ltm } } - bool LongtermMemoryBase::containsCoreSegment(const MemoryID& coreSegmentID) const + + bool + LongtermMemoryBase::containsCoreSegment(const MemoryID& coreSegmentID) const { //ARMARX_INFO << "Check if lut has core seg"; if (lut.hasCoreSegment(coreSegmentID.coreSegmentName)) @@ -75,7 +100,9 @@ namespace armarx::armem::server::ltm return false; } - bool LongtermMemoryBase::containsProviderSegment(const MemoryID& providerSegmentID) const + + bool + LongtermMemoryBase::containsProviderSegment(const MemoryID& providerSegmentID) const { //ARMARX_INFO << "Check if lut has prov seg"; if (lut.hasCoreSegment(providerSegmentID.coreSegmentName)) @@ -90,7 +117,9 @@ namespace armarx::armem::server::ltm return false; } - bool LongtermMemoryBase::containsEntity(const MemoryID& entityID) const + + bool + LongtermMemoryBase::containsEntity(const MemoryID& entityID) const { //ARMARX_INFO << "Check if lut has entity"; if (lut.hasCoreSegment(entityID.coreSegmentName)) @@ -109,7 +138,9 @@ namespace armarx::armem::server::ltm return false; } - bool LongtermMemoryBase::containsSnapshot(const MemoryID& snapshotID) const + + bool + LongtermMemoryBase::containsSnapshot(const MemoryID& snapshotID) const { //ARMARX_INFO << "Check if lut has snapshot"; if (lut.hasCoreSegment(snapshotID.coreSegmentName)) @@ -131,4 +162,5 @@ namespace armarx::armem::server::ltm } return false; } -} + +} // 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 index 097f951548cc777fa03cedbc5f425e867439cd48..463c4c37998bd95ce4ec81f2e92eb0c937e2dc7c 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.h +++ b/source/RobotAPI/libraries/armem/server/ltm/LongtermMemoryBase.h @@ -1,11 +1,14 @@ #pragma once -// STD / STL -#include <optional> +#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> -// Memory -#include "../../core/wm/memory_definitions.h" namespace armarx::armem::server::ltm { @@ -26,10 +29,10 @@ namespace armarx::armem::server::ltm struct ReloadResult { - }; - void append(const armem::wm::Memory&); + void append(const armem::wm::Memory& memory); + void append(const armem::server::wm::Memory& memory); virtual void reload() = 0; virtual void convert(armem::wm::Memory&) = 0; @@ -61,5 +64,11 @@ namespace armarx::armem::server::ltm /// A map from entityID to its latest snapshot stored. When adding a new snapshot we compare it to the last one stored. std::map<std::string, 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/disk/MemoryManager.h b/source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.h index 227d419119e3889006a3f0f30a4789e3b9e76dfe..e9eeffb05667a7e4feeb9c638abea41be02201cd 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.h +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/MemoryManager.h @@ -1,18 +1,16 @@ #pragma once -// STD / STL +#include <filesystem> #include <mutex> #include <optional> -#include <filesystem> -// Base Class -#include "../LongtermMemoryBase.h" +#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 MemoryManager : - public LongtermMemoryBase + class MemoryManager : public LongtermMemoryBase { using Base = LongtermMemoryBase; @@ -23,14 +21,13 @@ namespace armarx::armem::server::ltm::disk void convert(armem::wm::Memory&) override; void encodeAndStore() override; - void setBasePath(const std::filesystem::path& p) + void + setBasePath(const std::filesystem::path& p) { basePathToMemory = p; } protected: - - private: bool checkPath() const; @@ -41,4 +38,5 @@ namespace armarx::armem::server::ltm::disk static const constexpr char* TYPE_FILENAME = "type.aron.ltm.json"; static const constexpr char* DATA_FILENAME = "data.aron.ltm.json"; }; -} + +} // namespace armarx::armem::server::ltm::disk diff --git a/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp b/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp index e361438099e5e2a34b80d5f64f810a23fb3270d2..166256ba2e20bc72b560f481069b4fb9a927a825 100644 --- a/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp +++ b/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp @@ -1,6 +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 <ArmarXCore/core/exceptions/local/ExpressionException.h> @@ -148,18 +149,9 @@ namespace armarx::armem::gui::disk { if (dir.is_directory()) { - const std::string key = dir.path().filename(); - armem::server::ltm::disk::MemoryManager manager; - manager.setName(key); - manager.setBasePath(path / key); - - manager.reload(); - - armem::server::query_proc::ltm::MemoryQueryProcessor ltm_processor; - armem::wm::Memory query_res = ltm_processor.process(queryIce, manager.getCacheAndLutNotConverted()); - - manager.convert(query_res); - memoryData[key] = std::move(query_res); + std::string memoryName = dir.path().filename(); + armem::wm::Memory memory = armem::server::ltm::disk::load(dir.path()); + memoryData[memoryName] = std::move(memory); numLoaded++; }