diff --git a/score/launch_manager/src/daemon/src/common/identifier_hash.cpp b/score/launch_manager/src/daemon/src/common/identifier_hash.cpp index c6d9b1482b..6484b81b0c 100644 --- a/score/launch_manager/src/daemon/src/common/identifier_hash.cpp +++ b/score/launch_manager/src/daemon/src/common/identifier_hash.cpp @@ -79,26 +79,33 @@ std::size_t Fnv1aHash(std::string_view data) noexcept } // namespace -IdentifierHash::IdentifierHash(const std::string& id) +IdentifierHash::IdentifierHash(std::string_view id) { hash_id_ = Fnv1aHash(id); const std::lock_guard lock(get_registry_mutex()); get_registry()[hash_id_] = id; } -IdentifierHash::IdentifierHash(std::string_view id) +IdentifierHash::IdentifierHash(std::size_t hash_id) { - hash_id_ = Fnv1aHash(id); - const std::lock_guard lock(get_registry_mutex()); - get_registry()[hash_id_] = id; + hash_id_ = hash_id; } -IdentifierHash::IdentifierHash(const char* id) +std::optional IdentifierHash::if_exists(std::string_view id) { - const std::string_view sv = (id != nullptr) ? std::string_view(id) : std::string_view(""); - hash_id_ = Fnv1aHash(sv); + const std::size_t hash_id = Fnv1aHash(id); + const std::lock_guard lock(get_registry_mutex()); - get_registry()[hash_id_] = sv; + const std::unordered_map& registry = get_registry(); + + if (registry.find(hash_id) == registry.end()) + { + return std::nullopt; + } + else + { + return IdentifierHash(hash_id); + } } bool IdentifierHash::operator==(const IdentifierHash& other) const diff --git a/score/launch_manager/src/daemon/src/common/identifier_hash.hpp b/score/launch_manager/src/daemon/src/common/identifier_hash.hpp index 67aec10452..1ea0195f6f 100644 --- a/score/launch_manager/src/daemon/src/common/identifier_hash.hpp +++ b/score/launch_manager/src/daemon/src/common/identifier_hash.hpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -41,16 +42,13 @@ class IdentifierHash final { public: /// @brief Constructs an IdentifierHash object from the given ID. - /// @param id A const reference to std::string representing an ID. - explicit IdentifierHash(const std::string& id); - - /// @brief Constructs an IdentifierHash object from the given ID. - /// @param id A std::string_view representing an ID. + /// @param id A string representing an ID. explicit IdentifierHash(std::string_view id); - /// @brief Constructs an IdentifierHash object with the given ID. - /// @param A C-string representing an ID. - explicit IdentifierHash(const char* id); + /// @brief Constructs an IdentifierHash object from the given ID, + /// if that ID is already in the registry. + /// @param id A string representing an ID. + static std::optional if_exists(std::string_view id); // This class is trivially copyable / movable // For this reason we are applying the rule of zero @@ -135,6 +133,10 @@ class IdentifierHash final static std::mutex& get_registry_mutex(); private: + /// @brief Constructs an IdentifierHash object with the given ID. + /// @param A raw ID. + explicit IdentifierHash(std::size_t hash_id); + /// internal representation of the ID, that was passed in constructor std::size_t hash_id_ = 0; }; diff --git a/score/launch_manager/src/daemon/src/common/identifier_hash_UT.cpp b/score/launch_manager/src/daemon/src/common/identifier_hash_UT.cpp index 36cddc3e35..7a3dc417f0 100644 --- a/score/launch_manager/src/daemon/src/common/identifier_hash_UT.cpp +++ b/score/launch_manager/src/daemon/src/common/identifier_hash_UT.cpp @@ -147,13 +147,9 @@ TEST_F(IdentifierHashTest, IdentifierHash_HashValueIsStableAcrossCompilersAndPro TEST_F(IdentifierHashTest, IdentifierHash_ConstructorOverloadsAgreeOnTheSameContent) { RecordProperty("Description", "Verify all constructors of IdentifierHash have the same hash."); - const std::string as_string = "ProcessGroup1/Startup"; - const std::string_view as_string_view = "ProcessGroup1/Startup"; - const char* as_c_string = "ProcessGroup1/Startup"; - ASSERT_EQ(IdentifierHash(as_string).data(), IdentifierHash(as_string_view).data()); - ASSERT_EQ(IdentifierHash(as_string).data(), IdentifierHash(as_c_string).data()); - ASSERT_EQ(IdentifierHash(as_string_view).data(), IdentifierHash(as_c_string).data()); + ASSERT_EQ(IdentifierHash().data(), IdentifierHash("").data()); + ASSERT_EQ(IdentifierHash().data(), IdentifierHash::if_exists("").value().data()); } TEST_F(IdentifierHashTest, IdentifierHash_LessThanOperator) @@ -183,3 +179,19 @@ TEST_F(IdentifierHashTest, IdentifierHash_LessThanOperator) ASSERT_FALSE(hash2 < hash1); } } + +TEST_F(IdentifierHashTest, IdentifierHash_IfExists_Existing_CString) +{ + RecordProperty("Description", "Verify that IdentifierHash::if_exists returns the hash when it exists."); + + IdentifierHash("Hello"); + EXPECT_TRUE(IdentifierHash::if_exists("Hello").has_value()); +} + +TEST_F(IdentifierHashTest, IdentifierHash_IfExists_NotExisting_CString) +{ + RecordProperty( + "Description", "Verify that IdentifierHash::if_exists returns std::nullopt when the hash does not exist."); + + EXPECT_FALSE(IdentifierHash::if_exists("Hello C-string").has_value()); +}