Skip to content

Commit 3b9c329

Browse files
committed
[#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
1 parent 3b9622c commit 3b9c329

File tree

4 files changed

+73
-3
lines changed

4 files changed

+73
-3
lines changed

src/lib/dhcp/classify.cc

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ ClientClasses::fromElement(isc::data::ConstElementPtr cc_list) {
121121

122122
bool
123123
ClientClasses::equals(const ClientClasses& other) const {
124-
return ((size() == other.size()) && std::equal(cbegin(), cend(), other.cbegin()));
124+
return ((size() == other.size()) && std::equal(cbegin(), cend(), other.cbegin()));
125125
}
126126

127127
ClientClasses&
@@ -134,5 +134,14 @@ ClientClasses::operator=(const ClientClasses& other) {
134134
return (*this);
135135
}
136136

137-
} // end of namespace isc::dhcp
138-
} // end of namespace isc
137+
size_t
138+
ClientClasses::Hash::operator()(const ClientClasses &client_classes) {
139+
return (hash_value(client_classes));
140+
}
141+
142+
size_t hash_value(const ClientClasses& client_classes) {
143+
boost::hash<std::string> hasher;
144+
return (hasher(client_classes.toText("")));
145+
}
146+
147+
}} // end of namespace isc

src/lib/dhcp/classify.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <boost/multi_index/sequenced_index.hpp>
1919

2020
#include <string>
21+
#include <functional>
2122

2223
/// @file classify.h
2324
///
@@ -250,11 +251,32 @@ class ClientClasses : public isc::data::CfgToElement {
250251
/// are invalid
251252
void fromElement(isc::data::ConstElementPtr list);
252253

254+
/// @brief Hash enabling use in the unordered containers.
255+
struct Hash {
256+
/// @brief A hashing operator.
257+
///
258+
/// @param client_classes ClientClasses instance to be hashed.
259+
/// \return a hashing result.
260+
size_t operator()(const ClientClasses& client_classes);
261+
};
262+
253263
private:
254264
/// @brief container part
255265
ClientClassContainer container_;
256266
};
257267

268+
/// @brief Hash a ClientClasses instance.
269+
///
270+
/// This method allows boost multi-index hashed indexes on ClientClasses.
271+
/// It follows the requirement with equality: if two class lists are equal
272+
/// their hashes are equal, if two class lists are not equal their hashes
273+
/// are almost surely not equal.
274+
///
275+
/// @param address A @c ClientClasses to hash.
276+
/// @return The hash of the ClientClasses.
277+
278+
size_t hash_value(const ClientClasses& client_classes);
279+
258280
/// @brief Smart pointer to ClientClasses object.
259281
typedef boost::shared_ptr<ClientClasses> ClientClassesPtr;
260282

src/lib/dhcp/tests/classify_unittest.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <testutils/gtest_utils.h>
1212

1313
#include <gtest/gtest.h>
14+
#include <unordered_set>
1415

1516
using namespace isc;
1617
using namespace isc::dhcp;
@@ -291,3 +292,40 @@ TEST(ClassifyTest, ClientClassesIntersects) {
291292
EXPECT_TRUE(classes1.intersects(classes2));
292293
EXPECT_TRUE(classes2.intersects(classes1));
293294
}
295+
296+
TEST(ClassifyTest, ClientClassesHash) {
297+
// Add hashes for different contents to a set.
298+
ClientClasses::Hash hash;
299+
std::unordered_set<size_t> results;
300+
301+
ClientClasses cclasses;
302+
results.insert(hash(cclasses));
303+
304+
cclasses.insert("one");
305+
results.insert(hash(cclasses));
306+
307+
cclasses.insert("two");
308+
results.insert(hash(cclasses));
309+
310+
cclasses.insert("three");
311+
results.insert(hash(cclasses));
312+
313+
// Should have all four entries.
314+
EXPECT_EQ(4, results.size());
315+
316+
// Check that empty containers make equal hashes.
317+
ClientClasses empty1;
318+
ClientClasses empty2;
319+
EXPECT_EQ(hash(empty1), hash(empty2));
320+
321+
// Check that equal containers make equal hashes.
322+
ClientClasses cclasses2(cclasses);
323+
EXPECT_EQ(hash(cclasses2), hash(cclasses));
324+
325+
// Check that different ordering make not equal hashes.
326+
ClientClasses cclasses3;
327+
cclasses3.insert("three");
328+
cclasses3.insert("two");
329+
cclasses3.insert("one");
330+
EXPECT_NE(hash(cclasses3), hash(cclasses));
331+
}

src/lib/dhcpsrv/cfg_option.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ typedef boost::multi_index_container<
342342
ClientClasses,
343343
&OptionDescriptor::client_classes_>
344344
>
345+
345346
>
346347
>
347348
> OptionContainer;

0 commit comments

Comments
 (0)