From da86677880ee6e2c6879cb4fd0154edb12edbf75 Mon Sep 17 00:00:00 2001
From: "fabian.peller-konrad@kit.edu" <fabian.peller-konrad@kit.edu>
Date: Tue, 3 Aug 2021 13:57:59 +0200
Subject: [PATCH] removed disk ltm from query type. Added file browser to
 memory gui. Removed AlwaysTransfer setting from ltm

---
 source/RobotAPI/interface/armem/query.ice     |  3 +-
 .../armem/core/longtermmemory/Memory.cpp      | 12 +--
 .../armem/core/longtermmemory/Memory.h        |  8 +-
 .../armem/core/workingmemory/Memory.cpp       |  5 +
 .../armem/core/workingmemory/Memory.h         |  8 ++
 .../armem/server/MemoryToIceAdapter.cpp       | 12 +--
 .../diskmemory/BaseQueryProcessor.h           |  2 +-
 .../armem_gui/MemoryControlWidget.cpp         | 38 ++++++--
 .../libraries/armem_gui/MemoryControlWidget.h |  7 ++
 .../libraries/armem_gui/MemoryViewer.cpp      | 91 +++++++++++--------
 .../query_widgets/SnapshotSelectorWidget.cpp  | 24 +++--
 .../query_widgets/SnapshotSelectorWidget.h    |  4 +-
 12 files changed, 128 insertions(+), 86 deletions(-)

diff --git a/source/RobotAPI/interface/armem/query.ice b/source/RobotAPI/interface/armem/query.ice
index 2a1586fec..936294507 100644
--- a/source/RobotAPI/interface/armem/query.ice
+++ b/source/RobotAPI/interface/armem/query.ice
@@ -14,8 +14,7 @@ module armarx
                 enum QueryTarget
                 {
                     WM,
-                    LTM,
-                    Disk
+                    LTM
                 };
                 sequence<QueryTarget> QueryTargets;
 
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
index 2080879c5..316368676 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
@@ -13,7 +13,6 @@ namespace armarx::armem::ltm
     Memory::Memory(const Memory& other) :
         Base(other),
         dbsettings(other.dbsettings),
-        alwaysTransferSettings(other.alwaysTransferSettings),
         periodicTransferSettings(other.periodicTransferSettings),
         onFullTransferSettings(other.onFullTransferSettings),
         mongoDBMutex()
@@ -25,7 +24,6 @@ namespace armarx::armem::ltm
     Memory::Memory(Memory&& other) :
         Base(other),
         dbsettings(other.dbsettings),
-        alwaysTransferSettings(other.alwaysTransferSettings),
         periodicTransferSettings(other.periodicTransferSettings),
         onFullTransferSettings(other.onFullTransferSettings),
         reloaded(other.reloaded)
@@ -38,7 +36,6 @@ namespace armarx::armem::ltm
     {
         Base::operator=(other);
         dbsettings = other.dbsettings;
-        alwaysTransferSettings = other.alwaysTransferSettings;
         periodicTransferSettings = other.periodicTransferSettings;
         onFullTransferSettings = other.onFullTransferSettings;
 
@@ -51,7 +48,6 @@ namespace armarx::armem::ltm
     {
         Base::operator=(other);
         dbsettings = std::move(other.dbsettings);
-        alwaysTransferSettings = std::move(other.alwaysTransferSettings);
         periodicTransferSettings = std::move(other.periodicTransferSettings);
         onFullTransferSettings = std::move(other.onFullTransferSettings);
         reloaded = other.reloaded;
@@ -69,7 +65,7 @@ namespace armarx::armem::ltm
             ARMARX_WARNING << deactivateSpam("ConnectionIsNotValid")
                            << "The connection to mongocxx for memory '" << name() << "' is not valid. Settings are: " << dbsettings.toString()
                            << "\nTo start it, run e.g.: \n"
-                           << "mongod --port " << dbsettings.port << " --dbpath \"/tmp/\""
+                           << "armarx memory start"
                            << "\n\n";
             return false;
         }
@@ -83,9 +79,8 @@ namespace armarx::armem::ltm
         defs->optional(dbsettings.user, prefix + "ltm.20_user");
         defs->optional(dbsettings.password, prefix + "ltm.21_password");
         defs->optional(dbsettings.database, prefix + "ltm.22_database");
-        defs->optional(alwaysTransferSettings.enabled, prefix + "ltm.30_enableAlwaysTransfer", "Enable transfer whenever new data is committed (This disables the other transfer modes!).");
-        defs->optional(periodicTransferSettings.enabled, prefix + "ltm.31_enablePeriodicTransfer", "Enable transfer based on periodic interval.");
-        defs->optional(onFullTransferSettings.enabled, prefix + "ltm.32_enableOnFullTransfer", "Enable transfer whenever the wm is full (see maxHistorySize).");
+        defs->optional(periodicTransferSettings.enabled, prefix + "ltm.30_enablePeriodicTransfer", "Enable transfer based on periodic interval.");
+        defs->optional(onFullTransferSettings.enabled, prefix + "ltm.31_enableOnFullTransfer", "Enable transfer whenever the wm is full (see maxHistorySize).");
     }
 
     wm::Memory Memory::convert() const
