Browse Source

[2701] Added composite indexes to container holding V4 leases in memfile.

Marcin Siodelski 12 years ago
parent
commit
532c36304e

+ 1 - 1
src/lib/dhcp/duid.h

@@ -105,7 +105,7 @@ public:
     ClientId(const uint8_t* clientid, size_t len);
 
     /// @brief Returns reference to the client-id data
-    const std::vector<uint8_t> getClientId() const;
+    std::vector<uint8_t> getClientId() const;
 
     /// @brief Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
     std::string toText() const;

+ 3 - 1
src/lib/dhcpsrv/alloc_engine.cc

@@ -285,8 +285,9 @@ AllocEngine::allocateAddress4(const SubnetPtr& subnet,
         }
 
         // Check if there's existing lease for that subnet/clientid/hwaddr combination.
-        Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(hwaddr->hwaddr_, subnet->getID());
+        Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(*hwaddr, subnet->getID());
         if (existing) {
+            std::cout << "Got lease using HWADdr" << std::endl;
             // We have a lease already. This is a returning client, probably after
             // its reboot.
             existing = renewLease4(subnet, clientid, hwaddr, existing, fake_allocation);
@@ -301,6 +302,7 @@ AllocEngine::allocateAddress4(const SubnetPtr& subnet,
         if (clientid) {
             existing = LeaseMgrFactory::instance().getLease4(*clientid, subnet->getID());
             if (existing) {
+            std::cout << "Got lease using Clientid" << std::endl;
                 // we have a lease already. This is a returning client, probably after
                 // its reboot.
                 existing = renewLease4(subnet, clientid, hwaddr, existing, fake_allocation);

+ 24 - 1
src/lib/dhcpsrv/memfile_lease_mgr.cc

@@ -56,7 +56,9 @@ Lease4Ptr Memfile_LeaseMgr::getLease4(const isc::asiolink::IOAddress& addr) cons
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MEMFILE_GET_ADDR4).arg(addr.toText());
 
-    Lease4Storage::iterator l = storage4_.find(addr);
+    typedef Lease4Storage::nth_index<0>::type SearchIndex;
+    const SearchIndex& idx = storage4_.get<0>();
+    Lease4Storage::iterator l = idx.find(addr);
     if (l == storage4_.end()) {
         return (Lease4Ptr());
     } else {
@@ -77,6 +79,16 @@ Lease4Ptr Memfile_LeaseMgr::getLease4(const HWAddr& hwaddr,
               DHCPSRV_MEMFILE_GET_SUBID_HWADDR).arg(subnet_id)
         .arg(hwaddr.toText());
 
+    typedef Lease4Storage::nth_index<1>::type SearchIndex;
+    const SearchIndex& idx = storage4_.get<1>();
+    SearchIndex::const_iterator lease = idx.find(boost::make_tuple(hwaddr.hwaddr_,
+                                                                   subnet_id));
+    if (lease == idx.end()) {
+        return Lease4Ptr();
+    }
+
+    return (*lease);
+
     Lease4Storage::iterator l;
     for (l = storage4_.begin(); l != storage4_.end(); ++l) {
         if ( ((*l)->hwaddr_ == hwaddr.hwaddr_) &&
@@ -100,6 +112,17 @@ Lease4Ptr Memfile_LeaseMgr::getLease4(const ClientId& client_id,
     LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
               DHCPSRV_MEMFILE_GET_SUBID_CLIENTID).arg(subnet_id)
               .arg(client_id.toText());
+
+    typedef Lease4Storage::nth_index<2>::type SearchIndex;
+    const SearchIndex& idx = storage4_.get<2>();
+    SearchIndex::const_iterator lease = idx.find(boost::make_tuple(client_id.getClientId(),
+                                                                   subnet_id));
+    if (lease == idx.end()) {
+        return Lease4Ptr();
+    }
+
+    return (*lease);
+
     Lease4Storage::iterator l;
     for (l = storage4_.begin(); l != storage4_.end(); ++l) {
         if ( (*(*l)->client_id_ == client_id) &&

+ 45 - 1
src/lib/dhcpsrv/memfile_lease_mgr.h

@@ -22,6 +22,7 @@
 #include <boost/multi_index/member.hpp>
 #include <boost/multi_index/ordered_index.hpp>
 #include <boost/multi_index_container.hpp>
+#include <boost/multi_index/composite_key.hpp>
 
 namespace isc {
 namespace dhcp {
@@ -220,6 +221,30 @@ public:
 
 protected:
 
+    template<typename KeyExtractor1, typename KeyExtractor2>
+    class KeyFromKey {
+    public:
+        typedef typename KeyExtractor1::result_type result_type;
+
+        /// @brief Constructor.
+        KeyFromKey()
+            : key1_(KeyExtractor1()), key2_(KeyExtractor2()) { };
+
+        /// @brief Extract key with another key.
+        ///
+        /// @param arg the key value.
+        ///
+        /// @tparam key value type.
+        template<typename T>
+        result_type operator() (T& arg) const {
+            return (key1_(key2_(arg)));
+        }
+    private:
+        KeyExtractor1 key1_; ///< key 1.
+        KeyExtractor2 key2_; ///< key 2.
+    };
+
+
     typedef boost::multi_index_container< // this is a multi-index container...
     Lease6Ptr, // it will hold shared_ptr to leases6
         boost::multi_index::indexed_by< // and will be sorted by
@@ -238,8 +263,27 @@ protected:
             // IPv6 address that are unique. That particular key is a member
             // of the Lease6 structure, is of type IOAddress and can be accessed
             // by doing &Lease6::addr_
-            boost::multi_index::ordered_unique<
+            boost::multi_index::hashed_unique<
                 boost::multi_index::member<Lease, isc::asiolink::IOAddress, &Lease::addr_>
+            >,
+            boost::multi_index::ordered_unique<
+                boost::multi_index::composite_key<
+                    Lease4,
+                    boost::multi_index::member<Lease4, std::vector<uint8_t>,
+                                               &Lease4::hwaddr_>,
+                    boost::multi_index::member<Lease, SubnetID, &Lease::subnet_id_>
+                >
+            >,
+            boost::multi_index::ordered_unique<
+                boost::multi_index::composite_key<
+                    Lease4,
+                    KeyFromKey<
+                        boost::multi_index::const_mem_fun<ClientId, std::vector<uint8_t>,
+                                                          &ClientId::getClientId>,
+                        boost::multi_index::member<Lease4, ClientIdPtr, &Lease4::client_id_>
+                    >,
+                    boost::multi_index::member<Lease, uint32_t, &Lease::subnet_id_>
+                >
             >
         >
     > Lease4Storage; // Let the whole contraption be called Lease6Storage.