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&
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<std::string> hasher;
+ return (hasher(client_classes.toText("")));
+}
+
+}} // end of namespace isc
#include <boost/multi_index/sequenced_index.hpp>
#include <string>
+#include <functional>
/// @file classify.h
///
/// 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<ClientClasses> ClientClassesPtr;
#include <testutils/gtest_utils.h>
#include <gtest/gtest.h>
+#include <unordered_set>
using namespace isc;
using namespace isc::dhcp;
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<size_t> 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));
+}
ClientClasses,
&OptionDescriptor::client_classes_>
>
+
>
>
> OptionContainer;