@@ -230,7 +225,6 @@ namespace armarx::armem::ltm
             toAppendQueue.push_back(m);
             return;
         }
-
         _append(m);
     }
 }
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
index b24f4a7a6..4902701b3 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
@@ -10,7 +10,6 @@
 #include "../workingmemory/Memory.h"
 
 // Properties
-#include <ArmarXCore/core/application/properties/PluginAll.h>
 #include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
 
 namespace armarx::armem::ltm
@@ -33,11 +32,6 @@ namespace armarx::armem::ltm
             bool enabled = false;
         };
 
-        struct AlwaysTransferSettings : public TransferSettings
-        {
-
-        };
-
         struct PeriodicTransferSettings : public TransferSettings
         {
             bool deleteFromWMOnTransfer = false;
@@ -53,6 +47,7 @@ namespace armarx::armem::ltm
             };
 
             Mode mode;
+            int batch_size = 20;
         };
 
 
@@ -92,7 +87,6 @@ namespace armarx::armem::ltm
     public:
         MongoDBConnectionManager::MongoDBSettings dbsettings;
 
-        AlwaysTransferSettings alwaysTransferSettings;
         PeriodicTransferSettings periodicTransferSettings;
         OnFullTransferSettings onFullTransferSettings;
 
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp
index 70fd41e7c..3d0888c7f 100644
--- a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp
@@ -55,6 +55,11 @@ namespace armarx::armem::wm
     }
 
 
+    void Memory::defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix)
+    {
+    }
+
+
     // TODO: Add core segment if param is set
     Memory::Base::UpdateResult
     Memory::updateLocking(const EntityUpdate& update)
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h
index d52bce5ca..5093ffce2 100644
--- a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h
@@ -1,10 +1,15 @@
 #pragma once
 
+// Base Class
 #include <RobotAPI/libraries/armem/core/base/MemoryBase.h>
 
+// ArmarX
 #include "CoreSegment.h"
 #include "detail/CopyWithoutData.h"
 
