mirror of
https://github.com/ceph/ceph
synced 2025-02-24 03:27:10 +00:00
*** empty log message ***
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@318 29311d96-e01e-0410-9327-a35deaab8ce9
This commit is contained in:
parent
7416379a41
commit
43f09119e2
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user