diff --git a/ecal/core/src/ecal_descgate.cpp b/ecal/core/src/ecal_descgate.cpp index ea80fd0d45..40d69e855e 100644 --- a/ecal/core/src/ecal_descgate.cpp +++ b/ecal/core/src/ecal_descgate.cpp @@ -1,6 +1,6 @@ /* ========================= eCAL LICENSE ================================= * - * Copyright (C) 2016 - 2019 Continental Corporation + * Copyright (C) 2016 - 2024 Continental Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,7 +77,7 @@ namespace eCAL Util::QualityTopicInfoMultiMap multi_map; const std::lock_guard lock(topic_info_map_.mtx); - topic_info_map_.map.remove_deprecated(); + topic_info_map_.map.erase_expired(); for (const auto& topic_map_it : topic_info_map_.map) { @@ -92,7 +92,7 @@ namespace eCAL Util::QualityServiceInfoMultimap multi_map; const std::lock_guard lock(service_method_info_map_.mtx); - service_method_info_map_.map.remove_deprecated(); + service_method_info_map_.map.erase_expired(); for (const auto& service_method_info_map_it : service_method_info_map_.map) { @@ -183,14 +183,14 @@ namespace eCAL topic_quality_info.quality = topic_quality_; const std::unique_lock lock(topic_info_map_.mtx); - topic_info_map_.map.remove_deprecated(); + topic_info_map_.map.erase_expired(); topic_info_map_.map[topic_info_key] = topic_quality_info; } void CDescGate::RemTopicDescription(SQualityTopicIdMap& topic_info_map_, const std::string& topic_name_, const Util::TopicId& topic_id_) { const std::unique_lock lock(topic_info_map_.mtx); - topic_info_map_.map.remove_deprecated(); + topic_info_map_.map.erase_expired(); topic_info_map_.map.erase(STopicIdKey{ topic_name_, topic_id_ }); } @@ -213,7 +213,7 @@ namespace eCAL service_quality_info.response_quality = response_type_quality_; const std::lock_guard lock(service_method_info_map_.mtx); - service_method_info_map_.map.remove_deprecated(); + service_method_info_map_.map.erase_expired(); service_method_info_map_.map[service_method_info_key] = service_quality_info; } @@ -222,7 +222,7 @@ namespace eCAL std::list service_method_infos_to_remove; const std::lock_guard lock(service_method_info_map_.mtx); - service_method_info_map_.map.remove_deprecated(); + service_method_info_map_.map.erase_expired(); for (auto&& service_it : service_method_info_map_.map) { diff --git a/ecal/core/src/ecal_descgate.h b/ecal/core/src/ecal_descgate.h index c91b854be3..fbc1065324 100644 --- a/ecal/core/src/ecal_descgate.h +++ b/ecal/core/src/ecal_descgate.h @@ -1,6 +1,6 @@ /* ========================= eCAL LICENSE ================================= * - * Copyright (C) 2016 - 2019 Continental Corporation + * Copyright (C) 2016 - 2024 Continental Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -89,7 +89,7 @@ namespace eCAL CDescGate& operator=(CDescGate&&) = delete; protected: - using QualityTopicIdExpMap = eCAL::Util::CExpMap; + using QualityTopicIdExpMap = eCAL::Util::CExpirationMap; struct SQualityTopicIdMap { explicit SQualityTopicIdMap(const std::chrono::milliseconds& timeout_) : map(timeout_) {}; @@ -97,7 +97,7 @@ namespace eCAL QualityTopicIdExpMap map; }; - using QualityServiceIdExpMap = eCAL::Util::CExpMap; + using QualityServiceIdExpMap = eCAL::Util::CExpirationMap; struct SQualityServiceIdMap { explicit SQualityServiceIdMap(const std::chrono::milliseconds& timeout_) : map(timeout_) {}; diff --git a/ecal/core/src/monitoring/ecal_monitoring_impl.cpp b/ecal/core/src/monitoring/ecal_monitoring_impl.cpp index 73fac8cc29..59595dff16 100644 --- a/ecal/core/src/monitoring/ecal_monitoring_impl.cpp +++ b/ecal/core/src/monitoring/ecal_monitoring_impl.cpp @@ -1,6 +1,6 @@ /* ========================= eCAL LICENSE ================================= * - * Copyright (C) 2016 - 2019 Continental Corporation + * Copyright (C) 2016 - 2024 Continental Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -619,7 +619,7 @@ namespace eCAL monitoring_.processes.reserve(m_process_map.map->size()); // iterate map - m_process_map.map->remove_deprecated(); + m_process_map.map->erase_expired(); for (const auto& process : (*m_process_map.map)) { monitoring_.processes.emplace_back(process.second); @@ -637,7 +637,7 @@ namespace eCAL monitoring_.publisher.reserve(m_publisher_map.map->size()); // iterate map - m_publisher_map.map->remove_deprecated(); + m_publisher_map.map->erase_expired(); for (const auto& publisher : (*m_publisher_map.map)) { monitoring_.publisher.emplace_back(publisher.second); @@ -655,7 +655,7 @@ namespace eCAL monitoring_.subscriber.reserve(m_subscriber_map.map->size()); // iterate map - m_subscriber_map.map->remove_deprecated(); + m_subscriber_map.map->erase_expired(); for (const auto& subscriber : (*m_subscriber_map.map)) { monitoring_.subscriber.emplace_back(subscriber.second); @@ -673,7 +673,7 @@ namespace eCAL monitoring_.server.reserve(m_server_map.map->size()); // iterate map - m_server_map.map->remove_deprecated(); + m_server_map.map->erase_expired(); for (const auto& server : (*m_server_map.map)) { monitoring_.server.emplace_back(server.second); @@ -691,7 +691,7 @@ namespace eCAL monitoring_.clients.reserve(m_clients_map.map->size()); // iterate map - m_clients_map.map->remove_deprecated(); + m_clients_map.map->erase_expired(); for (const auto& client : (*m_clients_map.map)) { monitoring_.clients.emplace_back(client.second); @@ -705,7 +705,7 @@ namespace eCAL const std::lock_guard lock(m_process_map.sync); // iterate map - m_process_map.map->remove_deprecated(); + m_process_map.map->erase_expired(); for (const auto& process : (*m_process_map.map)) { // add process @@ -719,7 +719,7 @@ namespace eCAL const std::lock_guard lock(m_server_map.sync); // iterate map - m_server_map.map->remove_deprecated(); + m_server_map.map->erase_expired(); for (const auto& server : (*m_server_map.map)) { // add service @@ -733,7 +733,7 @@ namespace eCAL const std::lock_guard lock(m_clients_map.sync); // iterate map - m_clients_map.map->remove_deprecated(); + m_clients_map.map->erase_expired(); for (const auto& client : (*m_clients_map.map)) { // add client @@ -747,7 +747,7 @@ namespace eCAL const std::lock_guard lock(map_.sync); // iterate map - map_.map->remove_deprecated(); + map_.map->erase_expired(); for (const auto& topic : (*map_.map)) { if (direction_ == "publisher") diff --git a/ecal/core/src/monitoring/ecal_monitoring_impl.h b/ecal/core/src/monitoring/ecal_monitoring_impl.h index bfce029004..703bda8594 100644 --- a/ecal/core/src/monitoring/ecal_monitoring_impl.h +++ b/ecal/core/src/monitoring/ecal_monitoring_impl.h @@ -1,6 +1,6 @@ /* ========================= eCAL LICENSE ================================= * - * Copyright (C) 2016 - 2019 Continental Corporation + * Copyright (C) 2016 - 2024 Continental Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,7 +81,7 @@ namespace eCAL bool RegisterTopic(const Registration::Sample& sample_, enum ePubSub pubsub_type_); bool UnregisterTopic(const Registration::Sample& sample_, enum ePubSub pubsub_type_); - using TopicMonMapT = Util::CExpMap; + using TopicMonMapT = Util::CExpirationMap; struct STopicMonMap { explicit STopicMonMap(const std::chrono::milliseconds& timeout_) : @@ -92,7 +92,7 @@ namespace eCAL std::unique_ptr map; }; - using ProcessMonMapT = Util::CExpMap; + using ProcessMonMapT = Util::CExpirationMap; struct SProcessMonMap { explicit SProcessMonMap(const std::chrono::milliseconds& timeout_) : @@ -103,7 +103,7 @@ namespace eCAL std::unique_ptr map; }; - using ServerMonMapT = Util::CExpMap; + using ServerMonMapT = Util::CExpirationMap; struct SServerMonMap { explicit SServerMonMap(const std::chrono::milliseconds& timeout_) : @@ -114,7 +114,7 @@ namespace eCAL std::unique_ptr map; }; - using ClientMonMapT = Util::CExpMap; + using ClientMonMapT = Util::CExpirationMap; struct SClientMonMap { explicit SClientMonMap(const std::chrono::milliseconds& timeout_) : diff --git a/ecal/core/src/readwrite/ecal_reader.cpp b/ecal/core/src/readwrite/ecal_reader.cpp index 9fedd736f9..160071e563 100644 --- a/ecal/core/src/readwrite/ecal_reader.cpp +++ b/ecal/core/src/readwrite/ecal_reader.cpp @@ -1,6 +1,6 @@ /* ========================= eCAL LICENSE ================================= * - * Copyright (C) 2016 - 2019 Continental Corporation + * Copyright (C) 2016 - 2024 Continental Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -818,7 +818,7 @@ namespace eCAL // check connection timeouts { const std::lock_guard lock(m_pub_map_mtx); - m_pub_map.remove_deprecated(); + m_pub_map.erase_expired(); if (m_pub_map.empty()) { diff --git a/ecal/core/src/readwrite/ecal_reader.h b/ecal/core/src/readwrite/ecal_reader.h index 5d48a3c1f0..fbe0213e22 100644 --- a/ecal/core/src/readwrite/ecal_reader.h +++ b/ecal/core/src/readwrite/ecal_reader.h @@ -1,6 +1,6 @@ /* ========================= eCAL LICENSE ================================= * - * Copyright (C) 2016 - 2019 Continental Corporation + * Copyright (C) 2016 - 2024 Continental Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,7 +143,7 @@ namespace eCAL std::atomic m_topic_size; std::atomic m_connected; - using PublicationMapT = Util::CExpMap>; + using PublicationMapT = Util::CExpirationMap>; mutable std::mutex m_pub_map_mtx; PublicationMapT m_pub_map; diff --git a/ecal/core/src/readwrite/ecal_writer.cpp b/ecal/core/src/readwrite/ecal_writer.cpp index 6f4548e526..bc754e8faf 100644 --- a/ecal/core/src/readwrite/ecal_writer.cpp +++ b/ecal/core/src/readwrite/ecal_writer.cpp @@ -488,7 +488,7 @@ namespace eCAL // check connection timeouts { const std::lock_guard lock(m_sub_map_mtx); - m_sub_map.remove_deprecated(); + m_sub_map.erase_expired(); if (m_sub_map.empty()) { diff --git a/ecal/core/src/readwrite/ecal_writer.h b/ecal/core/src/readwrite/ecal_writer.h index bc6919c08f..d7738f8254 100644 --- a/ecal/core/src/readwrite/ecal_writer.h +++ b/ecal/core/src/readwrite/ecal_writer.h @@ -153,7 +153,7 @@ namespace eCAL std::atomic m_connected; - using SSubscriptionMapT = Util::CExpMap>; + using SSubscriptionMapT = Util::CExpirationMap>; mutable std::mutex m_sub_map_mtx; SSubscriptionMapT m_sub_map; diff --git a/ecal/core/src/service/ecal_clientgate.cpp b/ecal/core/src/service/ecal_clientgate.cpp index f3e49e33d3..47f7402f6c 100644 --- a/ecal/core/src/service/ecal_clientgate.cpp +++ b/ecal/core/src/service/ecal_clientgate.cpp @@ -1,6 +1,6 @@ /* ========================= eCAL LICENSE ================================= * - * Copyright (C) 2016 - 2019 Continental Corporation + * Copyright (C) 2016 - 2024 Continental Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -124,7 +124,7 @@ namespace eCAL m_service_register_map[service.key] = service; // remove timeouted services - m_service_register_map.remove_deprecated(); + m_service_register_map.erase_expired(); } // inform matching clients diff --git a/ecal/core/src/service/ecal_clientgate.h b/ecal/core/src/service/ecal_clientgate.h index d3a539d9cb..d3930051fe 100644 --- a/ecal/core/src/service/ecal_clientgate.h +++ b/ecal/core/src/service/ecal_clientgate.h @@ -1,6 +1,6 @@ /* ========================= eCAL LICENSE ================================= * - * Copyright (C) 2016 - 2019 Continental Corporation + * Copyright (C) 2016 - 2024 Continental Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,7 +64,7 @@ namespace eCAL std::shared_timed_mutex m_client_set_sync; ServiceNameServiceImplSetT m_client_set; - using ConnectedMapT = Util::CExpMap; + using ConnectedMapT = Util::CExpirationMap; std::shared_timed_mutex m_service_register_map_sync; ConnectedMapT m_service_register_map; }; diff --git a/ecal/core/src/util/ecal_expmap.h b/ecal/core/src/util/ecal_expmap.h index 9d41864ad3..fd71dcfca1 100644 --- a/ecal/core/src/util/ecal_expmap.h +++ b/ecal/core/src/util/ecal_expmap.h @@ -37,22 +37,35 @@ namespace eCAL namespace Util { /** - * @brief A time expiration map - **/ + * @brief A map that stores key-value pairs and the time at which they have last been updated. + * + * @tparam Key The type of the keys. + * @tparam T The type of the values. + * @tparam ClockType The type of the clock based on which the Map expires its elements + * + * This class is *not* threadsafe and needs to be protected by locks / mutexes in multithreaded environments. + * + * From the outside / for the user, this class acts as a regular std::map. + * However, it provides one additional function (erase_expired) that removes expired elements from this map. + * Elements are considered to be expired, if they have not been accessed (via `operator[]`) within a given timeout period. + * + * Internally, this is realized by storing both a map and a list. + * The map stores the regular key, and then the actual value and additional an iterator into the timestamp list. + * The timestamp list stores together a timestamp and the key which was inserted into the list at that given timestamp. + * It is always kept in a sorted order. + * + * Whenever a map element is accessed, the responding timestamp is updated and moved to the end of the list. + * This happens in constant time. + */ template, class Alloc = std::allocator > > - class CExpMap + class CExpirationMap { public: - // Key access history, most recent at back - using key_tracker_type = std::list>; - - // Key to value and key history iterator - using key_to_value_type = std::map>; - + // Type declarations necessary to be compliant to a regular map. using allocator_type = Alloc; using value_type = std::pair; using reference = typename Alloc::reference; @@ -60,6 +73,27 @@ namespace eCAL using key_type = Key; using mapped_type = T; + private: + struct AccessTimestampListEntry + { + typename ClockType::time_point timestamp; + Key corresponding_map_key; + }; + + // Key access history, most recent at back + using AccessTimestampListType = std::list; + + struct InternalMapEntry + { + T map_value; + typename AccessTimestampListType::iterator timestamp_list_iterator; + }; + + // Key to value and key history iterator + using InternalMapType = std::map; + + public: + class iterator { friend class const_iterator; @@ -71,7 +105,7 @@ namespace eCAL using pointer = std::pair*; using reference = std::pair&; - explicit iterator(const typename key_to_value_type::iterator _it) + explicit iterator(const typename InternalMapType::iterator _it) : it(_it) {} @@ -89,7 +123,7 @@ namespace eCAL std::pair operator*() const { - return std::make_pair(it->first, it->second.first); + return std::make_pair(it->first, it->second.map_value); } //friend void swap(iterator& lhs, iterator& rhs); //C++11 I think @@ -97,7 +131,7 @@ namespace eCAL bool operator!=(const iterator& rhs) const { return it != rhs.it; } private: - typename key_to_value_type::iterator it; + typename InternalMapType::iterator it; }; class const_iterator @@ -113,7 +147,7 @@ namespace eCAL : it(other.it) {} - explicit const_iterator(const typename key_to_value_type::const_iterator _it) + explicit const_iterator(const typename InternalMapType::const_iterator _it) : it(_it) {} @@ -132,7 +166,7 @@ namespace eCAL std::pair operator*() const { - return std::make_pair(it->first, it->second.first); + return std::make_pair(it->first, it->second.map_value); } //friend void swap(iterator& lhs, iterator& rhs); //C++11 I think @@ -140,74 +174,79 @@ namespace eCAL bool operator!=(const const_iterator& rhs) const { return it != rhs.it; } private: - typename key_to_value_type::const_iterator it; + typename InternalMapType::const_iterator it; }; // Constructor specifies the timeout of the map - CExpMap() : _timeout(std::chrono::milliseconds(5000)) {}; - explicit CExpMap(typename clock_type::duration t) : _timeout(t) {}; + CExpirationMap() : _timeout(std::chrono::milliseconds(5000)) {}; + explicit CExpirationMap(typename ClockType::duration t) : _timeout(t) {}; /** * @brief set expiration time **/ - void set_expiration(typename clock_type::duration t) { _timeout = t; }; + void set_expiration(typename ClockType::duration t) { _timeout = t; }; // Iterators: iterator begin() noexcept { - return iterator(_key_to_value.begin()); + return iterator(_internal_map.begin()); } iterator end() noexcept { - return iterator(_key_to_value.end()); + return iterator(_internal_map.end()); } const_iterator begin() const noexcept { - return const_iterator(_key_to_value.begin()); + return const_iterator(_internal_map.begin()); } const_iterator end() const noexcept { - return const_iterator(_key_to_value.end()); + return const_iterator(_internal_map.end()); } // Const begin and end functions const_iterator cbegin() const noexcept { - return const_iterator(_key_to_value.cbegin()); + return const_iterator(_internal_map.cbegin()); } const_iterator cend() const noexcept { - return const_iterator(_key_to_value.cend()); + return const_iterator(_internal_map.cend()); } // Capacity bool empty() const noexcept { - return _key_to_value.empty(); + return _internal_map.empty(); } size_type size() const noexcept { - return _key_to_value.size(); + return _internal_map.size(); } size_type max_size() const noexcept { - return _key_to_value.max_size(); + return _internal_map.max_size(); } - // Element access - // Obtain value of the cached function for k + /** + * @brief Accesses the value associated with the given key, resetting its expiration time. + * + * @param key The key to access the value for. + * + * @return The value associated with the key. + */ T& operator[](const Key& k) { // Attempt to find existing record - typename key_to_value_type::iterator it - = _key_to_value.find(k); + typename InternalMapType::iterator it + = _internal_map.find(k); - if (it == _key_to_value.end()) + if (it == _internal_map.end()) { // We don't have it: // Evaluate function and create new record @@ -224,17 +263,17 @@ namespace eCAL } // Return the retrieved value - return (*it).second.first; + return (*it).second.map_value; }; mapped_type& at(const key_type& k) { - return _key_to_value.at(k).first; + return _internal_map.at(k).first; } const mapped_type& at(const key_type& k) const { - return _key_to_value.at(k).first; + return _internal_map.at(k).first; } // Modifiers @@ -247,39 +286,42 @@ namespace eCAL // Operations iterator find(const key_type& k) { - return iterator(_key_to_value.find(k)); + return iterator(_internal_map.find(k)); } const_iterator find(const Key& k) const { - return const_iterator(_key_to_value.find(k)); + return const_iterator(_internal_map.find(k)); } - // Purge the timed out elements from the cache - void remove_deprecated(std::list* key_erased = nullptr) //-V826 + /** + * @brief Erase all expired key-value pairs from the map. + * + * This function erases all expired key-value pairs from the internal map / timestamp list. + * The CExpirationMap class does not call this function internally, it has to be called explicitly by the user. + */ + void erase_expired(std::list* keys_erased_from_expired_map = nullptr) //-V826 { - // Assert method is never called when cache is empty - //assert(!_key_tracker.empty()); - typename clock_type::time_point eviction_limit = get_curr_time() - _timeout; - - auto it(_key_tracker.begin()); - - while (it != _key_tracker.end() && it->first < eviction_limit) + // To erase timestamps from the map, the time point of the last access is calculated, all older entries will be erased. + // Since the list is sorted, we need to remove everything from the first element until the eviction limit. + typename ClockType::time_point eviction_limit = get_curr_time() - _timeout; + auto it(_access_timestamps_list.begin()); + while (it != _access_timestamps_list.end() && it->timestamp < eviction_limit) { - if (key_erased != nullptr) key_erased->push_back(it->second); - _key_to_value.erase(it->second); // erase the element from the map - it = _key_tracker.erase(it); // erase the element from the list + if (keys_erased_from_expired_map != nullptr) keys_erased_from_expired_map->push_back(it->corresponding_map_key); + _internal_map.erase(it->corresponding_map_key); // erase the element from the map + it = _access_timestamps_list.erase(it); // erase the element from the list } } // Remove specific element from the cache bool erase(const Key& k) { - auto it = _key_to_value.find(k); - if (it != _key_to_value.end()) + auto it = _internal_map.find(k); + if (it != _internal_map.end()) { - _key_tracker.erase(it->second.second); // erase the element from the list - _key_to_value.erase(k); // erase the element from the map + _access_timestamps_list.erase(it->second.timestamp_list_iterator); // erase the element from the list + _internal_map.erase(k); // erase the element from the map return true; } return false; @@ -288,8 +330,8 @@ namespace eCAL // Remove all elements from the cache void clear() { - _key_to_value.clear(); // erase all elements from the map - _key_tracker.clear(); // erase all elements from the list + _internal_map.clear(); // erase all elements from the map + _access_timestamps_list.clear(); // erase all elements from the list } private: @@ -297,49 +339,49 @@ namespace eCAL // Maybe pass the iterator instead of the key? or at least only get k once void update_timestamp(const Key& k) { - auto it_in_map = _key_to_value.find(k); - if (it_in_map != _key_to_value.end()) + auto it_in_map = _internal_map.find(k); + if (it_in_map != _internal_map.end()) { - auto& it_in_list = it_in_map->second.second; + auto& it_in_list = it_in_map->second.timestamp_list_iterator; // move the element to the end of the list - _key_tracker.splice(_key_tracker.end(), _key_tracker, it_in_list); + _access_timestamps_list.splice(_access_timestamps_list.end(), _access_timestamps_list, it_in_list); // update the timestamp - it_in_list->first = get_curr_time(); + it_in_list->timestamp = get_curr_time(); } } - // Record a fresh key-value pair in the cache - std::pair insert(const Key& k, const T& v) + // Record a fresh key-value pair in the cache + std::pair insert(const Key& k, const T& v) { // sorted list, containing (pair ( timestamp, K)) - auto it = _key_tracker.emplace(_key_tracker.end(), std::make_pair(get_curr_time(), k)); + auto it = _access_timestamps_list.emplace(_access_timestamps_list.end(), AccessTimestampListEntry{ get_curr_time(), k }); // entry mapping k -> pair (T, iterator(pair(timestamp, K))) - auto ret = _key_to_value.emplace( + auto ret = _internal_map.emplace( std::make_pair( k, - std::make_pair(v, it) + InternalMapEntry{ v, it } ) ); // return iterator to newly inserted element. return ret; } - typename clock_type::time_point get_curr_time() + typename ClockType::time_point get_curr_time() { - return clock_type::now(); + return ClockType::now(); } // Key access history - key_tracker_type _key_tracker; + AccessTimestampListType _access_timestamps_list; // Key-to-value lookup - key_to_value_type _key_to_value; + InternalMapType _internal_map; // Timeout of map - typename clock_type::duration _timeout; + typename ClockType::duration _timeout; }; } } diff --git a/ecal/tests/cpp/expmap_test/src/expmap_test.cpp b/ecal/tests/cpp/expmap_test/src/expmap_test.cpp index 8fbe3993ec..3a7f57aaef 100644 --- a/ecal/tests/cpp/expmap_test/src/expmap_test.cpp +++ b/ecal/tests/cpp/expmap_test/src/expmap_test.cpp @@ -61,7 +61,7 @@ TestingClock::duration TestingClock::current_time{ 0 }; TEST(core_cpp_core, ExpMap_SetGet) { // create the map with 2500 ms expiration - eCAL::Util::CExpMap expmap(std::chrono::milliseconds(200)); + eCAL::Util::CExpirationMap expmap(std::chrono::milliseconds(200)); // set "A" expmap["A"] = 1; @@ -81,7 +81,7 @@ TEST(core_cpp_core, ExpMap_SetGet) // check size //content = expmap.clone(); - expmap.remove_deprecated(); + expmap.erase_expired(); EXPECT_EQ(1, expmap.size()); // sleep @@ -89,7 +89,7 @@ TEST(core_cpp_core, ExpMap_SetGet) // check size //content = expmap.clone(); - expmap.remove_deprecated(); + expmap.erase_expired(); EXPECT_EQ(1, expmap.size()); // sleep @@ -97,29 +97,36 @@ TEST(core_cpp_core, ExpMap_SetGet) // check size //content = expmap.clone(); - expmap.remove_deprecated(); + expmap.erase_expired(); EXPECT_EQ(0, expmap.size()); expmap["A"] = 1; TestingClock::increment_time(std::chrono::milliseconds(150)); expmap["B"] = 2; expmap["C"] = 3; - expmap.remove_deprecated(); + expmap.erase_expired(); EXPECT_EQ(3, expmap.size()); TestingClock::increment_time(std::chrono::milliseconds(150)); expmap["B"] = 4; - expmap.remove_deprecated(); + expmap.erase_expired(); EXPECT_EQ(2, expmap.size()); TestingClock::increment_time(std::chrono::milliseconds(150)); - expmap.remove_deprecated(); + expmap.erase_expired(); EXPECT_EQ(1, expmap.size()); // sleep TestingClock::increment_time(std::chrono::milliseconds(150)); } +TEST(core_cpp_core, ExpMap_EraseEmptyMap) +{ + eCAL::Util::CExpirationMap expmap(std::chrono::milliseconds(200)); + expmap.erase_expired(); + EXPECT_TRUE(expmap.empty()); +} + TEST(core_cpp_core, ExpMap_Insert) { - eCAL::Util::CExpMap expmap(std::chrono::milliseconds(200)); + eCAL::Util::CExpirationMap expmap(std::chrono::milliseconds(200)); auto ret = expmap.insert(std::make_pair("A", 1)); auto key = (*ret.first).first; @@ -132,14 +139,14 @@ TEST(core_cpp_core, ExpMap_Insert) EXPECT_EQ(i, 1); TestingClock::increment_time(std::chrono::milliseconds(300)); - expmap.remove_deprecated(); + expmap.erase_expired(); EXPECT_EQ(0, expmap.size()); } // This tests uses find to find an element TEST(core_cpp_core, ExpMap_Find) { - eCAL::Util::CExpMap expmap(std::chrono::milliseconds(200)); + eCAL::Util::CExpirationMap expmap(std::chrono::milliseconds(200)); auto it = expmap.find("A"); EXPECT_EQ(expmap.end(), it); @@ -151,14 +158,14 @@ TEST(core_cpp_core, ExpMap_Find) EXPECT_EQ(i, 1); TestingClock::increment_time(std::chrono::milliseconds(300)); - expmap.remove_deprecated(); + expmap.erase_expired(); EXPECT_EQ(0, expmap.size()); } -// This test assures that find can be called on a const CExpMap and returns an CExpMap::const_iterator +// This test assures that find can be called on a const CExpirationMap and returns an CExpirationMap::const_iterator TEST(core_cpp_core, ExpMap_FindConst) { - eCAL::Util::CExpMap expmap(std::chrono::milliseconds(200)); + eCAL::Util::CExpirationMap expmap(std::chrono::milliseconds(200)); auto it = expmap.find("A"); EXPECT_EQ(expmap.end(), it); @@ -168,19 +175,19 @@ TEST(core_cpp_core, ExpMap_FindConst) const auto& const_ref_exmap = expmap; auto const_it = const_ref_exmap.find("A"); // assert that we are actually getting a const_iterator here! - static_assert(std::is_same::const_iterator>::value, "We're not being returned a const_iterator from find."); + static_assert(std::is_same::const_iterator>::value, "We're not being returned a const_iterator from find."); int i = (*const_it).second; EXPECT_EQ(i, 1); TestingClock::increment_time(std::chrono::milliseconds(300)); - expmap.remove_deprecated(); + expmap.erase_expired(); EXPECT_EQ(0, expmap.size()); } TEST(core_cpp_core, ExpMap_Iterate) { // create the map with 2500 ms expiration - eCAL::Util::CExpMap expmap(std::chrono::milliseconds(200)); + eCAL::Util::CExpirationMap expmap(std::chrono::milliseconds(200)); expmap["A"] = 1; std::string key; @@ -196,7 +203,7 @@ TEST(core_cpp_core, ExpMap_Iterate) EXPECT_EQ(1, value); } -void ConstRefIterate(const eCAL::Util::CExpMap& map) +void ConstRefIterate(const eCAL::Util::CExpirationMap& map) { std::string key; int value; @@ -214,7 +221,7 @@ void ConstRefIterate(const eCAL::Util::CExpMap& TEST(core_cpp_core, ExpMap_ConstExpMapIterate) { // create the map with 2500 ms expiration - eCAL::Util::CExpMap expmap(std::chrono::milliseconds(200)); + eCAL::Util::CExpirationMap expmap(std::chrono::milliseconds(200)); expmap["A"] = 1; ConstRefIterate(expmap); @@ -222,7 +229,7 @@ TEST(core_cpp_core, ExpMap_ConstExpMapIterate) TEST(core_cpp_core, ExpMap_Empty) { - eCAL::Util::CExpMap expmap(std::chrono::milliseconds(200)); + eCAL::Util::CExpirationMap expmap(std::chrono::milliseconds(200)); EXPECT_EQ(true, expmap.empty()); expmap["A"] = 1; EXPECT_EQ(false, expmap.empty()); @@ -230,7 +237,7 @@ TEST(core_cpp_core, ExpMap_Empty) TEST(core_cpp_core, ExpMap_Size) { - eCAL::Util::CExpMap expmap(std::chrono::milliseconds(200)); + eCAL::Util::CExpirationMap expmap(std::chrono::milliseconds(200)); EXPECT_EQ(0, expmap.size()); expmap["A"] = 1; EXPECT_EQ(1, expmap.size()); @@ -238,7 +245,7 @@ TEST(core_cpp_core, ExpMap_Size) TEST(core_cpp_core, ExpMap_Remove) { - eCAL::Util::CExpMap expmap(std::chrono::milliseconds(200)); + eCAL::Util::CExpirationMap expmap(std::chrono::milliseconds(200)); expmap["A"] = 1; EXPECT_EQ(1, expmap.size()); EXPECT_TRUE(expmap.erase("A"));