// insert p to lru-list...
// but fixed item can not be swaped(can not goes into Lru List)..
// const named BF_XXX or BM_XXX, see its definition..
void LruMap_Release(LruMap* self, LruMapNode* p) {
FS_ASSERT(p->refCount);
if (0 != --p->refCount) return;
#ifdef LRU_WRITE_BACK_AT_RELEASE
if (SIG_TRUE(p->flag, BF_DIRTY)) {
self->write(self, p);
CLR_SIG(p->flag, BF_DIRTY);
}
#endif
if (SIG_TRUE(p->flag, BF_FIXED)) return;
if (SIG_TRUE(p->flag, BF_HITED)) {
INSERT_NODE_NEXT(_M_LruHead, p);
self->last = self->last->prev; // --last, move backward...
}
else { // not hited..
switch (p->flag & BF_METHOD_MASK) {
default:
break;
case BM_NOMAL: {
unsigned int i;
LruMapNode *iter, *headPrev = _M_LruHead->prev;
INSERT_NODE_NEXT(self->last, p);
if (self->last == _M_LruHead) {
#ifdef _FS_DEBUG
int dgb_only = 0; // for set break point here..
#endif
}
else if (self->tmap.nCount > self->workSetSize) {
i = 0;
iter = p;
while (i < self->workSetSize) {
// 'workSetSize' is very small (normally == 4),
// so this cycle will not make a big overhead
if (iter == headPrev) {
// when hit prob is from high becoming to low,
// in this case, it will not go here..
// when hit prob has been very low,
// it hardly always goes here..
break;
}
iter = iter->next;
++i;
}
if (iter != headPrev) {
// working set is not full...
// must += 2, if not += 2, old hited item will be swaped out
// the lru-list becomes a queue..
self->last = p->next; // last += 2;
}
}
break; }
case BM_LRU: // insert as most recent used..
INSERT_NODE_NEXT(_M_LruHead, p);
break;
case BM_ACC_ONCE: // insert as most UNrecent used..
INSERT_NODE_PREV(p, _M_LruHead);
break;
}
}
return;
}