*** empty log message ***

git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@318 29311d96-e01e-0410-9327-a35deaab8ce9
This commit is contained in:
sage 2005-06-14 23:35:38 +00:00
parent 7416379a41
commit 43f09119e2

View 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);
}
}
}