From: sage Date: Tue, 14 Jun 2005 23:35:38 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: v0.1~2063 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=43f09119e2b616c89278ea953b5de772f369427f;p=ceph.git *** empty log message *** git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@318 29311d96-e01e-0410-9327-a35deaab8ce9 --- diff --git a/ceph/include/lru.h b/ceph/include/lru.h index be730bd5b84..3a387369d8c 100644 --- a/ceph/include/lru.h +++ b/ceph/include/lru.h @@ -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); } } }