From b103038cb683b3d61cf2b69f14faeb647e713871 Mon Sep 17 00:00:00 2001 From: Fabian Peller-Konrad <fabian.peller-konrad@kit.edu> Date: Wed, 10 Nov 2021 14:55:03 +0100 Subject: [PATCH] Buffered LTM now mixin --- .../ltm/base/detail/BufferedMemoryBase.h | 30 +++---- .../server/ltm/base/detail/LUTMemoryBase.h | 1 + .../armem/server/ltm/disk/Memory.cpp | 78 +++++++++++++------ .../libraries/armem/server/ltm/disk/Memory.h | 13 ++-- 4 files changed, 76 insertions(+), 46 deletions(-) diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/BufferedMemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/BufferedMemoryBase.h index 41f17c6b8..e03084a0b 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/BufferedMemoryBase.h +++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/BufferedMemoryBase.h @@ -4,23 +4,26 @@ namespace armarx::armem::server::ltm { - template <class _CoreSegmentT> - class BufferedMemoryBase : virtual public MemoryBase<_CoreSegmentT> + class BufferedMemoryItem { public: - using MemoryBase<_CoreSegmentT>::MemoryBase; - BufferedMemoryBase(const MemoryID&) = delete; // remove non-default constructor + BufferedMemoryItem() = default; + BufferedMemoryItem(const MemoryID& id) : + buffer(id) + { + } + + virtual ~BufferedMemoryItem() = default; armem::wm::Memory getBuffer() const { - std::lock_guard l(this->ltm_mutex); return buffer; } void directlyStore(const armem::wm::Memory& memory) { TIMING_START(LTM_Memory_DirectlyStore); - _directlyStore(memory); + _directlyStore(memory); TIMING_END(LTM_Memory_DirectlyStore); } @@ -28,31 +31,22 @@ namespace armarx::armem::server::ltm { if (buffer.empty()) { - ARMARX_INFO << "Cannot store an empty buffer. Ignoring."; + ARMARX_INFO << deactivateSpam() << "Cannot store an empty buffer. Ignoring."; return; } this->directlyStore(buffer); buffer.clear(); } - void setMemoryID(const MemoryID& id) override - { - MemoryBase<_CoreSegmentT>::setMemoryID(id); - buffer.name() = this->name(); - } - protected: virtual void _directlyStore(const armem::wm::Memory& memory) = 0; - void _store(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) + /// This buffer may still be filtered. + /// This means that it is not guaranteed that all data in the buffer will be stored in the ltm armem::wm::Memory buffer; }; diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/LUTMemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/LUTMemoryBase.h index 159e1912c..597f4e387 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/LUTMemoryBase.h +++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/LUTMemoryBase.h @@ -4,6 +4,7 @@ namespace armarx::armem::server::ltm { + // TODO refactor to mixin (see buffered) template <class _CoreSegmentT> class CachedMemoryBase : virtual public MemoryBase<_CoreSegmentT> { diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp index ffb38022f..8797b7cd6 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp @@ -5,6 +5,13 @@ #include <RobotAPI/libraries/armem/server/wm/memory_definitions.h> +// ArmarX +#include "../base/filter/frequencyFilter/FrequencyFilter.h" +#include "../base/extractor/noExtractor/NoExtractor.h" +#include "../base/extractor/imageExtractor/ImageExtractor.h" +#include "../base/converter/dict/json/JsonConverter.h" +#include "../base/converter/dict/bson/BsonConverter.h" +#include "../base/converter/image/png/PngConverter.h" namespace armarx::armem::server::ltm::disk { @@ -12,44 +19,57 @@ namespace armarx::armem::server::ltm::disk { MemoryID getMemoryIDFromPath(const std::filesystem::path& p) { + ARMARX_CHECK(!p.empty()); + util::ensureFolderExists(p); MemoryID m; m.memoryName = p.filename(); return m; } + + std::filesystem::path getDefaultStoragePath() + { + /*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";*/ + return "/tmp/MemoryExport/Test"; + } } - Memory::Memory() : - BufferedMemoryBase(), - DiskStorage() + void Memory::createPropertyDefinitions(PropertyDefinitionsPtr& properties, const std::string& prefix) { - filter = std::make_shared<filter::FrequencyFilter>(); - setMemoryID(MemoryID("Test", "")); + properties->optional(path, prefix + "storagepath", "The path to the memory storage."); + } - /*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() : + Memory(getDefaultStoragePath()) + { } Memory::Memory(const std::filesystem::path& p) : - BufferedMemoryBase(), - DiskStorage(p) + Base(getMemoryIDFromPath(p)), + BufferedMemoryItem(getMemoryIDFromPath(p)), + DiskMemoryItem(p) { - filter = std::make_shared<filter::FrequencyFilter>(); - setPath(p); - setMemoryID(getMemoryIDFromPath(p)); + pipeline.memFilter = std::make_shared<filter::MemoryFrequencyFilter>(); + pipeline.snapFilter = std::make_shared<filter::SnapshotFrequencyFilter>(); + pipeline.extractor = std::make_shared<extractor::ImageExtractor>(); + pipeline.dictConverter = std::make_shared<converter::dict::JsonConverter>(); + pipeline.imgConverter = std::make_shared<converter::image::PngConverter>(); } void Memory::setMemoryID(const MemoryID& id) { - BufferedMemoryBase::setMemoryID(id); + ARMARX_CHECK_NOT_EMPTY(id.memoryName); + + Base::setMemoryID(id.getMemoryID()); std::filesystem::path p(path); - setPath(p.parent_path() / id.memoryName); + path = (p.parent_path() / id.memoryName); + buffer.id() = id.getMemoryID(); } std::string Memory::getExpectedFolderName() const @@ -70,7 +90,7 @@ namespace armarx::armem::server::ltm::disk for (const auto& subdir : std::filesystem::directory_iterator(p)) { std::filesystem::path subdirPath = subdir.path(); - CoreSegment c(subdirPath); + CoreSegment c(subdirPath, pipeline); func(c); } return true; @@ -88,7 +108,7 @@ namespace armarx::armem::server::ltm::disk std::filesystem::path subpath = p / n; util::ensureFolderExists(subpath, false); - auto c = std::make_shared<CoreSegment>(subpath); + auto c = std::make_shared<CoreSegment>(subpath, pipeline); return c; } @@ -114,13 +134,25 @@ namespace armarx::armem::server::ltm::disk 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); + CoreSegment c((std::filesystem::path(path) / e.id().coreSegmentName), pipeline); c.load(e); }); } + void Memory::_store(const armem::wm::Memory& memory) + { + std::lock_guard l(this->ltm_mutex); + buffer.append(memory); + } + void Memory::_directlyStore(const armem::wm::Memory& memory) { + if (!this->pipeline.memFilter->accept(memory)) + { + ARMARX_WARNING << deactivateSpam() << "Ignoring to put a Memory into the LTM because it got filtered."; + return; + } + if (!checkPath()) { return; @@ -131,7 +163,7 @@ namespace armarx::armem::server::ltm::disk memory.forEachCoreSegment([this](const auto& core) { util::ensureFolderExists(std::filesystem::path(path) / core.id().coreSegmentName); - CoreSegment c(std::filesystem::path(path) / core.id().coreSegmentName); + CoreSegment c((std::filesystem::path(path) / core.id().coreSegmentName), pipeline); c.store(core); }); } diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h index 3a29444fe..aae36c932 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h @@ -9,23 +9,25 @@ // Segmnet Type #include "CoreSegment.h" -// Config -#include <RobotAPI/libraries/armem/server/ltm/base/filter/frequencyFilter/FrequencyFilter.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 MemoryBase<CoreSegment>, + public BufferedMemoryItem, + public DiskMemoryItem { public: + using Base = MemoryBase<CoreSegment>; + Memory(); Memory(const std::filesystem::path&); void setMemoryID(const MemoryID& id) override; + void createPropertyDefinitions(PropertyDefinitionsPtr& properties, const std::string& prefix) override; + bool forEachCoreSegment(std::function<void(CoreSegment&)>&& func) const override; std::shared_ptr<CoreSegment> findCoreSegment(const std::string&) const override; @@ -33,6 +35,7 @@ namespace armarx::armem::server::ltm::disk protected: void _loadAll(armem::wm::Memory&) override; void _load(armem::wm::Memory&) override; + void _store(const armem::wm::Memory&) override; void _directlyStore(const armem::wm::Memory&) override; std::string getExpectedFolderName() const override; -- GitLab