]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
*** empty log message ***
authorsage <sage@29311d96-e01e-0410-9327-a35deaab8ce9>
Tue, 14 Jun 2005 23:35:38 +0000 (23:35 +0000)
committersage <sage@29311d96-e01e-0410-9327-a35deaab8ce9>
Tue, 14 Jun 2005 23:35:38 +0000 (23:35 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@318 29311d96-e01e-0410-9327-a35deaab8ce9

ceph/include/lru.h

index be730bd5b848d3b6135cdc14c57356553f386207..3a387369d8ca47e195702b26c06e3c3ee732db36 100644 (file)
@@ -9,58 +9,110 @@ using namespace std;
 #include "include/config.h"
 
 
-#define LRU_POS_NONE    0
-#define LRU_POS_TOP     1
-#define LRU_POS_BOT     2
-#define LRU_POS_PINTAIL 3
-
 
 class LRUObject {
  private:
   LRUObject *lru_next, *lru_prev;
-  char lru_pos;
   bool lru_expireable;
   class LRU *lru;
+  class LRUList *lru_list;
 
  public:
   LRUObject() {
        lru_next = lru_prev = NULL;
-       lru_pos = LRU_POS_NONE;
+       lru_list = 0;
        lru_expireable = true;
        lru = 0;
   }
 
-  bool lru_get_pos() { return lru_pos; }
-  void lru_set_pos(char p) { lru_pos = p; }
-
   // pin/unpin item in cache
   void lru_pin(); 
   void lru_unpin();
   bool lru_is_expireable() { return lru_expireable; }
 
   friend class LRU;
-  //friend class MDCache;
+  friend class LRUList;
 };
 
 
+class LRUList {
+ private:
+  LRUObject *head, *tail;
+  __uint32_t len;
+
+ public:
+  LRUList() {
+       head = tail = 0;
+       len = 0;
+  }
+  
+  __uint32_t  get_length() { return len; }
+
+  LRUObject *get_head() {
+       return head;
+  }
+  LRUObject *get_tail() {
+       return tail;
+  }
+
+  void insert_head(LRUObject *o) {
+       o->lru_next = head;
+       o->lru_prev = NULL;
+       if (head) {
+         head->lru_prev = o;
+       } else {
+         tail = o;
+       }
+       head = o;
+       o->lru_list = this;
+       len++;
+  }
+  void insert_tail(LRUObject *o) {
+       o->lru_next = NULL;
+       o->lru_prev = tail;
+       if (tail) {
+         tail->lru_next = o;
+       } else {
+         head = o;
+       }
+       tail = o;
+       o->lru_list = this;
+       len++;
+  }
+
+  void remove(LRUObject *o) {
+       assert(o->lru_list == this);
+       if (o->lru_next)
+         o->lru_next->lru_prev = o->lru_prev;
+       else
+         tail = o->lru_prev;
+       if (o->lru_prev)
+         o->lru_prev->lru_next = o->lru_next;
+       else
+         head = o->lru_next;
+       o->lru_next = o->lru_prev = NULL;
+       o->lru_list = 0;
+       assert(len>0);
+       len--;
+  }
+  
+};
+
 
 class LRU {
  protected:
-  LRUObject *lru_tophead, *lru_toptail, *lru_bothead, *lru_bottail;
-  LRUObject *lru_pintailhead, *lru_pintailtail;
-  __uint32_t lru_ntop, lru_nbot, lru_num, lru_num_pinned;
-  double lru_midpoint;
+  LRUList lru_top, lru_bot, lru_pintail;
+  __uint32_t lru_num, lru_num_pinned;
   __uint32_t lru_max;   // max items
+  double lru_midpoint;
 
   friend class LRUObject;
   //friend class MDCache; // hack
+  
  public:
   LRU() {
-       lru_ntop = lru_nbot = lru_num = 0;
+       lru_num = 0;
        lru_num_pinned = 0;
-       lru_tophead = lru_toptail = NULL;
-       lru_bothead = lru_bottail = NULL;
-       lru_pintailhead = lru_pintailtail = NULL;
        lru_midpoint = .9;
        lru_max = 0;
   }
@@ -88,17 +140,7 @@ class LRU {
        //o->lru_in_lru = true;
        assert(!o->lru);
        o->lru = this;
-
-       o->lru_set_pos( LRU_POS_TOP );
-       o->lru_next = lru_tophead;
-       o->lru_prev = NULL;
-       if (lru_tophead) {
-         lru_tophead->lru_prev = o;
-       } else {
-         lru_toptail = o;
-       }
-       lru_tophead = o;
-       lru_ntop++;
+       lru_top.insert_head( o );
        lru_num++;
        lru_num_pinned += !o->lru_expireable;
        lru_adjust();
@@ -110,17 +152,7 @@ class LRU {
        //o->lru_in_lru = true;
        assert(!o->lru);
        o->lru = this;
-
-       o->lru_set_pos( LRU_POS_BOT );
-       o->lru_next = lru_bothead;
-       o->lru_prev = NULL;
-       if (lru_bothead) {
-         lru_bothead->lru_prev = o;
-       } else {
-         lru_bottail = o;
-       }
-       lru_bothead = o;
-       lru_nbot++;
+       lru_bot.insert_head(o);
        lru_num++;
        lru_num_pinned += !o->lru_expireable;
   }
@@ -129,17 +161,19 @@ class LRU {
   void lru_insert_bot(LRUObject *o) {
        assert(!o->lru);
        o->lru = this;
+       lru_bot.insert_tail(o);
+       lru_num++;
+       lru_num_pinned += !o->lru_expireable;
+  }
 
-       o->lru_set_pos( LRU_POS_BOT );
-       o->lru_next = NULL;
-       o->lru_prev = lru_bottail;
-       if (lru_bottail) {
-         lru_bottail->lru_next = o;
-       } else {
-         lru_bothead = o;
-       }
-       lru_bottail = o;
-       lru_nbot++;
+  // insert at bottom of lru
+  void lru_insert_pintail(LRUObject *o) {
+       assert(!o->lru);
+       o->lru = this;
+       
+       assert(!o->lru_is_expireable());
+
+       lru_pintail.insert_head(o);
        lru_num++;
        lru_num_pinned += !o->lru_expireable;
   }
@@ -152,10 +186,14 @@ class LRU {
        if (!lru_max) return;
 
        __uint32_t topwant = (__uint32_t)(lru_midpoint * (double)lru_max);
-       while (lru_ntop > topwant && lru_toptail) {
+       while (0 && lru_top.get_length() > 0 && 
+                  lru_top.get_length() > topwant) {
          // remove from tail of top, stick at head of bot
          // FIXME: this could be way more efficient by moving a whole chain of items.
-         lru_insert_mid( lru_remove( lru_toptail) );
+
+         LRUObject *o = lru_top.get_tail();
+         lru_top.remove(o);
+         lru_bot.insert_head(o);
        }
   }
 
@@ -168,48 +206,17 @@ class LRU {
        if (!o->lru) return o;
 
 
-       if (o->lru_get_pos() == LRU_POS_TOP) {
-         //cout << "removing " << o << " from top" << endl;
-         // top
-         if (o->lru_next)
-               o->lru_next->lru_prev = o->lru_prev;
-         else
-               lru_toptail = o->lru_prev;
-         if (o->lru_prev)
-               o->lru_prev->lru_next = o->lru_next;
-         else
-               lru_tophead = o->lru_next;
-         lru_ntop--;
-       } 
-       else if (o->lru_get_pos() == LRU_POS_BOT) {
-         //cout << "removing " << o << " from bot" << endl;
-         // bot
-         if (o->lru_next)
-               o->lru_next->lru_prev = o->lru_prev;
-         else
-               lru_bottail = o->lru_prev;
-         if (o->lru_prev)
-               o->lru_prev->lru_next = o->lru_next;
-         else
-               lru_bothead = o->lru_next;
-         lru_nbot--;
-       }
-       else {
-         assert(o->lru_get_pos() == LRU_POS_PINTAIL);
-         if (o->lru_next)
-               o->lru_next->lru_prev = o->lru_prev;
-         else
-               lru_pintailtail = o->lru_prev;
-         if (o->lru_prev)
-               o->lru_prev->lru_next = o->lru_next;
-         else
-               lru_pintailhead = o->lru_next;
-         lru_nbot--;
-       }
+       if (o->lru_list == &lru_top)
+         lru_top.remove(o);
+       else if (o->lru_list == &lru_bot) 
+         lru_bot.remove(o);
+       else if (o->lru_list == &lru_pintail)
+         lru_pintail.remove(o);
+       else
+         assert(0);
+
        lru_num--;
        lru_num_pinned -= !o->lru_expireable;
-       o->lru_next = o->lru_prev = NULL;
-       o->lru_set_pos(LRU_POS_NONE);
        o->lru = 0;
        return o;
   }
@@ -223,7 +230,7 @@ class LRU {
 
   // touch item -- move to midpoint (unless already higher)
   bool lru_midtouch(LRUObject *o) {
-       if (o->lru_get_pos() == LRU_POS_TOP) return false;
+       if (o->lru_list == &lru_top) return false;
        
        lru_remove(o);
        lru_insert_mid(o);
@@ -243,31 +250,24 @@ class LRU {
        LRUObject *p;
 
        // look through tail of bot
-       while (lru_bottail) {
-         p = lru_remove( lru_bottail );
+       while (lru_bot.get_length()) {
+         p = lru_bot.get_tail();
+
          if (p->lru_expireable) 
-               return p;   // yay.
-         
-         // pinned, move to pintail
-         p->lru_next = lru_pintailhead;
-         p->lru_prev = NULL;
-         if (lru_pintailhead) {
-               lru_pintailhead->lru_prev = p;
-         } else {
-               lru_pintailtail = p;
-         }
-         lru_pintailhead = p;
-         
-         p->lru_set_pos( LRU_POS_PINTAIL );
+               return lru_remove(p);   // yay.
+
+         // move to pintail
+         lru_pintail.insert_head(p);
        }
 
        // ok, try head then
-       p = lru_toptail;
-       while (p) {
+       while (lru_top.get_length()) {
+         p = lru_top.get_tail();
          if (p->lru_expireable) 
                return lru_remove( p );
-         //cout << "p " << p << " no expireable" << endl;
-         p = p->lru_prev;
+
+         // move to pintail
+         lru_pintail.insert_head(p);
        }
        
        // no luck!
@@ -276,7 +276,7 @@ class LRU {
 
 
   void lru_status() {
-       dout(10) << "lru: " << lru_num << " items, " << lru_ntop << " top, " << lru_nbot << " bot" << endl;
+       dout(10) << "lru: " << lru_num << " items, " << lru_top.get_length() << " top, " << lru_bot.get_length() << " bot, " << lru_pintail.get_length() << " pintail" << endl;
   }
 
 };
@@ -293,9 +293,9 @@ inline void LRUObject::lru_unpin() {
        lru->lru_num_pinned--;
 
        // move out of tail?
-       if (lru_get_pos() == LRU_POS_PINTAIL) {
-         lru->lru_remove(this);
-         lru->lru_insert_bot(this);
+       if (lru_list == &lru->lru_pintail) {
+         lru->lru_pintail.remove(this);
+         lru->lru_bot.insert_tail(this);
        }
   }
 }