From: Thomas Markwalder Date: Wed, 23 Jul 2025 17:29:27 +0000 (-0400) Subject: [#3770] Add hashing to CfgOption X-Git-Tag: Kea-3.1.0~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3b9c32932ccc1af4ba1443e1e2ff178970be4f1f;p=thirdparty%2Fkea.git [#3770] Add hashing to CfgOption modified: src/lib/dhcp/classify.cc modified: src/lib/dhcp/classify.h modified: src/lib/dhcp/tests/classify_unittest.cc modified: src/lib/dhcpsrv/cfg_option.h --- diff --git a/src/lib/dhcp/classify.cc b/src/lib/dhcp/classify.cc index 5021ef1005..543b81d99f 100644 --- a/src/lib/dhcp/classify.cc +++ b/src/lib/dhcp/classify.cc @@ -121,7 +121,7 @@ ClientClasses::fromElement(isc::data::ConstElementPtr cc_list) { bool ClientClasses::equals(const ClientClasses& other) const { - return ((size() == other.size()) && std::equal(cbegin(), cend(), other.cbegin())); + return ((size() == other.size()) && std::equal(cbegin(), cend(), other.cbegin())); } ClientClasses& @@ -134,5 +134,14 @@ ClientClasses::operator=(const ClientClasses& other) { return (*this); } -} // end of namespace isc::dhcp -} // end of namespace isc +size_t +ClientClasses::Hash::operator()(const ClientClasses &client_classes) { + return (hash_value(client_classes)); +} + +size_t hash_value(const ClientClasses& client_classes) { + boost::hash hasher; + return (hasher(client_classes.toText(""))); +} + +}} // end of namespace isc diff --git a/src/lib/dhcp/classify.h b/src/lib/dhcp/classify.h index 9e60e24393..645a65eab0 100644 --- a/src/lib/dhcp/classify.h +++ b/src/lib/dhcp/classify.h @@ -18,6 +18,7 @@ #include #include +#include /// @file classify.h /// @@ -250,11 +251,32 @@ public: /// are invalid void fromElement(isc::data::ConstElementPtr list); + /// @brief Hash enabling use in the unordered containers. + struct Hash { + /// @brief A hashing operator. + /// + /// @param client_classes ClientClasses instance to be hashed. + /// \return a hashing result. + size_t operator()(const ClientClasses& client_classes); + }; + private: /// @brief container part ClientClassContainer container_; }; +/// @brief Hash a ClientClasses instance. +/// +/// This method allows boost multi-index hashed indexes on ClientClasses. +/// It follows the requirement with equality: if two class lists are equal +/// their hashes are equal, if two class lists are not equal their hashes +/// are almost surely not equal. +/// +/// @param address A @c ClientClasses to hash. +/// @return The hash of the ClientClasses. + +size_t hash_value(const ClientClasses& client_classes); + /// @brief Smart pointer to ClientClasses object. typedef boost::shared_ptr ClientClassesPtr; diff --git a/src/lib/dhcp/tests/classify_unittest.cc b/src/lib/dhcp/tests/classify_unittest.cc index f635817e63..64c68064fe 100644 --- a/src/lib/dhcp/tests/classify_unittest.cc +++ b/src/lib/dhcp/tests/classify_unittest.cc @@ -11,6 +11,7 @@ #include #include +#include using namespace isc; using namespace isc::dhcp; @@ -291,3 +292,40 @@ TEST(ClassifyTest, ClientClassesIntersects) { EXPECT_TRUE(classes1.intersects(classes2)); EXPECT_TRUE(classes2.intersects(classes1)); } + +TEST(ClassifyTest, ClientClassesHash) { + // Add hashes for different contents to a set. + ClientClasses::Hash hash; + std::unordered_set results; + + ClientClasses cclasses; + results.insert(hash(cclasses)); + + cclasses.insert("one"); + results.insert(hash(cclasses)); + + cclasses.insert("two"); + results.insert(hash(cclasses)); + + cclasses.insert("three"); + results.insert(hash(cclasses)); + + // Should have all four entries. + EXPECT_EQ(4, results.size()); + + // Check that empty containers make equal hashes. + ClientClasses empty1; + ClientClasses empty2; + EXPECT_EQ(hash(empty1), hash(empty2)); + + // Check that equal containers make equal hashes. + ClientClasses cclasses2(cclasses); + EXPECT_EQ(hash(cclasses2), hash(cclasses)); + + // Check that different ordering make not equal hashes. + ClientClasses cclasses3; + cclasses3.insert("three"); + cclasses3.insert("two"); + cclasses3.insert("one"); + EXPECT_NE(hash(cclasses3), hash(cclasses)); +} diff --git a/src/lib/dhcpsrv/cfg_option.h b/src/lib/dhcpsrv/cfg_option.h index 9c8ef0f75a..aefef982ec 100644 --- a/src/lib/dhcpsrv/cfg_option.h +++ b/src/lib/dhcpsrv/cfg_option.h @@ -342,6 +342,7 @@ typedef boost::multi_index_container< ClientClasses, &OptionDescriptor::client_classes_> > + > > > OptionContainer;