From b9b87923e58a9e430bf306287049c4d8e5f90915 Mon Sep 17 00:00:00 2001 From: Dominik Drexler Date: Mon, 29 Apr 2024 16:40:23 +0200 Subject: [PATCH] simplified factory code by making use of pop_back --- include/loki/details/pddl/factory.hpp | 34 +++++++++---------- .../loki/details/utils/segmented_vector.hpp | 9 +++++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/include/loki/details/pddl/factory.hpp b/include/loki/details/pddl/factory.hpp index c56a79b5..cb3b25dd 100644 --- a/include/loki/details/pddl/factory.hpp +++ b/include/loki/details/pddl/factory.hpp @@ -57,32 +57,38 @@ class PDDLFactory [[nodiscard]] HolderType const* get_or_create(Args&&... args) { /* Construct and insert the element in persistent memory. */ - size_t identifier = m_count; + // Ensure that element with identifier i is stored at position i. - assert((identifier == (m_persistent_vector.size() - 1)) || (identifier == m_persistent_vector.size())); + size_t identifier = m_count; + assert(identifier == m_persistent_vector.size()); + // Explicitly call the constructor of T to give exclusive access to the factory. auto element = HolderType(std::move(SubType(identifier, std::forward(args)...))); - bool overwrite_last_element = (identifier == m_persistent_vector.size() - 1); + const auto* element_ptr = &(m_persistent_vector.push_back(std::move(element))); // The pointer to the location in persistent memory. - const auto* element_ptr = - overwrite_last_element ? &(m_persistent_vector[identifier] = std::move(element)) : &(m_persistent_vector.push_back(std::move(element))); assert(element_ptr); + /* Test for uniqueness */ auto it = m_uniqueness_set.find(element_ptr); if (it == m_uniqueness_set.end()) { - // Element is unique! + /* Element is unique! */ + m_uniqueness_set.emplace(element_ptr); // Validate the element by increasing the identifier to the next free position ++m_count; - assert(m_uniqueness_set.size() == m_count); } else { - // Element is not unique! - // Return the existing one. + /* Element is not unique! */ + element_ptr = *it; + // Remove duplicate from vector + m_persistent_vector.pop_back(); } + // Ensure that indexing matches size of uniqueness set. + assert(m_uniqueness_set.size() == m_count); + return element_ptr; } @@ -91,15 +97,7 @@ class PDDLFactory */ /// @brief Returns a pointer to an existing object with the given identifier. - [[nodiscard]] HolderType const* get(size_t identifier) const - { - if (identifier < m_persistent_vector.size()) - { - return &(m_persistent_vector[identifier]); - } - - throw std::invalid_argument("invalid identifier"); - } + [[nodiscard]] HolderType const* get(size_t identifier) const { return &(m_persistent_vector.at(identifier)); } /** * Iterators diff --git a/include/loki/details/utils/segmented_vector.hpp b/include/loki/details/utils/segmented_vector.hpp index c765d2c9..701459b5 100644 --- a/include/loki/details/utils/segmented_vector.hpp +++ b/include/loki/details/utils/segmented_vector.hpp @@ -46,6 +46,7 @@ class SegmentedVector { // Add an additional vector with capacity N m_data.resize(m_data.size() + 1); + // This reserve is important to avoid reallocations m_data.back().reserve(m_elements_per_segment); // Increase total capacity m_capacity += m_elements_per_segment; @@ -78,6 +79,14 @@ class SegmentedVector return segment.back(); } + void pop_back() + { + assert(m_size > 0); + auto& segment = m_data[segment_index(size() - 1)]; + segment.pop_back(); + --m_size; + } + /** * Accessors */