priority based lru
in src/mp/mp_fget.c, __memp_fget()
, 初始化 一个page buffer时, 设置其 priority:
bhp->priority = MPOOL_LRU_REDZONE;
in src/mp/mp_fget.c, __memp_fput()
, 对一个page buffer做put, 使其reference减一. bhp->ref--
, 若reference减为0, 则调整其 priority. 下面的 bhp->priority = c_mp->lru_priority;
和 ++c_mp->lru_priority
保证LRU; 而且根据传入的 priority参数做相应的调整.
prioriry最大为UINT32_MAX, 所以有可能需要 wraparound. __memp_reset_lru() 降低 所有page buffer的priority.
/* Update priority values. */
if (priority == DB_PRIORITY_VERY_LOW ||
mfp->priority == MPOOL_PRI_VERY_LOW)
bhp->priority = 0;
else {
/*
* We don‘t lock the LRU priority or the pages field, if
* we get garbage (which won‘t happen on a 32-bit machine), it
* only means a buffer has the wrong priority.
*/
bhp->priority = c_mp->lru_priority;
switch (priority) {
default:
case DB_PRIORITY_UNCHANGED:
pfactor = mfp->priority;
break;
case DB_PRIORITY_VERY_LOW:
pfactor = MPOOL_PRI_VERY_LOW;
break;
case DB_PRIORITY_LOW:
pfactor = MPOOL_PRI_LOW;
break;
case DB_PRIORITY_DEFAULT:
pfactor = MPOOL_PRI_DEFAULT;
break;
case DB_PRIORITY_HIGH:
pfactor = MPOOL_PRI_HIGH;
break;
case DB_PRIORITY_VERY_HIGH:
pfactor = MPOOL_PRI_VERY_HIGH;
break;
}
adjust = 0;
if (pfactor != 0)
adjust = (int)c_mp->pages / pfactor;
if (F_ISSET(bhp, BH_DIRTY))
adjust += (int)c_mp->pages / MPOOL_PRI_DIRTY;
if (adjust > 0) {
if (MPOOL_LRU_REDZONE - bhp->priority >=
(u_int32_t)adjust)
bhp->priority += adjust;
} else if (adjust < 0)
if (bhp->priority > (u_int32_t)-adjust)
bhp->priority += adjust;
}
...
/*
* On every buffer put we update the cache lru priority and check
* for wraparound. The increment doesn‘t need to be atomic: occasional
* lost increments are okay; __memp_reset_lru handles race conditions.
*/
if (++c_mp->lru_priority >= MPOOL_LRU_REDZONE &&
(t_ret = __memp_reset_lru(env, infop)) != 0 && ret == 0)
ret = t_ret;
return (ret);
src/mp/mp_alloc.c, __memp_alloc()
, 无法分配新的 buffer的内存时, 则重用已有的 buffer内存. 算法很复杂, 单独写一个吧.
时间: 2024-10-17 10:28:01