diff --git a/ecal/core/include/ecal/ecal_util.h b/ecal/core/include/ecal/ecal_util.h index c3284d0bdc..c580dd7a58 100644 --- a/ecal/core/include/ecal/ecal_util.h +++ b/ecal/core/include/ecal/ecal_util.h @@ -27,7 +27,9 @@ #include #include +#include #include +#include namespace eCAL { @@ -148,7 +150,14 @@ namespace eCAL * @param topic_info_map_ Map to store the topic informations. * Map containing { TopicName -> (Type, Description) } mapping of all topics that are currently known. **/ - ECAL_API void GetTopics(std::map& topic_info_map_); + ECAL_API void GetTopics(std::unordered_map& topic_info_map_); + + /** + * @brief Get all topic names. + * + * @param topic_names_ Vector to store the topic names. + **/ + ECAL_API void GetTopicNames(std::vector& topic_names_); /** * @brief Gets type name of the specified topic. @@ -203,6 +212,13 @@ namespace eCAL **/ ECAL_API void GetServices(std::map, Util::SServiceMethodInfo>& service_info_map_); + /** + * @brief Get all service/method names. + * + * @param service_method_names_ Vector to store the service/method tuples (Vector { (ServiceName, MethodName) }). + **/ + ECAL_API void GetServiceNames(std::vector>& service_method_names_); + /** * @brief Gets service method request and response type names. * diff --git a/ecal/core/src/ecal_descgate.cpp b/ecal/core/src/ecal_descgate.cpp index aa7c914586..056d928e9e 100644 --- a/ecal/core/src/ecal_descgate.cpp +++ b/ecal/core/src/ecal_descgate.cpp @@ -22,6 +22,8 @@ **/ #include +#include + #include "ecal_descgate.h" #include #include @@ -29,7 +31,11 @@ namespace eCAL { - CDescGate::CDescGate() = default; + CDescGate::CDescGate() : + m_topic_info_map (std::chrono::milliseconds(Config::GetMonitoringTimeoutMs())), + m_service_info_map(std::chrono::milliseconds(Config::GetMonitoringTimeoutMs())) + { + } CDescGate::~CDescGate() = default; void CDescGate::Create() @@ -42,30 +48,33 @@ namespace eCAL void CDescGate::ApplyTopicDescription(const std::string& topic_name_, const std::string& topic_type_, const std::string& topic_desc_, const QualityFlags description_quality_) { - std::unique_lock lock(m_topic_info_map_mutex); - const auto topic_info_it = m_topic_info_map.find(topic_name_); + std::unique_lock lock(m_topic_info_map.sync); + m_topic_info_map.map->remove_deprecated(); + + const auto topic_info_it = m_topic_info_map.map->find(topic_name_); // new element (no need to check anything, just add it) - if(topic_info_it == m_topic_info_map.end()) + if(topic_info_it == m_topic_info_map.map->end()) { // TODO: Maybe we should copy the description from another topic with the same type, if it is empty? - STopicInfoQuality topic_info; + STopicInfoQuality& topic_info = (*m_topic_info_map.map)[topic_name_]; topic_info.info.type_name = topic_type_; topic_info.info.type_description = topic_desc_; topic_info.description_quality = description_quality_; - m_topic_info_map.emplace(topic_name_, std::move(topic_info)); } else { // existing type for the same topic name should be equal !! // we log the error only one time - if( !topic_info_it->second.type_missmatch_logged + STopicInfoQuality& topic_info = (*m_topic_info_map.map)[topic_name_]; + + if( !topic_info.type_missmatch_logged && !topic_type_.empty() - && !topic_info_it->second.info.type_name.empty() - && (topic_info_it->second.info.type_name != topic_type_) + && !topic_info.info.type_name.empty() + && (topic_info.info.type_name != topic_type_) ) { - std::string ttype1 = topic_info_it->second.info.type_name; + std::string ttype1 = topic_info.info.type_name; std::string ttype2 = topic_type_; std::replace(ttype1.begin(), ttype1.end(), '\0', '?'); std::replace(ttype1.begin(), ttype1.end(), '\t', '?'); @@ -80,42 +89,61 @@ namespace eCAL msg += "\')"; eCAL::Logging::Log(log_level_warning, msg); - topic_info_it->second.type_missmatch_logged = true; + topic_info.type_missmatch_logged = true; } // existing description for the same topic name should be equal !! // we log the warning only one time - if ( !topic_info_it->second.type_missmatch_logged + if( !topic_info.type_missmatch_logged && !topic_desc_.empty() - && !topic_info_it->second.info.type_description.empty() - && (topic_info_it->second.info.type_description != topic_desc_) + && !topic_info.info.type_description.empty() + && (topic_info.info.type_description != topic_desc_) ) { std::string msg = "eCAL Pub/Sub description mismatch for topic "; msg += topic_name_; eCAL::Logging::Log(log_level_warning, msg); - topic_info_it->second.type_missmatch_logged = true; + topic_info.type_missmatch_logged = true; } // Now let's check whether the current information has a higher quality. // If it has a higher quality, we overwrite it. - if (description_quality_ > topic_info_it->second.description_quality) + if (description_quality_ > topic_info.description_quality) { - topic_info_it->second.info.type_name = topic_type_; - topic_info_it->second.info.type_description = topic_desc_; - topic_info_it->second.description_quality = description_quality_; + topic_info.info.type_name = topic_type_; + topic_info.info.type_description = topic_desc_; + topic_info.description_quality = description_quality_; } } } - void CDescGate::GetTopics(std::map& topic_info_map_) + void CDescGate::GetTopics(std::unordered_map& topic_info_map_) { - topic_info_map_.clear(); - std::shared_lock lock(m_topic_info_map_mutex); - for (auto& topic_info : m_topic_info_map) + std::unordered_map map; + + std::shared_lock lock(m_topic_info_map.sync); + m_topic_info_map.map->remove_deprecated(); + map.reserve(m_topic_info_map.map->size()); + + for (const auto& topic_info : (*m_topic_info_map.map)) { - topic_info_map_[topic_info.first] = topic_info.second.info; + map.emplace(topic_info.first, topic_info.second.info); + } + topic_info_map_.swap(map); + } + + void CDescGate::GetTopicNames(std::vector& topic_names_) + { + topic_names_.clear(); + + std::shared_lock lock(m_topic_info_map.sync); + m_topic_info_map.map->remove_deprecated(); + topic_names_.reserve(m_topic_info_map.map->size()); + + for (const auto& topic_info : (*m_topic_info_map.map)) + { + topic_names_.emplace_back(topic_info.first); } } @@ -123,23 +151,23 @@ namespace eCAL { if(topic_name_.empty()) return(false); - std::shared_lock lock(m_topic_info_map_mutex); - const auto topic_info_it = m_topic_info_map.find(topic_name_); + std::shared_lock lock(m_topic_info_map.sync); + const auto topic_info_it = m_topic_info_map.map->find(topic_name_); - if(topic_info_it == m_topic_info_map.end()) return(false); - topic_type_ = topic_info_it->second.info.type_name; + if(topic_info_it == m_topic_info_map.map->end()) return(false); + topic_type_ = (*topic_info_it).second.info.type_name; return(true); } bool CDescGate::GetTopicDescription(const std::string& topic_name_, std::string& topic_desc_) { - if(topic_name_.empty()) return(false); + if (topic_name_.empty()) return(false); - std::shared_lock lock(m_topic_info_map_mutex); - const auto topic_info_it = m_topic_info_map.find(topic_name_); + std::shared_lock lock(m_topic_info_map.sync); + const auto topic_info_it = m_topic_info_map.map->find(topic_name_); - if(topic_info_it == m_topic_info_map.end()) return(false); - topic_desc_ = topic_info_it->second.info.type_description; + if (topic_info_it == m_topic_info_map.map->end()) return(false); + topic_desc_ = (*topic_info_it).second.info.type_description; return(true); } @@ -153,55 +181,72 @@ namespace eCAL { std::tuple service_method_tuple = std::make_tuple(service_name_, method_name_); - std::shared_lock lock(m_service_info_map_mutex); - auto service_info_map_it = m_service_info_map.find(service_method_tuple); - if (service_info_map_it == m_service_info_map.end()) + std::unique_lock lock(m_service_info_map.sync); + m_service_info_map.map->remove_deprecated(); + + auto service_info_map_it = m_service_info_map.map->find(service_method_tuple); + if (service_info_map_it == m_service_info_map.map->end()) { - SServiceMethodInfoQuality service_info; + SServiceMethodInfoQuality& service_info = (*m_service_info_map.map)[service_method_tuple]; service_info.info.request_type_name = req_type_name_; service_info.info.request_type_description = req_type_desc_; service_info.info.response_type_name = resp_type_name_; service_info.info.response_type_description = resp_type_desc_; service_info.info_quality = info_quality_; - - m_service_info_map[service_method_tuple] = std::move(service_info); } else { // do we need to check consistency ? - if (info_quality_ > service_info_map_it->second.info_quality) + SServiceMethodInfoQuality& service_info = (*m_service_info_map.map)[service_method_tuple]; + if (info_quality_ > service_info.info_quality) { - service_info_map_it->second.info.request_type_name = req_type_name_; - service_info_map_it->second.info.request_type_description = req_type_desc_; - service_info_map_it->second.info.response_type_name = resp_type_name_; - service_info_map_it->second.info.response_type_description = resp_type_desc_; - service_info_map_it->second.info_quality = info_quality_; + service_info.info.request_type_name = req_type_name_; + service_info.info.request_type_description = req_type_desc_; + service_info.info.response_type_name = resp_type_name_; + service_info.info.response_type_description = resp_type_desc_; + service_info.info_quality = info_quality_; } } } void CDescGate::GetServices(std::map, Util::SServiceMethodInfo>& service_info_map_) { - service_info_map_.clear(); - std::shared_lock lock(m_service_info_map_mutex); - for (auto& service_info : m_service_info_map) + std::map, Util::SServiceMethodInfo> map; + + std::shared_lock lock(m_service_info_map.sync); + m_service_info_map.map->remove_deprecated(); + + for (const auto& service_info : (*m_service_info_map.map)) { - service_info_map_[service_info.first] = service_info.second.info; + map.emplace(service_info.first, service_info.second.info); } + service_info_map_.swap(map); } - bool CDescGate::GetServiceTypeNames(const std::string& service_name_, const std::string& method_name_, std::string& req_type_name_, std::string& resp_type_name_) + void CDescGate::GetServiceNames(std::vector>& service_method_names_) { - std::tuple service_method_tuple = std::make_tuple(service_name_, method_name_); + service_method_names_.clear(); - std::shared_lock lock(m_service_info_map_mutex); - auto service_info_map_it = m_service_info_map.find(service_method_tuple); + std::shared_lock lock(m_service_info_map.sync); + m_service_info_map.map->remove_deprecated(); + service_method_names_.reserve(m_service_info_map.map->size()); - if (service_info_map_it == m_service_info_map.end()) return false; + for (const auto& service_info : (*m_service_info_map.map)) + { + service_method_names_.emplace_back(service_info.first); + } + } - req_type_name_ = service_info_map_it->second.info.request_type_name; - resp_type_name_ = service_info_map_it->second.info.response_type_name; + bool CDescGate::GetServiceTypeNames(const std::string& service_name_, const std::string& method_name_, std::string& req_type_name_, std::string& resp_type_name_) + { + std::tuple service_method_tuple = std::make_tuple(service_name_, method_name_); + std::shared_lock lock(m_service_info_map.sync); + auto service_info_map_it = m_service_info_map.map->find(service_method_tuple); + + if (service_info_map_it == m_service_info_map.map->end()) return false; + req_type_name_ = (*service_info_map_it).second.info.request_type_name; + resp_type_name_ = (*service_info_map_it).second.info.response_type_name; return true; } @@ -209,14 +254,12 @@ namespace eCAL { std::tuple service_method_tuple = std::make_tuple(service_name_, method_name_); - std::shared_lock lock(m_service_info_map_mutex); - auto service_info_map_it = m_service_info_map.find(service_method_tuple); - - if (service_info_map_it == m_service_info_map.end()) return false; - - req_type_desc_ = service_info_map_it->second.info.request_type_description; - resp_type_desc_ = service_info_map_it->second.info.response_type_description; + std::shared_lock lock(m_service_info_map.sync); + auto service_info_map_it = m_service_info_map.map->find(service_method_tuple); + if (service_info_map_it == m_service_info_map.map->end()) return false; + req_type_desc_ = (*service_info_map_it).second.info.request_type_description; + resp_type_desc_ = (*service_info_map_it).second.info.response_type_description; return true; } }; diff --git a/ecal/core/src/ecal_descgate.h b/ecal/core/src/ecal_descgate.h index 7fabcde946..bc8f135212 100644 --- a/ecal/core/src/ecal_descgate.h +++ b/ecal/core/src/ecal_descgate.h @@ -27,12 +27,15 @@ #include "ecal_global_accessors.h" #include "ecal_def.h" +#include "ecal_expmap.h" #include #include #include +#include #include #include +#include namespace eCAL @@ -64,7 +67,8 @@ namespace eCAL const std::string& topic_desc_, const QualityFlags description_quality_); - void GetTopics(std::map& topic_info_map_); + void GetTopics(std::unordered_map& topic_info_map_); + void GetTopicNames(std::vector& topic_names_); bool GetTopicTypeName(const std::string& topic_name_, std::string& topic_type_); bool GetTopicDescription(const std::string& topic_name_, std::string& topic_desc_); @@ -77,6 +81,7 @@ namespace eCAL const QualityFlags info_quality_); void GetServices(std::map, Util::SServiceMethodInfo>& service_info_map_); + void GetServiceNames(std::vector>& service_method_names_); bool GetServiceTypeNames(const std::string& service_name_, const std::string& method_name_, std::string& req_type_name_, std::string& resp_type_name_); bool GetServiceDescription(const std::string& service_name_, const std::string& method_name_, std::string& req_type_desc_, std::string& resp_type_desc_); @@ -94,16 +99,31 @@ namespace eCAL QualityFlags info_quality = QualityFlags::NO_QUALITY; //!< The Quality of the Info }; - // key: topic name | value: topic(type/desc) - using TopicInfoMap = std::map; //!< Map containing { TopicName -> (Type, Description) } mapping of all topics that are currently known - mutable std::shared_timed_mutex m_topic_info_map_mutex; //!< Mutex protecting the m_topic_info_map - TopicInfoMap m_topic_info_map; //!< Map containing information about each known topic + // key: topic name | value: topic (type/desc), quality + using TopicInfoMap = eCAL::Util::CExpMap; //!< Map containing { TopicName -> (Type, Description, Quality) } mapping of all topics that are currently known + struct STopicInfoMap + { + explicit STopicInfoMap(const std::chrono::milliseconds& timeout_) : + map(new TopicInfoMap(timeout_)) + { + }; + mutable std::shared_timed_mutex sync; //!< Mutex protecting the map + std::unique_ptr map; //!< Map containing information about each known topic + }; + STopicInfoMap m_topic_info_map; - // key: tup | value: tup - using ServiceMethodInfoMap - = std::map, SServiceMethodInfoQuality>; //!< Map { (ServiceName, MethodName) -> ( (ReqType, ReqDescription), (RespType, RespDescription) ) } mapping of all currently known services - mutable std::shared_timed_mutex m_service_info_map_mutex; //!< Mutex protecting the m_service_info_map - ServiceMethodInfoMap m_service_info_map; //!< Map containing information about each known service method + // key: tup | value: request (type/desc), response (type/desc), quality + using ServiceMethodInfoMap = eCAL::Util::CExpMap, SServiceMethodInfoQuality>; //!< Map { (ServiceName, MethodName) -> ( (ReqType, ReqDescription), (RespType, RespDescription), Quality ) } mapping of all currently known services + struct SServiceMethodInfoMap + { + explicit SServiceMethodInfoMap(const std::chrono::milliseconds& timeout_) : + map(new ServiceMethodInfoMap(timeout_)) + { + }; + mutable std::shared_timed_mutex sync; //!< Mutex protecting the map + std::unique_ptr map; //!< Map containing information about each known service + }; + SServiceMethodInfoMap m_service_info_map; }; constexpr inline CDescGate::QualityFlags operator~ (CDescGate::QualityFlags a) { return static_cast( ~static_cast::type>(a) ); } diff --git a/ecal/core/src/ecal_util.cpp b/ecal/core/src/ecal_util.cpp index 67c5549674..703bdacc11 100644 --- a/ecal/core/src/ecal_util.cpp +++ b/ecal/core/src/ecal_util.cpp @@ -229,12 +229,23 @@ namespace eCAL * @param topic_info_map_ Map to store the topic informations. * Map containing { TopicName -> (Type, Description) } mapping of all topics that are currently known. **/ - void GetTopics(std::map& topic_info_map_) + void GetTopics(std::unordered_map& topic_info_map_) { if (!g_descgate()) return; g_descgate()->GetTopics(topic_info_map_); } + /** + * @brief Get all topic names. + * + * @param topic_names_ Vector to store the topic names. + **/ + void GetTopicNames(std::vector& topic_names_) + { + if (!g_descgate()) return; + g_descgate()->GetTopicNames(topic_names_); + } + /** * @brief Gets type name of the specified topic. * @@ -333,6 +344,17 @@ namespace eCAL g_descgate()->GetServices(service_info_map_); } + /** + * @brief Get all service/method names. + * + * @param service_names_ Vector to store the service/method tuples (Vector { (ServiceName, MethodName) }). + **/ + void GetServiceNames(std::vector>& service_method_names_) + { + if (!g_descgate()) return; + g_descgate()->GetServiceNames(service_method_names_); + } + /** * @brief Gets service method request and response type names. * diff --git a/ecal/core/src/mon/ecal_monitoring_impl.cpp b/ecal/core/src/mon/ecal_monitoring_impl.cpp index e7af6042e8..b61352b2d3 100644 --- a/ecal/core/src/mon/ecal_monitoring_impl.cpp +++ b/ecal/core/src/mon/ecal_monitoring_impl.cpp @@ -544,7 +544,7 @@ namespace eCAL // iterate map m_process_map.map->remove_deprecated(); - for (auto process : (*m_process_map.map)) + for (const auto& process : (*m_process_map.map)) { // add host eCAL::pb::Process* pMonProcs = monitoring_.add_processes(); @@ -618,7 +618,7 @@ namespace eCAL // iterate map m_server_map.map->remove_deprecated(); - for (auto service : (*m_server_map.map)) + for (const auto& service : (*m_server_map.map)) { // add host eCAL::pb::Service* pMonService = monitoring_.add_services(); @@ -668,7 +668,7 @@ namespace eCAL // iterate map m_client_map.map->remove_deprecated(); - for (auto service : (*m_client_map.map)) + for (const auto& service : (*m_client_map.map)) { // add host eCAL::pb::Client* pMonClient = monitoring_.add_clients(); @@ -703,7 +703,7 @@ namespace eCAL // iterate map map_.map->remove_deprecated(); - for (auto topic : (*map_.map)) + for (const auto& topic : (*map_.map)) { // add topic eCAL::pb::Topic* pMonTopic = monitoring_.add_topics(); diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 6bb88cf20d..cfb8328992 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -64,6 +64,7 @@ add_subdirectory(cpp/misc/proto_dyn) add_subdirectory(cpp/misc/proto_dyn_json) add_subdirectory(cpp/misc/time) add_subdirectory(cpp/misc/timer) +add_subdirectory(cpp/monitoring/monitoring_get_services) add_subdirectory(cpp/monitoring/monitoring_get_topics) add_subdirectory(cpp/monitoring/monitoring_rec) add_subdirectory(cpp/monitoring/monitoring_reg) diff --git a/samples/cpp/monitoring/monitoring_get_services/CMakeLists.txt b/samples/cpp/monitoring/monitoring_get_services/CMakeLists.txt new file mode 100644 index 0000000000..9449124573 --- /dev/null +++ b/samples/cpp/monitoring/monitoring_get_services/CMakeLists.txt @@ -0,0 +1,41 @@ +# ========================= eCAL LICENSE ================================= +# +# Copyright (C) 2016 - 2019 Continental Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ========================= eCAL LICENSE ================================= + +cmake_minimum_required(VERSION 3.10) + +set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) + +project(monitoring_get_services) + +find_package(eCAL REQUIRED) + +set(monitoring_get_services_src + src/monitoring_get_services.cpp +) + +ecal_add_sample(${PROJECT_NAME} ${monitoring_get_services_src}) + +target_link_libraries(${PROJECT_NAME} eCAL::core) + +target_link_libraries(${PROJECT_NAME} eCAL::core_pb) + +target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) + +ecal_install_sample(${PROJECT_NAME}) + +set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER samples/cpp/monitoring) diff --git a/samples/cpp/monitoring/monitoring_get_services/src/monitoring_get_services.cpp b/samples/cpp/monitoring/monitoring_get_services/src/monitoring_get_services.cpp new file mode 100644 index 0000000000..3f40b7affc --- /dev/null +++ b/samples/cpp/monitoring/monitoring_get_services/src/monitoring_get_services.cpp @@ -0,0 +1,76 @@ +/* ========================= eCAL LICENSE ================================= + * + * Copyright (C) 2016 - 2019 Continental Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ========================= eCAL LICENSE ================================= +*/ + +#include + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + int run(0), runs(100000); + std::chrono::steady_clock::time_point start_time; + + // initialize eCAL core API + eCAL::Initialize(argc, argv, "monitoring get services"); + + // monitor for ever + while(eCAL::Ok()) + { + // GetServices + { + std::map, eCAL::Util::SServiceMethodInfo> service_info_map; + + start_time = std::chrono::steady_clock::now(); + for (run = 0; run < runs; ++run) + { + eCAL::Util::GetServices(service_info_map); + } + + auto num_services = service_info_map.size(); + auto diff_time = std::chrono::duration_cast(std::chrono::steady_clock::now() - start_time); + std::cout << "GetServices : " << static_cast(diff_time.count()) / runs << " ms" << " (" << num_services << " services)" << std::endl; + std::cout << std::endl; + } + + // GetServiceNames + { + std::vector> service_method_names; + + start_time = std::chrono::steady_clock::now(); + for (run = 0; run < runs; ++run) + { + eCAL::Util::GetServiceNames(service_method_names); + } + + auto num_services = service_method_names.size(); + auto diff_time = std::chrono::duration_cast(std::chrono::steady_clock::now() - start_time); + std::cout << "GetServicesNames : " << static_cast(diff_time.count()) / runs << " ms" << " (" << num_services << " services)" << std::endl; + std::cout << std::endl; + } + } + + // finalize eCAL API + eCAL::Finalize(); + + return(0); +} diff --git a/samples/cpp/monitoring/monitoring_get_topics/src/monitoring_get_topics.cpp b/samples/cpp/monitoring/monitoring_get_topics/src/monitoring_get_topics.cpp index 001272d451..fb1d28a525 100644 --- a/samples/cpp/monitoring/monitoring_get_topics/src/monitoring_get_topics.cpp +++ b/samples/cpp/monitoring/monitoring_get_topics/src/monitoring_get_topics.cpp @@ -22,6 +22,7 @@ #include #include #include +#include int main(int argc, char **argv) { @@ -34,18 +35,37 @@ int main(int argc, char **argv) // monitor for ever while(eCAL::Ok()) { - std::map topic_info_map; - - start_time = std::chrono::steady_clock::now(); - for (run = 0; run < runs; ++run) + // GetTopics { - eCAL::Util::GetTopics(topic_info_map); + std::unordered_map topic_info_map; + + start_time = std::chrono::steady_clock::now(); + for (run = 0; run < runs; ++run) + { + eCAL::Util::GetTopics(topic_info_map); + } + + auto num_topics = topic_info_map.size(); + auto diff_time = std::chrono::duration_cast(std::chrono::steady_clock::now() - start_time); + std::cout << "GetTopics : " << static_cast(diff_time.count()) / runs << " ms" << " (" << num_topics << " topics)" << std::endl; + std::cout << std::endl; } - auto num_topics = topic_info_map.size(); - auto diff_time = std::chrono::duration_cast(std::chrono::steady_clock::now() - start_time); - std::cout << "GetTopics : " << static_cast(diff_time.count()) / runs << " ms" << " (" << num_topics << " topics)" << std::endl; - std::cout << std::endl; + // GetTopicNames + { + std::vector topic_names; + + start_time = std::chrono::steady_clock::now(); + for (run = 0; run < runs; ++run) + { + eCAL::Util::GetTopicNames(topic_names); + } + + auto num_topics = topic_names.size(); + auto diff_time = std::chrono::duration_cast(std::chrono::steady_clock::now() - start_time); + std::cout << "GetTopicsNames : " << static_cast(diff_time.count()) / runs << " ms" << " (" << num_topics << " topics)" << std::endl; + std::cout << std::endl; + } } // finalize eCAL API diff --git a/testing/ecal/pubsub_test/src/pubsub_test.cpp b/testing/ecal/pubsub_test/src/pubsub_test.cpp index 84fc3757f8..fa5ce8a0f4 100644 --- a/testing/ecal/pubsub_test/src/pubsub_test.cpp +++ b/testing/ecal/pubsub_test/src/pubsub_test.cpp @@ -20,10 +20,12 @@ #include #include +#include #include #define CMN_REGISTRATION_REFRESH 1000 +#define CMN_MONITORING_TIMEOUT 5000 #define DATA_FLOW_TIME 50 #define PAYLOAD_SIZE 1024 @@ -244,36 +246,48 @@ TEST(IO, GetTopics) // initialize eCAL API eCAL::Initialize(0, nullptr, "pubsub_test"); - std::map topic_info_map; + std::unordered_map topic_info_map; - std::string ttype("type"); - std::string tdesc("desc"); + // create and check a few pub/sub entities + { + std::string ttype("type"); + std::string tdesc("desc"); - // create 3 publisher - eCAL::CPublisher pub1("A1", ttype + "A1", tdesc + "A1"); - eCAL::CPublisher pub2("A2", ttype + "A2", tdesc + "A2"); - eCAL::CPublisher pub3("A3", ttype + "A3", tdesc + "A3"); + // create 3 publisher + eCAL::CPublisher pub1("A1", ttype + "A1", tdesc + "A1"); + eCAL::CPublisher pub2("A2", ttype + "A2", tdesc + "A2"); + eCAL::CPublisher pub3("A3", ttype + "A3", tdesc + "A3"); - // create 2 subscriber - eCAL::CSubscriber sub1("B1", ttype + "B1", tdesc + "B1"); - eCAL::CSubscriber sub2("B2", ttype + "B2", tdesc + "B2"); + // create 2 subscriber + eCAL::CSubscriber sub1("B1", ttype + "B1", tdesc + "B1"); + eCAL::CSubscriber sub2("B2", ttype + "B2", tdesc + "B2"); - // let's register them - eCAL::Process::SleepMS(2 * CMN_REGISTRATION_REFRESH); + // let's register them + eCAL::Process::SleepMS(2 * CMN_REGISTRATION_REFRESH); - // get all topics - eCAL::Util::GetTopics(topic_info_map); + // get all topics + eCAL::Util::GetTopics(topic_info_map); - // check size - EXPECT_EQ(topic_info_map.size(), 5); + // check size + EXPECT_EQ(topic_info_map.size(), 5); - // check types and descriptions - for (auto& topic_info : topic_info_map) - { - EXPECT_EQ(eCAL::Util::GetTopicTypeName(topic_info.first), ttype + topic_info.first); - EXPECT_EQ(eCAL::Util::GetTopicDescription(topic_info.first), tdesc + topic_info.first); + // check types and descriptions + for (auto& topic_info : topic_info_map) + { + EXPECT_EQ(eCAL::Util::GetTopicTypeName(topic_info.first), ttype + topic_info.first); + EXPECT_EQ(eCAL::Util::GetTopicDescription(topic_info.first), tdesc + topic_info.first); + } } + // let's unregister them + eCAL::Process::SleepMS(CMN_MONITORING_TIMEOUT); + + // get all topics again + eCAL::Util::GetTopics(topic_info_map); + + // check size + EXPECT_EQ(topic_info_map.size(), 0); + // finalize eCAL API eCAL::Finalize(); }