[svn] commit: r2315 - /branches/trac192/src/lib/datasrc/cache.cc

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Jun 28 20:44:09 UTC 2010


Author: each
Date: Mon Jun 28 20:44:09 2010
New Revision: 2315

Log:
Refactor HotCache to use a std::list for the LRU queue.

Modified:
    branches/trac192/src/lib/datasrc/cache.cc

Modified: branches/trac192/src/lib/datasrc/cache.cc
==============================================================================
--- branches/trac192/src/lib/datasrc/cache.cc (original)
+++ branches/trac192/src/lib/datasrc/cache.cc Mon Jun 28 20:44:09 2010
@@ -23,6 +23,8 @@
 #include <dns/rrset.h>
 #include <dns/rrtype.h>
 
+#include <list>
+
 #include <datasrc/cache.h>
 
 using namespace std;
@@ -111,9 +113,9 @@
     bool isValid() const;
     //@}
 
-    // Links to next and previous nodes in the LRU list.
-    CacheNodePtr prev;
-    CacheNodePtr next;
+    // An iterator referencing this entry in the LRU list. This
+    // permits unit-time removal using list::erase().
+    list<CacheNodePtr>::iterator lru_entry_;
 
     /// The \c Question (name/rrclass/rrtype) answered by this cache node
     const isc::dns::Question question;
@@ -135,8 +137,6 @@
     expiry = now + lifespan;
 
     entry = CacheEntryPtr(new CacheEntry(rrset, flags));
-    prev = CacheNodePtr();
-    next = CacheNodePtr();
 }
 
 // CacheNode constructor for a negative cache entry
@@ -151,10 +151,7 @@
     expiry = now + lifespan;
 
     entry = CacheEntryPtr(new CacheEntry(RRsetPtr(), flags));
-    prev = CacheNodePtr();
-    next = CacheNodePtr();
-}
-
+}
 // Returns true if the node has not yet expired.
 bool
 CacheNode::isValid() const {
@@ -177,16 +174,14 @@
 class HotCacheImpl {
 public:
     HotCacheImpl(int slots, bool enabled);
-    ~HotCacheImpl();
-
-    // Pointers to the head and tail of the LRU list.
-    CacheNodePtr lru_head_;
-    CacheNodePtr lru_tail_;
-
-    // Is this cache enabled?  (True by default)
+
+    // The LRU list
+    list<CacheNodePtr> lru_;
+
+    // Flag to indicate whether the cache is enabled
     bool enabled_;
 
-    // Number of available slots in the LRU list.  (If zero,
+    // The number of available slots in the LRU list.  (If zero,
     // then the list is unbounded; otherwise, items are removed
     // from the tail of the list whenever it grows past slots_.)
     int slots_;
@@ -194,10 +189,11 @@
     // The number of items currently in the list.
     int count_;
 
-    // Map from query tuple to cache node pointer, allowing faster retrieval
+    // Map from query tuple to cache node pointer, allowing fast retrieval
+    // of data without a linear search of the LRU list
     std::map<Question, CacheNodePtr> map_;
 
-    // Move a node to the front of the LRU queue.
+    // Move a node to the front of the LRU list.
     void promote(CacheNodePtr node);
 
     // Remove a node from the cache.
@@ -211,19 +207,6 @@
 HotCacheImpl::HotCacheImpl(int slots, bool enabled) :
     enabled_(enabled), slots_(slots), count_(0)
 {}
-
-// HotCacheImpl destructor
-HotCacheImpl::~HotCacheImpl() {
-    CacheNodePtr node;
-    for (node = lru_head_; node != CacheNodePtr(); node = node->next) {
-        lru_head_ = node->next;
-        if (lru_head_) {
-            lru_head_->prev = CacheNodePtr();
-        }
-    }
-
-    lru_head_ = lru_tail_ = CacheNodePtr();
-}
 
 // Insert a cache node into the cache
 inline void
@@ -237,74 +220,35 @@
         }
     }
 
-    if (lru_head_) {
-        node->next = lru_head_;
-        lru_head_->prev = node;
-        lru_head_ = node;
-    } else {
-        node->next = lru_head_;
-        lru_head_ = node;
-        lru_tail_ = node;
-    }
+    lru_.push_front(node);
+    node->lru_entry_ = lru_.begin();
 
     map_[node->question] = node;
     ++count_;
 
-    if (slots_ != 0 && count_ > slots_ && lru_tail_) {
-        remove(lru_tail_);
-        assert(count_ == slots_);
-    }
-}
-
-// Promote a node to the head of the LRU queue
+    if (slots_ != 0 && count_ > slots_) {
+        remove(lru_.back());
+    }
+}
+
+// Promote a node to the head of the LRU list
 void
 HotCacheImpl::promote(CacheNodePtr node) {
-    if (!node || node == lru_head_) {
-        return;
-    }
-
-    if (node->prev) {
-        node->prev->next = node->next;
-    }
-
-    if (node->next) {
-        node->next->prev = node->prev;
-    }
-
-    if (node == lru_tail_) {
-        lru_tail_ = node->prev;
-        lru_tail_->next = CacheNodePtr();
-    }
-
-    lru_head_->prev = node;
-    node->prev = CacheNodePtr();
-    node->next = lru_head_;
-    lru_head_ = node;
-}
-
-// Remove a node from the LRU queue and the map
+    if (!node) {
+        return;
+    }
+    if (node->lru_entry_ == lru_.begin()) {
+        return;
+    }
+    lru_.erase(node->lru_entry_);
+    lru_.push_front(node);
+    node->lru_entry_ = lru_.begin();
+}
+
+// Remove a node from the LRU list and the map
 void
 HotCacheImpl::remove(ConstCacheNodePtr node) {
-    if (!node) {
-        return;
-    }
-    
-    if (node == lru_head_) {
-        lru_head_ = node->next;
-    }
-
-    if (node == lru_tail_) {
-        lru_tail_ = node->prev;
-    }
-
-    if (node->next) {
-        node->next->prev = node->prev;
-    }
-
-    if (node->prev) {
-        node->prev->next = node->next;
-    }
-
+    lru_.erase(node->lru_entry_);
     map_.erase(node->question);
     --count_;
 }
@@ -387,10 +331,8 @@
         return;
     }
 
-    while (impl_->slots_ != 0 && impl_->count_ > impl_->slots_ &&
-           impl_->lru_tail_)
-    {
-        impl_->remove(impl_->lru_tail_);
+    while (impl_->slots_ != 0 && impl_->count_ > impl_->slots_) {
+        impl_->remove(impl_->lru_.back());
     }
 }
 




More information about the bind10-changes mailing list