+// Properties
+#include <ArmarXCore/core/application/properties/PluginAll.h>
+#include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
 
 namespace armarx::armem::wm
 {
@@ -27,6 +32,9 @@ namespace armarx::armem::wm
         Memory& operator=(const Memory& other) = default;
         Memory& operator=(Memory&& other) = default;
 
+        // PropertyDefinitions related to LTM
+        void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "");
+
         /**
          * @brief Perform the commit, locking the core segments.
          *
diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
index 354eec9ce..65bd2f642 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
+++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
@@ -176,17 +176,7 @@ namespace armarx::armem::server
                 // TODO: Move outside of loop?
                 if (longtermMemory)
                 {
-                    if (longtermMemory->alwaysTransferSettings.enabled)
-                    {
-                        wm::Memory tmp(longtermMemory->name());
-                        tmp._addMissingCoreSegmentDuringUpdate = true;
-                        tmp.update(update);
-                        longtermMemory->append(tmp);
-                    }
-                    else
-                    {
-                        // TODO: see below
-                    }
+
                 }
 
                 // TODO: Consollidate to ltm if onFilledTransfer is enabled (fabian.peller)
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h
index 469b5f907..0e3ddac45 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h
@@ -25,7 +25,7 @@ namespace armarx::armem::d_ltm::query_proc
 
         query::data::QueryTarget getTargetType() const override
         {
-            return query::data::QueryTarget::Disk;
+            return query::data::QueryTarget::LTM;
         }
 
     };
diff --git a/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.cpp b/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.cpp
index 5016db50b..38e4d8c88 100644
--- a/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.cpp
+++ b/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.cpp
@@ -4,6 +4,7 @@
 #include <QLineEdit>
 #include <QTimer>
 #include <QHBoxLayout>
+#include <QFileDialog>
 
 #include <cmath>
 
@@ -16,32 +17,53 @@ namespace armarx::armem::gui
         setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Fixed);
 
         auto vlayout = new QVBoxLayout();
-        auto hlayout = new QHBoxLayout();
+        auto hlayout1 = new QHBoxLayout();
+        auto hlayout2 = new QHBoxLayout();
+
+        hlayout1->setContentsMargins(10, 2, 10, 2);
+        hlayout2->setContentsMargins(10, 2, 10, 2);
 
         const int margin = 0;
         vlayout->setContentsMargins(margin, margin, margin, margin);
 
         _lineEdit = new QLineEdit("/tmp/MemoryExport", this);
         _lineEdit->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
-        _lineEdit->setMinimumWidth(400);
+        _lineEdit->setMinimumWidth(150);
+
+        _openFileBrowserButton = new QPushButton("Search files", this);
+
+        _storeOnDiskButton = new QPushButton("Store query (Disk)", this);
+        _storeInLTMButton = new QPushButton("Store query (LTM)", this);
 
-        _storeOnDiskButton = new QPushButton("Store current result on local Disk", this);
+        hlayout1->addWidget(_lineEdit);
+        hlayout1->addWidget(_openFileBrowserButton);
 
-        _storeInLTMButton = new QPushButton("Store current result in LTM", this);
+        hlayout2->addWidget(_storeOnDiskButton);
+        hlayout2->addWidget(_storeInLTMButton);
 
-        vlayout->addWidget(_lineEdit);
-        hlayout->addWidget(_storeOnDiskButton);
-        hlayout->addWidget(_storeInLTMButton);
-        vlayout->addItem(hlayout);
+        vlayout->addItem(hlayout1);
+        vlayout->addItem(hlayout2);
 
         this->setLayout(vlayout);
         // Private connections.
 
         // Public connections.
+        connect(_openFileBrowserButton, &QPushButton::pressed, this, &This::openFileBrowser);
         connect(_storeInLTMButton, &QPushButton::pressed, this, &This::storeInLTM);
         connect(_storeOnDiskButton, &QPushButton::pressed, this, &This::storeOnDisk);
     }
 
+    void MemoryControlWidget::openFileBrowser()
+    {
+        QFileDialog dialog;
+        dialog.setFileMode(QFileDialog::DirectoryOnly);
+        //dialog.setOption(QFileDialog::DontUseNativeDialog, true);
+        dialog.setOption(QFileDialog::ShowDirsOnly, false);
+        dialog.exec();
+        QString open = dialog.directory().path();
+        _lineEdit->setText(open);
+    }
+
     QLineEdit* MemoryControlWidget::pathInputBox()
     {
         return _lineEdit;
diff --git a/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.h b/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.h
index 19831694a..c6b156db3 100644
--- a/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.h
+++ b/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.h
@@ -4,6 +4,7 @@
 
 class QPushButton;
 class QLineEdit;
+class QFileDialog;
 
 namespace armarx::armem::gui
 {
@@ -20,11 +21,15 @@ namespace armarx::armem::gui
         QLineEdit* pathInputBox();
         QString getEnteredPath();
 
+        QPushButton* openFileBrowserButton();
+
         QPushButton* storeInLTMButton();
         QPushButton* storeOnDiskButton();
 
     public slots:
 
+        void openFileBrowser();
+
     signals:
 
         void storeInLTM();
@@ -40,6 +45,8 @@ namespace armarx::armem::gui
 
         QLineEdit* _lineEdit;
 
+        QPushButton* _openFileBrowserButton;
+
         QPushButton* _storeInLTMButton;
         QPushButton* _storeOnDiskButton;
 
diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
index f88a2e173..4edb2b417 100644
--- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
+++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
@@ -216,6 +216,8 @@ namespace armarx::armem::gui
 
     void MemoryViewer::updateMemories()
     {
+        int errorCnt = 0;
+
         memoryReaders.clear();
         memoryData.clear();
 
@@ -228,6 +230,8 @@ namespace armarx::armem::gui
 
         std::filesystem::path p(utf8_text);
 
+        armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput();
+
         // first check if the local file system should be queried
         if (memoryGroup->queryWidget()->alsoQueryLocalDisk())
         {
@@ -241,15 +245,13 @@ namespace armarx::armem::gui
                         armem::d_ltm::Memory dMem(k);
                         dMem.reload(p / k);
 
-                        armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput();
-                        input.addQueryTargetToAll(armem::query::data::QueryTarget::Disk);
+                        input.addQueryTargetToAll(armem::query::data::QueryTarget::LTM); // We use LTM as query target for the disk
 
                         armem::d_ltm::query_proc::MemoryQueryProcessor d_ltm_processor;
                         dMem = d_ltm_processor.process(input.toIce(), dMem);
 
                         wm::Memory converted = dMem.convert();
                         memoryData[k] = std::move(converted);
-                        dataChanged = true;
                     }
                 }
             }
@@ -257,67 +259,78 @@ namespace armarx::armem::gui
             {
                 ARMARX_WARNING << "Could not import a memory from '" << utf8_text << "'. Skipping import.";
             }
-        }
 
-        armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput();
-        for (auto& [name, reader] : memoryReaders)
+            dataChanged = true; // in any case we update the view (even if there was no result)
+        }
+        else
         {
-            TIMING_START(MemoryQuery);
+
+            for (auto& [name, reader] : memoryReaders)
             {
-                armem::client::QueryResult result = reader.query(input);
-                if (result)
+                TIMING_START(MemoryQuery);
                 {
-                    if (result.memory.hasData())
+                    armem::client::QueryResult result = reader.query(input);
+                    if (result)
                     {
-                        if (const auto& it = memoryData.find(name); it != memoryData.end())
+                        if (result.memory.hasData())
                         {
-                            result.memory.append(it->second);
-
-                            // requery (e.g. to get only the last n values instead of the last n from disk and the last n from wm)
-                            armem::wm::query_proc::MemoryQueryProcessor wm_processor;
-                            result.memory = wm_processor.process(input.toIce(), result.memory);
-
-                            if (!result.memory.hasData())
+                            if (const auto& it = memoryData.find(name); it != memoryData.end())
                             {
-                                ARMARX_ERROR << "A memory which had data before lost data. This indicates that there is something wrong.";
+                                // TODO is this necessary (or dead code?)
+                                result.memory.append(it->second);
+
+                                if (!result.memory.hasData())
+                                {
+                                    ARMARX_ERROR << "A memory which had data before lost data. This indicates that there is something wrong.";
+                                }
                             }
-                        }
 
-                        dataChanged = true;
-                        memoryData[name] = std::move(result.memory);
+                            memoryData[name] = std::move(result.memory);
+                        }
+                        else
+                        {
+                            ARMARX_INFO << "The memory " << name << " has no data after querying.";
+                        }
+                        dataChanged = true; // in any case we update the view (even if there was no result)
                     }
                     else
                     {
-                        ARMARX_INFO << "The memory " << name << " has no data after querying.";
+                        ARMARX_WARNING << "A query for memory '" << name << "' produced an error: " << result.errorMessage;
+                        errorCnt++;
                     }
                 }
-                else
+                TIMING_END_STREAM(MemoryQuery, ARMARX_VERBOSE);
+
+                if (debugObserver)
                 {
-                    ARMARX_WARNING << "A query for memory '" << name << "' produced an error: " << result.errorMessage;
-                    if (statusLabel)
-                    {
-                        statusLabel->setText(QString::fromStdString(result.errorMessage));
-                    }
+                    debugObserver->setDebugDatafield(Logging::tag.tagName, "Memory Query [ms]", new Variant(MemoryQuery.toMilliSecondsDouble()));
                 }
             }
-            TIMING_END_STREAM(MemoryQuery, ARMARX_VERBOSE);
-
-            if (debugObserver)
-            {
-                debugObserver->setDebugDatafield(Logging::tag.tagName, "Memory Query [ms]", new Variant(MemoryQuery.toMilliSecondsDouble()));
-            }
         }
 
+        // Code to output status label information
+        std::stringstream ss;
+        auto now = std::chrono::system_clock::now();
+        auto in_time_t = std::chrono::system_clock::to_time_t(now);
+        ss << "Last update: " << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X");
+
         if (dataChanged)
         {
             emit memoryDataChanged();
         }
         else
         {
-            if (statusLabel)
-            {
-                statusLabel->setText("No query result.");
-            }
+            ss << "- No query result. ";
+        }
+
+        if (errorCnt > 0)
+        {
+            ss << "The query produced " << errorCnt << " errors! Please check log.";
+        }
+
+        if (statusLabel)
+        {
+            statusLabel->setText(ss.str().c_str());
         }
     }
 
diff --git a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.cpp b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.cpp
index e41bed15c..9d5cc9ea6 100644
--- a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.cpp
+++ b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.cpp
@@ -26,11 +26,23 @@ namespace armarx::armem::gui
         {
             targets.push_back(query::data::QueryTarget::LTM);
         }
-        if (_DiskMemoryQueryTargetCheckBox->isChecked())
+        return targets;
+    }
+
+    void SnapshotSelectorWidget::localDiskStateChanged()
+    {
+        if (_LocalDiskMemoryQueryTargetCheckBox->isChecked())
         {
-            targets.push_back(query::data::QueryTarget::Disk);
+            _WMQueryTargetCheckBox->setChecked(false);
+            _LTMQueryTargetCheckBox->setChecked(false);
+            _WMQueryTargetCheckBox->setEnabled(false);
+            _LTMQueryTargetCheckBox->setEnabled(false);
+        }
+        else
+        {
+            _WMQueryTargetCheckBox->setEnabled(true);
+            _LTMQueryTargetCheckBox->setEnabled(true);
         }
-        return targets;
     }
 
     bool SnapshotSelectorWidget::queryTargetContainsLocalDisk() const
@@ -59,13 +71,13 @@ namespace armarx::armem::gui
             // query type select box
             auto queryTargetLayout = new QHBoxLayout();
             _WMQueryTargetCheckBox = new QCheckBox("WM");
-            _LTMQueryTargetCheckBox = new QCheckBox("LTM (MongoDB)");
-            _DiskMemoryQueryTargetCheckBox = new QCheckBox("LTM (Disk)");
+            _LTMQueryTargetCheckBox = new QCheckBox("LTM");
             _LocalDiskMemoryQueryTargetCheckBox = new QCheckBox("Local Disk");
 
+            connect(_LocalDiskMemoryQueryTargetCheckBox, &QCheckBox::stateChanged, this, &This::localDiskStateChanged);
+
             queryTargetLayout->addWidget(_WMQueryTargetCheckBox);
             queryTargetLayout->addWidget(_LTMQueryTargetCheckBox);
-            queryTargetLayout->addWidget(_DiskMemoryQueryTargetCheckBox);
             queryTargetLayout->addWidget(_LocalDiskMemoryQueryTargetCheckBox);
 
             _WMQueryTargetCheckBox->setChecked(true);
diff --git a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.h b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.h
index 6f6422c3c..a0b69eb1b 100644
--- a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.h
+++ b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.h
@@ -45,14 +45,13 @@ namespace armarx::armem::gui
     signals:
         void queryChanged();
 
-
     private slots:
 
         //void updateSelector();
 
         void hideAllForms();
         void showSelectedFormForQuery(QString selected);
-
+        void localDiskStateChanged();
 
     signals:
         void queryOutdated();
@@ -68,7 +67,6 @@ namespace armarx::armem::gui
         QComboBox* _queryComboBox;
         QCheckBox* _WMQueryTargetCheckBox;
         QCheckBox* _LTMQueryTargetCheckBox;
-        QCheckBox* _DiskMemoryQueryTargetCheckBox;
         QCheckBox* _LocalDiskMemoryQueryTargetCheckBox;
         /// The forms for the different query types. Hidden when not selected.
         std::map<QString, SnapshotForm*> _queryForms;
-- 
GitLab