在postgres 8.2.19中用LRU替换时钟替换算法。任何想法?

时间:2014-10-31 05:39:36

标签: c algorithm postgresql

在postgres代码中,与此更改相关的代码存在于这些地方

~/src/backend/storage/buffer/buf_init.c
~/src/backend/storage/buffer/bufmgr.c
~/src/backend/storage/buffer/freelist.c 

我尝试更改freelist.c中具有实际时钟替换算法逻辑的代码。 有人可以帮助我如何继续用LRU逻辑替换时钟替换算法逻辑。 欢迎相关的想法! 提前谢谢。

这是代码freelist.c

的一部分
volatile BufferDesc *
StrategyGetBuffer(void)
{
    volatile BufferDesc *buf;
    int trycounter;
    LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE);

    /*
     * Try to get a buffer from the freelist.  Note that the freeNext fields
     * are considered to be protected by the BufFreelistLock not the
     * individual buffer spinlocks, so it's OK to manipulate them without
     * holding the spinlock.
     */
    while (StrategyControl->firstFreeBuffer >= 0)
    {
        buf = &BufferDescriptors[StrategyControl->firstFreeBuffer];
        Assert(buf->freeNext != FREENEXT_NOT_IN_LIST);

        /* Unconditionally remove buffer from freelist */
        StrategyControl->firstFreeBuffer = buf->freeNext;
        buf->freeNext = FREENEXT_NOT_IN_LIST;

        /*
         * If the buffer is pinned or has a nonzero usage_count, we cannot use
         * it; discard it and retry.  (This can only happen if VACUUM put a
         * valid buffer in the freelist and then someone else used it before
         * we got to it.)
         */
        LockBufHdr(buf);
        if (buf->refcount == 0 && buf->usage_count == 0)
            return buf;
        UnlockBufHdr(buf);
    }
    /* Nothing on the freelist, so run the "clock sweep" algorithm */
    trycounter = NBuffers;
    for (;;)
    {
        buf = &BufferDescriptors[StrategyControl->nextVictimBuffer];

        if (++StrategyControl->nextVictimBuffer >= NBuffers)
            StrategyControl->nextVictimBuffer = 0;

        /*
         * If the buffer is pinned or has a nonzero usage_count, we cannot use
         * it; decrement the usage_count and keep scanning.
         */
        LockBufHdr(buf);
        if (buf->refcount == 0 && buf->usage_count == 0)
            return buf;
        if (buf->usage_count > 0)
        {
            buf->usage_count--;
            trycounter = NBuffers;
        }
        else if (--trycounter == 0)
        {
            /*
             * We've scanned all the buffers without making any state changes,
             * so all the buffers are pinned (or were when we looked at them).
             * We could hope that someone will free one eventually, but it's * probably  
               better to fail than to risk getting stuck in an
             * infinite loop.
             */
            UnlockBufHdr(buf);
            elog(ERROR, "no unpinned buffers available");
        }
        UnlockBufHdr(buf);
    }

    /* not reached */
    return NULL;
}

0 个答案:

没有答案