diff --git a/source/RobotAPI/components/ArMemGlobalStorage/ArMemGlobalStorage.cpp b/source/RobotAPI/components/ArMemGlobalStorage/ArMemGlobalStorage.cpp index f379578e5fcf7cca267fa0cd5a5052e3e023827a..7ae852eeec344ba3d612068c3eb45aea70b1f66f 100644 --- a/source/RobotAPI/components/ArMemGlobalStorage/ArMemGlobalStorage.cpp +++ b/source/RobotAPI/components/ArMemGlobalStorage/ArMemGlobalStorage.cpp @@ -22,42 +22,105 @@ #include "ArMemGlobalStorage.h" +// STD/STL +#include <algorithm> -namespace armarx -{ - - std::string ArMemGlobalStorage::getDefaultName() const - { - return "ArMemGlobalStorage"; - } - - - void ArMemGlobalStorage::onInitComponent() - { - - } - - - void ArMemGlobalStorage::onConnectComponent() - { - - } - - - void ArMemGlobalStorage::onDisconnectComponent() - { +// Boost +#include <boost/asio.hpp> - } +// Simox +#include <SimoxUtility/algorithm/string.h> +// ArmarX +#include <RobotAPI/interface/armem.h> - void ArMemGlobalStorage::onExitComponent() +namespace armarx +{ + namespace armem { - } - - armarx::PropertyDefinitionsPtr ArMemGlobalStorage::createPropertyDefinitions() - { - PropertyDefinitionsPtr defs{new ComponentPropertyDefinitions{getConfigIdentifier()}}; - return defs; + armarx::PropertyDefinitionsPtr ArMemGlobalStorage::createPropertyDefinitions() + { + PropertyDefinitionsPtr defs{new ComponentPropertyDefinitions{getConfigIdentifier()}}; + + defs->optional(local_memory_hostnames, "LocalMemoryHostnames", "The hostnames of the local memories, comma separated"); + return defs; + } + + ArMemGlobalStorage::ArMemGlobalStorage(): + armarx::Component(), + armarx::armem::ArMemBase(), + armarx::armem::ArMemGlobalMemoryResolver() + { + } + + std::string ArMemGlobalStorage::getDefaultName() const + { + return "ArMemGlobalStorage"; + } + + + void ArMemGlobalStorage::onInitComponent() + { + for (const std::string& hostname : simox::alg::split(local_memory_hostnames, ",")) + { + usingProxy(GenerateLocalMemoryObjectNameFromHostname(hostname)); + } + } + + + void ArMemGlobalStorage::onConnectComponent() + { + for (const std::string& hostname : simox::alg::split(local_memory_hostnames, ",")) + { + ArMemLocalMemoryInterfacePrx localMemoryPrx = getProxy<ArMemLocalMemoryInterfacePrx>(GenerateLocalMemoryObjectNameFromHostname(hostname)); + local_memories[hostname] = localMemoryPrx; + } + } + + + void ArMemGlobalStorage::onDisconnectComponent() + { + + } + + + void ArMemGlobalStorage::onExitComponent() + { + + } + + std::string ArMemGlobalStorage::getHostnameOfCurrentMachine(const Ice::Current&) + { + return getMyHostname(); + } + + ArMemLocalMemoryInterfacePrx ArMemGlobalStorage::getMemoryOfCurrentMachine(const Ice::Current& c) + { + return getMemoryForHostname(getMyHostname(), c); + } + + ArMemLocalMemoryInterfacePrx ArMemGlobalStorage::getMemoryForHostname(const std::string& hostname, const Ice::Current&) + { + if (local_memories.find(hostname) == local_memories.end()) + { + throw LocalException("The local memory of host '" + hostname + "' does not exist!. Could not return proxy!"); + } + return local_memories[hostname]; + } + + void ArMemGlobalStorage::dynamicallyRegisterNewLocalMemory(const std::string& hostname, const Ice::Current&) + { + if (local_memories.find(hostname) == local_memories.end()) + { + ArMemLocalMemoryInterfacePrx localMemoryPrx = getProxy<ArMemLocalMemoryInterfacePrx>(GenerateLocalMemoryObjectNameFromHostname(hostname)); + local_memories[hostname] = localMemoryPrx; + } + } + + void ArMemGlobalStorage::exportDataOfAllMemoriesToLocation(const std::string&, const Ice::Current&) + { + // TODO!! Needs Aron-JSON Export? + } } } diff --git a/source/RobotAPI/components/ArMemGlobalStorage/ArMemGlobalStorage.h b/source/RobotAPI/components/ArMemGlobalStorage/ArMemGlobalStorage.h index 16a5afc2018513d13345f1c509648623772095ff..f3534e096425a2719ec6d460cefafc3de38b15b6 100644 --- a/source/RobotAPI/components/ArMemGlobalStorage/ArMemGlobalStorage.h +++ b/source/RobotAPI/components/ArMemGlobalStorage/ArMemGlobalStorage.h @@ -22,25 +22,49 @@ #pragma once +// STD/STL +#include <map> +// Aron +#include <RobotAPI/interface/aron.h> +#include <RobotAPI/interface/armem.h> + +// ArmarX #include <ArmarXCore/core/Component.h> +#include <RobotAPI/libraries/armem/ArMemBase.h> namespace armarx { - class ArMemGlobalStorage : - virtual public armarx::Component + namespace armem { - public: - std::string getDefaultName() const override; + class ArMemGlobalStorage : + virtual public armarx::Component, + virtual public armarx::armem::ArMemBase, + virtual public armarx::armem::ArMemGlobalMemoryResolver + { + public: + ArMemGlobalStorage(); + + std::string getDefaultName() const override; + + std::string getHostnameOfCurrentMachine(const Ice::Current& = Ice::Current()); + ArMemLocalMemoryInterfacePrx getMemoryOfCurrentMachine(const Ice::Current& = Ice::Current()); + ArMemLocalMemoryInterfacePrx getMemoryForHostname(const std::string&, const Ice::Current& = Ice::Current()); + + void dynamicallyRegisterNewLocalMemory(const std::string&, const Ice::Current& = Ice::Current()); - protected: - void onInitComponent() override; - void onConnectComponent() override; - void onDisconnectComponent() override; - void onExitComponent() override; - armarx::PropertyDefinitionsPtr createPropertyDefinitions() override; + void exportDataOfAllMemoriesToLocation(const std::string&, const Ice::Current& = Ice::Current()); - private: + protected: + void onInitComponent() override; + void onConnectComponent() override; + void onDisconnectComponent() override; + void onExitComponent() override; + armarx::PropertyDefinitionsPtr createPropertyDefinitions() override; - }; + private: + std::string local_memory_hostnames; + std::map<std::string, ArMemLocalMemoryInterfacePrx> local_memories; + }; + } } diff --git a/source/RobotAPI/components/ArMemGlobalStorage/CMakeLists.txt b/source/RobotAPI/components/ArMemGlobalStorage/CMakeLists.txt index 768ddea4f7b4825cd002a248237be89727062ae9..df827fa04cd4f34d7c42c861581f12034698a157 100644 --- a/source/RobotAPI/components/ArMemGlobalStorage/CMakeLists.txt +++ b/source/RobotAPI/components/ArMemGlobalStorage/CMakeLists.txt @@ -3,6 +3,7 @@ armarx_component_set_name("ArMemGlobalStorage") set(COMPONENT_LIBS ArmarXCore ArmarXCoreInterfaces + RobotAPICore RobotAPIInterfaces armem ) @@ -15,4 +16,4 @@ armarx_add_component("${SOURCES}" "${HEADERS}") # add unit tests add_subdirectory(test) -armarx_generate_and_add_component_executable(APPLICATION_APP_SUFFIX) +armarx_generate_and_add_component_executable(COMPONENT_NAMESPACE "armarx::armem" APPLICATION_APP_SUFFIX) diff --git a/source/RobotAPI/components/ArMemGlobalStorage/test/ArMemGlobalStorageTest.cpp b/source/RobotAPI/components/ArMemGlobalStorage/test/ArMemGlobalStorageTest.cpp index 9b008a1b9accb23c2bb351348044d472dfd7a0cf..f5451b02e484b0fde7ce24805beb9b46cc5c2b60 100644 --- a/source/RobotAPI/components/ArMemGlobalStorage/test/ArMemGlobalStorageTest.cpp +++ b/source/RobotAPI/components/ArMemGlobalStorage/test/ArMemGlobalStorageTest.cpp @@ -31,7 +31,7 @@ BOOST_AUTO_TEST_CASE(testExample) { - armarx::ArMemGlobalStorage instance; + armarx::armem::ArMemGlobalStorage instance; BOOST_CHECK_EQUAL(true, true); } diff --git a/source/RobotAPI/components/ArMemLocalStorage/ArMemLocalStorage.cpp b/source/RobotAPI/components/ArMemLocalStorage/ArMemLocalStorage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb1c918d4f1bd5ca554877e3cf3452e456edfef2 --- /dev/null +++ b/source/RobotAPI/components/ArMemLocalStorage/ArMemLocalStorage.cpp @@ -0,0 +1,192 @@ +/* + * 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::ArMemLocalStorage + * @author fabian.peller-konrad@kit.edu ( fabian dot peller-konrad at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +// Header +#include "ArMemLocalStorage.h" + +// Boost +#include <boost/asio.hpp> + +namespace armarx +{ + + namespace armem + { + armarx::PropertyDefinitionsPtr ArMemLocalStorage::createPropertyDefinitions() + { + PropertyDefinitionsPtr defs{new ComponentPropertyDefinitions{getConfigIdentifier()}}; + defs->optional(maximum_segments, "MaximumNumberOfSegments", "Maximum number of segments (<0 means infinite)"); + defs->optional(maximum_entries_per_segment, "MaximumEntriesPerSegment", "Maximum number of accepted datatypes per segment (<0 means infinite)"); + defs->optional(maximum_entries_per_datatype, "MaximumEntriesPerDatatype", "Maximum number of accepted commits per datatype (<0 means infinite)"); + + return defs; + } + + std::string ArMemLocalStorage::getDefaultName() const + { + std::string hostname = getMyHostname(); + return GenerateLocalMemoryObjectNameFromHostname(hostname); + } + + ArMemLocalStorage::ArMemLocalStorage() : + armarx::Component(), + armarx::armem::ArMemBase(), + maximum_segments(-1), + maximum_entries_per_segment(-1), + maximum_entries_per_datatype(-1) + { + + } + + void ArMemLocalStorage::onInitComponent() + { + + } + + void ArMemLocalStorage::onConnectComponent() + { + + } + + void ArMemLocalStorage::onDisconnectComponent() + { + + } + + void ArMemLocalStorage::onExitComponent() + { + + } + + bool ArMemLocalStorage::hasSegment(const std::string& segment) const + { + auto index_pos = indexed_storage.find(segment); + auto timestamped_pos = timestamped_storage.find(segment); + auto hashed_pos = hashed_storage.find(segment); + + return index_pos == indexed_storage.end() || timestamped_pos == timestamped_storage.end() || hashed_pos == hashed_storage.end(); + } + + + std::string ArMemLocalStorage::commit(const std::string& segment, long sentAt, const std::vector<aron::AronDataPtr>& data, const Ice::Current&) + { + // Check if segment already exists + if (!hasSegment(segment)) + { + // Need to allocate a new storage for a new segment + ARMARX_WARNING << "A new segment '" + segment + "' registered to the memory. Allocating space for its members..."; + indexed_storage[segment] = IndexedDatatypeStorage(); + timestamped_storage[segment] = TimestampedDataTypeStorage(); + hashed_storage[segment] = HashedDataTypeStorage(); + } + + IndexedDatatypeStorage& indexed_segment_storage = indexed_storage[segment]; + TimestampedDataTypeStorage& timestamped_segment_storage = timestamped_storage[segment]; + HashedDataTypeStorage& hashed_segment_storage = hashed_storage[segment]; + + long now = IceUtil::Time::now().toMilliSeconds(); + if (sentAt > now) + { + ARMARX_WARNING << "Received an invalid timestamp. The timestamp when sending data to the segment '" + segment + "' is greater than the storage timestamp (The transmitted time needs to be in milliseconds [ms]). Please check!" ; + } + + // Create new memory entry and save result + ArMemCommitPtr entryPtr = ArMemCommitPtr(new ArMemCommit()); + entryPtr->producer = "TODO"; + entryPtr->stored_in_segment = segment; + entryPtr->produce_timestamp_ms = sentAt; + entryPtr->stored_in_segment = IceUtil::Time::now().toMilliSeconds(); + entryPtr->data = data; + + ARMARX_INFO_S << "Saving a new commit to segment '" + segment + "'"; + std::string string_to_hash = "commit_to_" + segment + "_at_" + std::to_string(now); + size_t hash = std::hash<std::string> {}(string_to_hash); + + if (timestamped_segment_storage.find(now) != timestamped_segment_storage.end()) + { + ARMARX_WARNING << "The segment '" + segment + "' already contains a value at timestamp " + std::to_string(now) + ". Overwriting value!"; + } + if (hashed_segment_storage.find(hash) != hashed_segment_storage.end()) + { + ARMARX_WARNING << "The segment '" + segment + "' already contains data at the commit hash " + std::to_string(hash) + ". Overwriting value!"; + } + + indexed_segment_storage.push_back(entryPtr); + timestamped_segment_storage[now] = entryPtr; + hashed_segment_storage[hash] = entryPtr; + return std::to_string(hash); + } + + std::string ArMemLocalStorage::commit_single(const std::string& segment, long generatedTS, const aron::AronDataPtr& x, const Ice::Current& c) + { + return commit(segment, generatedTS, {x}, c); + } + + void ArMemLocalStorage::checkStorageIntegrity() const + { + if (indexed_storage.size() != timestamped_storage.size() || + indexed_storage.size() != hashed_storage.size() || + timestamped_storage.size() != hashed_storage.size()) + { + throw LocalException("The memory is in an invalid state. The storages have different sizes! Please Check!"); + } + for (const auto& [segment, datatypeStorage] : indexed_storage) + { + if (!hasSegment(segment)) + { + throw LocalException("The memory is in an invalid state. Not all storages contain the segment '" + segment + "'! Please Check!"); + } + } + } + + void ArMemLocalStorage::checkStorageIntegrityForSegment(const std::string& segment) const + { + + } + + + ArMemCommitPtr ArMemLocalStorage::getLatestCommitFromSegment(const std::string& segment, const Ice::Current &) + { + int index = indexed_storage[segment].size() -1; + if(index >= 0) + { + return indexed_storage[segment][index]; + } + return nullptr; + } + + ArMemCommitPtr ArMemLocalStorage::getNextCommitFromSegmentForTimestamp(const std::string &, Ice::Long, const Ice::Current &) + { + return nullptr; + } + + TimestampedArMemCommitList ArMemLocalStorage::getAllCommitsBetweenTimestampsFromSegment(const std::string &, Ice::Long, Ice::Long, const Ice::Current &) + { + return {}; + } + + TimestampedArMemCommitList ArMemLocalStorage::getAllCommitsFromSegment(const std::string &, const Ice::Current &) + { + return {}; + } + } +} diff --git a/source/RobotAPI/components/ArMemLocalStorage/ArMemLocalStorage.h b/source/RobotAPI/components/ArMemLocalStorage/ArMemLocalStorage.h new file mode 100644 index 0000000000000000000000000000000000000000..e0e277b28aa29cae01945d0c5e70de0a4a9af4e7 --- /dev/null +++ b/source/RobotAPI/components/ArMemLocalStorage/ArMemLocalStorage.h @@ -0,0 +1,89 @@ +/* + * 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::ArMemLocalStorage + * @author fabian.peller-konrad@kit.edu ( fabian dot peller-konrad at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +// STD/STL +#include <map> + +// Aron +#include <RobotAPI/interface/aron.h> +#include <RobotAPI/interface/armem.h> + +// ArmarX +#include <ArmarXCore/core/Component.h> +#include <RobotAPI/libraries/armem/ArMemBase.h> + +namespace armarx +{ + + namespace armem + { + class ArMemLocalStorage : + virtual public armarx::Component, + virtual public armarx::armem::ArMemBase, + virtual public armarx::armem::ArMemLocalMemoryInterface + { + public: + typedef std::vector<ArMemCommitPtr> IndexedDatatypeStorage; + typedef std::map<long, ArMemCommitPtr> TimestampedDataTypeStorage; + typedef std::map<std::size_t, ArMemCommitPtr> HashedDataTypeStorage; + + ArMemLocalStorage(); + + std::string getDefaultName() const override; + + bool hasSegment(const std::string&) const; + long size(const std::string&) const; + + ArMemCommitPtr getLatestCommitFromSegment(const std::string&, const Ice::Current& = Ice::Current()); + ArMemCommitPtr getNextCommitFromSegmentForTimestamp(const std::string&, long, const Ice::Current& = Ice::Current()); + TimestampedArMemCommitList getAllCommitsBetweenTimestampsFromSegment(const std::string&, Ice::Long, Ice::Long, const Ice::Current& = Ice::Current()); + TimestampedArMemCommitList getAllCommitsFromSegment(const std::string&, const Ice::Current& = Ice::Current()); + + std::string commit(const std::string& segment, long generatedTS, const std::vector<aron::AronDataPtr>&, const Ice::Current& = Ice::Current()); + std::string commit_single(const std::string& segment, long generatedTS, const aron::AronDataPtr&, const Ice::Current& = Ice::Current()); + + protected: + void onInitComponent() override; + void onConnectComponent() override; + void onDisconnectComponent() override; + void onExitComponent() override; + + armarx::PropertyDefinitionsPtr createPropertyDefinitions() override; + + private: + + void checkStorageIntegrity() const; + void checkStorageIntegrityForSegment(const std::string&) const; + + private: + std::map<std::string, IndexedDatatypeStorage> indexed_storage; + std::map<std::string, TimestampedDataTypeStorage> timestamped_storage; + std::map<std::string, HashedDataTypeStorage> hashed_storage; + + long maximum_segments; + long maximum_entries_per_segment; + long maximum_entries_per_datatype; + }; + } +} diff --git a/source/RobotAPI/components/ArMemLocalStorage/CMakeLists.txt b/source/RobotAPI/components/ArMemLocalStorage/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..38cac48d2c54abd4d58c5a64ea5fe6b178a1b79a --- /dev/null +++ b/source/RobotAPI/components/ArMemLocalStorage/CMakeLists.txt @@ -0,0 +1,34 @@ +armarx_component_set_name("ArMemLocalStorage") + + +set(COMPONENT_LIBS + ArmarXCore + ArmarXCoreInterfaces + RobotAPICore + RobotAPIInterfaces + armem +) + +set(SOURCES + ./ArMemLocalStorage.cpp +) +set(HEADERS + ./ArMemLocalStorage.h +) + + +armarx_add_component("${SOURCES}" "${HEADERS}") + +#find_package(MyLib QUIET) +#armarx_build_if(MyLib_FOUND "MyLib not available") +# all target_include_directories must be guarded by if(Xyz_FOUND) +# for multiple libraries write: if(X_FOUND AND Y_FOUND).... +#if(MyLib_FOUND) +# target_include_directories(ArMemLocalStorage PUBLIC ${MyLib_INCLUDE_DIRS}) +#endif() + +# add unit tests +add_subdirectory(test) + +#generate the application +armarx_generate_and_add_component_executable(COMPONENT_NAMESPACE "armarx::armem" APPLICATION_APP_SUFFIX) diff --git a/source/RobotAPI/libraries/armem/ArMemWorkingMemory.h b/source/RobotAPI/components/ArMemLocalStorage/test/ArMemLocalStorageTest.cpp similarity index 60% rename from source/RobotAPI/libraries/armem/ArMemWorkingMemory.h rename to source/RobotAPI/components/ArMemLocalStorage/test/ArMemLocalStorageTest.cpp index d8ac0c02c41b669e732a06a81f3d94e9a9fbd7a4..48a74567fdd35708d0d6e30ee8b25f67f4381be3 100644 --- a/source/RobotAPI/libraries/armem/ArMemWorkingMemory.h +++ b/source/RobotAPI/components/ArMemLocalStorage/test/ArMemLocalStorageTest.cpp @@ -13,33 +13,25 @@ * 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 ) + * @package RobotAPI::ArmarXObjects::ArMemLocalStorage + * @author fabian.peller-konrad@kit.edu ( fabian dot peller-konrad at kit dot edu ) * @date 2020 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt * GNU General Public License */ -#pragma once +#define BOOST_TEST_MODULE RobotAPI::ArmarXObjects::ArMemLocalStorage +#define ARMARX_BOOST_TEST -namespace armarx -{ - /** - * @defgroup Library-armem armem - * @ingroup RobotAPI - * A description of the library armem. - * - * @class armem - * @ingroup Library-armem - * @brief Brief description of class armem. - * - * Detailed description of class armem. - */ - class armem - { - public: +#include <RobotAPI/Test.h> +#include <RobotAPI/components/ArMemLocalStorage/ArMemLocalStorage.h> + +#include <iostream> - }; +BOOST_AUTO_TEST_CASE(testExample) +{ + armarx::armem::ArMemLocalStorage instance; + BOOST_CHECK_EQUAL(true, true); } diff --git a/source/RobotAPI/components/ArMemLocalStorage/test/CMakeLists.txt b/source/RobotAPI/components/ArMemLocalStorage/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f72cfa041acff0351e753c642b077c34b3e807b8 --- /dev/null +++ b/source/RobotAPI/components/ArMemLocalStorage/test/CMakeLists.txt @@ -0,0 +1,5 @@ + +# Libs required for the tests +SET(LIBS ${LIBS} ArmarXCore ArMemLocalStorage) + +armarx_add_test(ArMemLocalStorageTest ArMemLocalStorageTest.cpp "${LIBS}") diff --git a/source/RobotAPI/components/CMakeLists.txt b/source/RobotAPI/components/CMakeLists.txt index f6672a7055291d75376831a026748404db17d7e0..fb382b82c1c1cf054a24da77b2e2cf5a22540bb4 100644 --- a/source/RobotAPI/components/CMakeLists.txt +++ b/source/RobotAPI/components/CMakeLists.txt @@ -25,3 +25,5 @@ add_subdirectory(ViewSelection) add_subdirectory(ArMemGlobalStorage) + +add_subdirectory(ArMemLocalStorage) \ No newline at end of file diff --git a/source/RobotAPI/interface/armem.ice b/source/RobotAPI/interface/armem.ice index 226f4bb3e3791bea544a4f909dc53c4e7b02c395..f5ced2684babf02ebe711b89efbe580f82f765a1 100644 --- a/source/RobotAPI/interface/armem.ice +++ b/source/RobotAPI/interface/armem.ice @@ -6,31 +6,49 @@ module armarx { module armem { - dictionary<long, aron::AronData> TimestampedAronDataList; + // data in a commit + class ArMemCommit + { + string producer; + string stored_in_segment; + long produce_timestamp_ms; + long storage_timestamp_ms; + aron::AronDataList data; + }; + + // map storageTS to commit + dictionary<long, ArMemCommit> TimestampedArMemCommitList; - interface ArMemWorkingMemoryReceiverInterface + + interface ArMemReceiverInterface { - aron::AronData getLatestEntryFromProducer(string producer); - aron::AronData getNextEntryFromProducerForTimestamp(string producer, long timestamp); - TimestampedAronDataList getAllEntriesBetweenTimestampsFromProducer(string producer, long timestamp1, long timestamp2); - TimestampedAronDataList getAllEntriesFromProducer(string producer); + ArMemCommit getLatestCommitFromSegment(string segment); + ArMemCommit getNextCommitFromSegmentForTimestamp(string segment, long timestamp); + TimestampedArMemCommitList getAllCommitsBetweenTimestampsFromSegment(string segment, long timestamp1, long timestamp2); + TimestampedArMemCommitList getAllCommitsFromSegment(string segment); }; - interface ArMemWorkingMemoryProducerInterface + interface ArMemProducerInterface { - void sendToMemory(string producer, long produceTimestamp, aron::AronData value); + string commit(string segment, long produceTimestamp, aron::AronDataList values); + string commit_single(string segment, long produceTimestamp, aron::AronData value); }; - interface ArMemWorkingMemoryInterface - extends ArMemWorkingMemoryReceiverInterface, ArMemWorkingMemoryProducerInterface + interface ArMemLocalMemoryInterface + extends ArMemReceiverInterface, ArMemProducerInterface { }; interface ArMemGlobalMemoryResolver { - ArMemWorkingMemoryInterface getMemporyForHostname(string hostname); - void exportAllDataToLocation(string location); + string getHostnameOfCurrentMachine(); + ArMemLocalMemoryInterface* getMemoryOfCurrentMachine(); + ArMemLocalMemoryInterface* getMemoryForHostname(string hostname); + + void dynamicallyRegisterNewLocalMemory(string hostname); + + void exportDataOfAllMemoriesToLocation(string location); } }; }; diff --git a/source/RobotAPI/libraries/armem/ArMemBase.cpp b/source/RobotAPI/libraries/armem/ArMemBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5048a42d4c4a424ff509e59b6a1dc3a1ddf63494 --- /dev/null +++ b/source/RobotAPI/libraries/armem/ArMemBase.cpp @@ -0,0 +1,54 @@ +/* + * 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 + */ + +// Header +#include "ArMemBase.h" + + +namespace armarx +{ + namespace armem + { + const std::string ArMemBase::DEFAULT_LOCAL_MEMORY_NAME_PREFIX = "ArMemLocalStorage"; + + ArMemBase::ArMemBase() + { + my_hostname = getMyHostname(); + } + + std::string ArMemBase::GenerateLocalMemoryObjectNameFromHostname(const std::string& hostname) + { + return DEFAULT_LOCAL_MEMORY_NAME_PREFIX + "__" + hostname; + } + + std::string ArMemBase::getMyHostname() const + { + return my_hostname; + } + + std::string ArMemBase::GetMyHostname() + { + boost::asio::io_service io_service; + return boost::asio::ip::host_name(); + } + } +} diff --git a/source/RobotAPI/libraries/armem/ArMemWorkingMemory.cpp b/source/RobotAPI/libraries/armem/ArMemBase.h similarity index 59% rename from source/RobotAPI/libraries/armem/ArMemWorkingMemory.cpp rename to source/RobotAPI/libraries/armem/ArMemBase.h index 601a7e37e774a759321cbd5f20004559f7781a85..851b2b869aa70a9271d3bc54021582d77977af57 100644 --- a/source/RobotAPI/libraries/armem/ArMemWorkingMemory.cpp +++ b/source/RobotAPI/libraries/armem/ArMemBase.h @@ -20,9 +20,38 @@ * GNU General Public License */ -#include "armem.h" +#pragma once + +// STD/STL +#include <string> + +// Boost +#include <boost/asio.hpp> + namespace armarx { + namespace armem + { + + class ArMemBase; + typedef std::shared_ptr<ArMemBase> ArMemBasePtr; + + class ArMemBase + { + + public: + ArMemBase(); + + std::string getMyHostname() const; + static std::string GetMyHostname(); + + static std::string GenerateLocalMemoryObjectNameFromHostname(const std::string&); + + private: + static const std::string DEFAULT_LOCAL_MEMORY_NAME_PREFIX; + std::string my_hostname; + }; + } } diff --git a/source/RobotAPI/libraries/armem/ArMemWorkingMemoryBase.cpp b/source/RobotAPI/libraries/armem/ArMemWorkingMemoryBase.cpp deleted file mode 100644 index 15ea5dcac2ddbcefc059805a45ca969b393c97c3..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/ArMemWorkingMemoryBase.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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 - */ - -// Header -#include "ArMemWorkingMemoryBase.h" - -// STD/STL -#include <vector> -#include <map> -#include <memory> -#include <unordered_map> - -// ArmarX -#include <ArmarXCore/core/logging/Logging.h> - -namespace armarx -{ - namespace armem - { - - ArMemWorkingMemoryBase::ArMemWorkingMemoryBase() : - maximumEntriesPerDatatype(-1), - maximumEntriesPerProducer(-1) - { - - } - - void ArMemWorkingMemoryBase::store(const std::string& producer, const std::string& datatype, long sentAt, const aron::data::AronDataNavigatorPtr& data) - { - if (storage.find(producer) == storage.end()) - { - // Need to allocate a new storage for a new producer - ARMARX_WARNING_S << "A new producer '" + producer + "' registered to the memory. Allocating space for its members..."; - storage[producer] = ProducerDatatypeStorage(); - } - - ProducerDatatypeStorage& producer_storage = storage[producer]; - if (producer_storage.find(datatype) == producer_storage.end()) - { - // Need to allocate a new storage for a new producer - ARMARX_WARNING_S << "A new datatype '" + datatype + "' registered to the memory to producer '" + producer + "'. Allocating space for its members..."; - producer_storage[datatype] = SingleDatatypeStorage(); - } - - SingleDatatypeStorage& datatype_storage = producer_storage[datatype]; - - long now = IceUtil::Time::now().toMilliSeconds(); - if (sentAt > now) - { - ARMARX_WARNING_S << "Received an invalid timestamp. The timestamp when sending data of type '" + datatype + "' from the producer '" + producer + "' is greater than the storage timestamp (The transmitted time needs to be in milliseconds [ms]). Please check!" ; - } - - // Create new memory entry and save result - ArMemEntryPtr entryPtr = ArMemEntryPtr(new ArMemEntry()); - entryPtr->producer = producer; - entryPtr->datatype = datatype; - entryPtr->produceTimestampMs = sentAt; - entryPtr->storageTimestampMs = IceUtil::Time::now().toMilliSeconds(); - entryPtr->value = data; - - ARMARX_INFO_S << "Saving a new entry of type '" + datatype + "' for producer '" + producer + "'"; - datatype_storage.push_back(entryPtr); - } - } -} diff --git a/source/RobotAPI/libraries/armem/ArMemWorkingMemoryBase.h b/source/RobotAPI/libraries/armem/ArMemWorkingMemoryBase.h deleted file mode 100644 index df8bb735e6cf2c5f8ab94a4d985d47c36705a240..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem/ArMemWorkingMemoryBase.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 - */ - -#pragma once - -// STD/STL -#include <vector> -#include <map> -#include <memory> -#include <unordered_map> - -// ArmarX -#include <RobotAPI/interface/armem.h> -#include <RobotAPI/libraries/aron/data/AronDataNavigator.h> - - -namespace armarx -{ - namespace armem - { - - class ArMemWorkingMemoryBase; - typedef std::shared_ptr<ArMemWorkingMemoryBase> ArMemWorkingMemoryBasePtr; - - struct ArMemEntry; - typedef std::shared_ptr<ArMemEntry> ArMemEntryPtr; - - struct ArMemEntry - { - std::string producer; - std::string datatype; - long produceTimestampMs; - long storageTimestampMs; - armarx::aron::data::AronDataNavigatorPtr value; - }; - - class ArMemWorkingMemoryBase - { - typedef std::vector<armem::ArMemEntryPtr> SingleDatatypeStorage; // make map to access via timestamp? - typedef std::unordered_map<std::string, SingleDatatypeStorage> ProducerDatatypeStorage; - typedef std::unordered_map<std::string, ProducerDatatypeStorage> TotalDataTypeStorage; - - public: - ArMemWorkingMemoryBase(); - - void store(const std::string&, const std::string&, long, const aron::data::AronDataNavigatorPtr&); - - - private: - TotalDataTypeStorage storage; - long maximumEntriesPerDatatype; - long maximumEntriesPerProducer; - }; - - } -} diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt index 5de144492fd19df6489a4b3e01f150fc8770fdc9..121a15c6ef5cb56d312fa9d7871212fa6e2db9a8 100644 --- a/source/RobotAPI/libraries/armem/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem/CMakeLists.txt @@ -3,38 +3,17 @@ set(LIB_NAME armem) armarx_component_set_name("${LIB_NAME}") armarx_set_target("Library: ${LIB_NAME}") -find_package(Eigen3 QUIET) -armarx_build_if(Eigen3_FOUND "Eigen3 not available") -if(Eigen3_FOUND) - include_directories(${Eigen3_INCLUDE_DIR}) -endif() - -find_package(Simox QUIET) -armarx_build_if(Simox_FOUND "Simox not available") -if(Simox_FOUND) - include_directories(${Simox_INCLUDE_DIR}) -endif() - -find_package(OpenCV QUIET) -armarx_build_if(OpenCV_FOUND "OpenCV not available") -if(OpenCV_FOUND) - include_directories(${OpenCV_INCLUDE_DIRS}) -endif() - set(LIBS ArmarXCoreInterfaces ArmarXCore - RobotAPIInterfaces - ${OpenCV_LIBS} - ${Simox_LIBS} ) set(LIB_FILES - ./ArMemWorkingMemoryBase.cpp + ./ArMemBase.cpp ) set(LIB_HEADERS - ./ArMemWorkingMemoryBase.h + ./ArMemBase.h ) armarx_add_library("${LIB_NAME}" "${LIB_FILES}" "${LIB_HEADERS}" "${LIBS}")