]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1334] Moved ClientClasses to multi index
authorFrancis Dupont <fdupont@isc.org>
Wed, 22 Jul 2020 17:13:50 +0000 (19:13 +0200)
committerFrancis Dupont <fdupont@isc.org>
Mon, 31 Jan 2022 15:31:32 +0000 (16:31 +0100)
src/lib/dhcp/classify.cc
src/lib/dhcp/classify.h

index 65cd8308ce62e1b6085507544378d24a5001af7f..adcf0a4997729441a34391b5af6522219982aa81 100644 (file)
@@ -17,7 +17,7 @@ namespace isc {
 namespace dhcp {
 
 ClientClasses::ClientClasses(const std::string& class_names)
-    : list_(), set_() {
+    : container_() {
     std::vector<std::string> split_text;
     boost::split(split_text, class_names, boost::is_any_of(","),
                  boost::algorithm::token_compress_off);
@@ -32,8 +32,17 @@ ClientClasses::ClientClasses(const std::string& class_names)
 
 void
 ClientClasses::erase(const ClientClass& class_name) {
-    list_.remove(class_name);
-    static_cast<void>(set_.erase(class_name));
+    auto& idx = container_.get<ClassNameTag>();
+    auto it = idx.find(class_name);
+    if (it != idx.end()) {
+        static_cast<void>(idx.erase(it));
+    }
+}
+
+bool
+ClientClasses::contains(const ClientClass& x) const {
+    auto const& idx = container_.get<ClassNameTag>();
+    return (idx.count(x) != 0);
 }
 
 std::string
@@ -47,6 +56,6 @@ ClientClasses::toText(const std::string& separator) const {
     }
     return (s.str());
 }
-    
+
 } // end of namespace isc::dhcp
 } // end of namespace isc
index 9a2ef8be35670f62151e483d248df6ff49f29b19..cdc249d6385bf80375e488641e80be4beb8766e3 100644 (file)
@@ -7,10 +7,11 @@
 #ifndef CLASSIFY_H
 #define CLASSIFY_H
 
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index_container.hpp>
 #include <string>
-#include <iterator>
-#include <list>
-#include <unordered_set>
 
 /// @file   classify.h
 ///
@@ -36,6 +37,28 @@ namespace dhcp {
     /// @brief Defines a single class name.
     typedef std::string ClientClass;
 
+    /// @brief Tag for the sequence index.
+    struct ClassSequenceTag { };
+
+    /// @brief Tag for the name index.
+    struct ClassNameTag { };
+
+    /// @brief the client class multi-index.
+    typedef boost::multi_index_container<
+        ClientClass,
+        boost::multi_index::indexed_by<
+            // First index is the sequence one.
+            boost::multi_index::sequenced<
+                boost::multi_index::tag<ClassSequenceTag>
+            >,
+            // Second index is the name hash one.
+            boost::multi_index::hashed_unique<
+                boost::multi_index::tag<ClassNameTag>,
+                boost::multi_index::identity<ClientClass>
+            >
+        >
+    > ClientClassContainer;
+
     /// @brief Container for storing client class names
     ///
     /// Both a list to iterate on it in insert order and unordered
@@ -44,10 +67,10 @@ namespace dhcp {
     public:
 
         /// @brief Type of iterators
-        typedef std::list<ClientClass>::const_iterator const_iterator;
+        typedef ClientClassContainer::const_iterator const_iterator;
 
         /// @brief Default constructor.
-        ClientClasses() : list_(), set_() {
+        ClientClasses() : container_() {
         }
 
         /// @brief Constructor from comma separated values.
@@ -60,8 +83,7 @@ namespace dhcp {
         ///
         /// @param class_name The name of the class to insert
         void insert(const ClientClass& class_name) {
-            list_.push_back(class_name);
-            set_.insert(class_name);
+            static_cast<void>(container_.push_back(class_name));
         }
 
         /// @brief Erase element by name.
@@ -71,7 +93,7 @@ namespace dhcp {
 
         /// @brief Check if classes is empty.
         bool empty() const {
-            return (list_.empty());
+            return (container_.empty());
         }
 
         /// @brief Returns the number of classes.
@@ -79,31 +101,28 @@ namespace dhcp {
         /// @note; in C++ 11 list size complexity is constant so
         /// there is no advantage to use the set part.
         size_t size() const {
-            return (list_.size());
+            return (container_.size());
         }
 
         /// @brief Iterator to the first element.
         const_iterator cbegin() const {
-            return (list_.cbegin());
+            return (container_.cbegin());
         }
 
         /// @brief Iterator to the past the end element.
         const_iterator cend() const {
-            return (list_.cend());
+            return (container_.cend());
         }
 
         /// @brief returns if class x belongs to the defined classes
         ///
         /// @param x client class to be checked
         /// @return true if x belongs to the classes
-        bool contains(const ClientClass& x) const {
-            return (set_.count(x) != 0);
-        }
+        bool contains(const ClientClass& x) const;
 
         /// @brief Clears containers.
         void clear() {
-            list_.clear();
-            set_.clear();
+            container_.clear();
         }
 
         /// @brief Returns all class names as text
@@ -114,15 +133,11 @@ namespace dhcp {
         std::string toText(const std::string& separator = ", ") const;
 
     private:
-        /// @brief List/ordered part
-        std::list<ClientClass> list_;
-
-        /// @brief Set/unordered part
-        std::unordered_set<ClientClass> set_;
+        /// @brief container part
+        ClientClassContainer container_;
     };
+}
 
-};
-
-};
+}
 
 #endif /* CLASSIFY_H */