bearbecueLe 09/05/2011 à 10:12
for (hh_u32 b = m_Blocks.Count(); b-- != 0; )
{
TArray<SBlock> &bl = m_Blocks[b];
hh_u32 slotsLeft = kMaxTrashCount - curTrashCount;
hh_u32 stop = HHMin(bl.Count(), slotsLeft, 0xFFFFUL); // 0xFFFF -> pretty unlikely... just in case...
hh_u32 l2Bits = (_BlockCount - b) << 14;
for (hh_u32 i = 0; i < stop; i++)
{
// encoding of the sort key:
//
// 31 0
// 00000000 00000111 11000000 00000000
// Frame Age log2sz slot
// [0 - 8192] [0 - 20] [0 - 16384]
//
// for identical-age pages, we want to free the largest ones in priority.
// and we want to trash the oldest pages.
// by storing (maxAge - (currentDate - pageDate)) in bits [19-31]
// and (_BlockCount - (log2(size) - _MinAllocSizeL2)) in bits [14-18]
// and sorting from lowest to highest, we'll get the exact ordering we want:
// oldest pages first, then largest pages first
HH_STATIC_ASSERT(_BlockCount < 0x1F); // must fit inside 5 bits for the above mapping to work. in practise, unless we're using the full 32 bits, it will always fit.
hh_i32 date = hh_i32(m_CurrentDate) - bl[i].m_Date; // m_CurrentDate always >= m_Date
enum { kMaxDate = (1 << (32-19)) - 1 };
date = kMaxDate - date; // dates older than kMaxDate will be < 0
hh_u32 cMask = (date & 0x80000000) >> 31; // clear mask, when date < 0, cMask = 0xFFFFFFFF, when date >= 0, cMask = 0x00000000
hh_u32 cDate = date & ~cMask; // cDate = HHMax(date, 0);
toTrash[curTrashCount++] = (cDate << 19) | l2Bits | i;
}
}