/******************************************************************//**
Try to free a block.  If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.

NOTE: If this function returns TRUE, it will temporarily
release buf_pool->mutex.  Furthermore, the page frame will no longer be
accessible via bpage.

The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call.  No other
buf_page_get_mutex() may be held when calling this function.
@return TRUE if freed, FALSE otherwise. */
UNIV_INTERN
ibool
buf_LRU_free_block(
/*===============*/
    buf_page_t*    bpage,    /*!< in: block to be freed */
    ibool        zip)    /*!< in: TRUE if should remove also the
                compressed page of an uncompressed page */
{
    buf_page_t*    b = NULL;
    buf_pool_t*    buf_pool = buf_pool_from_bpage(bpage);
    mutex_t*    block_mutex = buf_page_get_mutex(bpage);

    ut_ad(buf_pool_mutex_own(buf_pool));
    ut_ad(mutex_own(block_mutex));
    ut_ad(buf_page_in_file(bpage));
    ut_ad(bpage->in_LRU_list);
    ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
#if UNIV_WORD_SIZE == 4
    /* On 32-bit systems, there is no padding in buf_page_t.  On
    other systems, Valgrind could complain about uninitialized pad
    bytes. */
    UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
#endif

    if (!buf_page_can_relocate(bpage)) {

        /* Do not free buffer-fixed or I/O-fixed blocks. */
        return(FALSE);
    }

#ifdef UNIV_IBUF_COUNT_DEBUG
    ut_a(ibuf_count_get(bpage->space, bpage->offset) == );
#endif /* UNIV_IBUF_COUNT_DEBUG */

    if (zip || !bpage->zip.data) {
        /* This would completely free the block. */
        /* Do not completely free dirty blocks. */

        if (bpage->oldest_modification) {
            return(FALSE);
        }
    } else if (bpage->oldest_modification) {
        /* Do not completely free dirty blocks. */

        if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
            ut_ad(buf_page_get_state(bpage)
                  == BUF_BLOCK_ZIP_DIRTY);
            return(FALSE);
        }

        goto alloc;
    } else if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
        /* Allocate the control block for the compressed page.
        If it cannot be allocated (without freeing a block
        from the LRU list), refuse to free bpage. */
alloc:
        b = buf_page_alloc_descriptor();
        ut_a(b);
        memcpy(b, bpage, sizeof *b);
    }

#ifdef UNIV_DEBUG
    if (buf_debug_prints) {
        fprintf(stderr, "Putting space %lu page %lu to free list\n",
            (ulong) buf_page_get_space(bpage),
            (ulong) buf_page_get_page_no(bpage));
    }
#endif /* UNIV_DEBUG */

    if (buf_LRU_block_remove_hashed_page(bpage, zip)!= BUF_BLOCK_ZIP_FREE) {  //这里
        ut_a(bpage->buf_fix_count == );

        if (b) {
            buf_page_t*    hash_b;
            buf_page_t*    prev_b    = UT_LIST_GET_PREV(LRU, b);

            const ulint    fold = buf_page_address_fold(
                bpage->space, bpage->offset);

            hash_b    = buf_page_hash_get_low(
                buf_pool, bpage->space, bpage->offset, fold);

            ut_a(!hash_b);

            b->state = b->oldest_modification
                ? BUF_BLOCK_ZIP_DIRTY
                : BUF_BLOCK_ZIP_PAGE;
            UNIV_MEM_DESC(b->zip.data,
                      page_zip_get_size(&b->zip), b);

            /* The fields in_page_hash and in_LRU_list of
            the to-be-freed block descriptor should have
            been cleared in
            buf_LRU_block_remove_hashed_page(), which
            invokes buf_LRU_remove_block(). */
            ut_ad(!bpage->in_page_hash);
            ut_ad(!bpage->in_LRU_list);
            /* bpage->state was BUF_BLOCK_FILE_PAGE because
            b != NULL. The type cast below is thus valid. */
            ut_ad(!((buf_block_t*) bpage)->in_unzip_LRU_list);

            /* The fields of bpage were copied to b before
            buf_LRU_block_remove_hashed_page() was invoked. */
            ut_ad(!b->in_zip_hash);
            ut_ad(b->in_page_hash);
            ut_ad(b->in_LRU_list);

            HASH_INSERT(buf_page_t, hash,
                    buf_pool->page_hash, fold, b);

            /* Insert b where bpage was in the LRU list. */
            if (UNIV_LIKELY(prev_b != NULL)) {
                ulint    lru_len;

                ut_ad(prev_b->in_LRU_list);
                ut_ad(buf_page_in_file(prev_b));
#if UNIV_WORD_SIZE == 4
                /* On 32-bit systems, there is no
                padding in buf_page_t.  On other
                systems, Valgrind could complain about
                uninitialized pad bytes. */
                UNIV_MEM_ASSERT_RW(prev_b, sizeof *prev_b);
#endif
                UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU,
                             prev_b, b);

                incr_LRU_size_in_bytes(b, buf_pool);

                if (buf_page_is_old(b)) {
                    buf_pool->LRU_old_len++;
                    if (UNIV_UNLIKELY
                        (buf_pool->LRU_old
                         == UT_LIST_GET_NEXT(LRU, b))) {

                        buf_pool->LRU_old = b;
                    }
                }

                lru_len = UT_LIST_GET_LEN(buf_pool->LRU);

                if (lru_len > BUF_LRU_OLD_MIN_LEN) {
                    ut_ad(buf_pool->LRU_old);
                    /* Adjust the length of the
                    old block list if necessary */
                    buf_LRU_old_adjust_len(buf_pool);
                } else if (lru_len == BUF_LRU_OLD_MIN_LEN) {
                    /* The LRU list is now long
                    enough for LRU_old to become
                    defined: init it */
                    buf_LRU_old_init(buf_pool);
                }
#ifdef UNIV_LRU_DEBUG
                /* Check that the "old" flag is consistent
                in the block and its neighbours. */
                buf_page_set_old(b, buf_page_is_old(b));
#endif /* UNIV_LRU_DEBUG */
            } else {
                ut_d(b->in_LRU_list = FALSE);
                buf_LRU_add_block_low(b, buf_page_is_old(b));
            }

            if (b->state == BUF_BLOCK_ZIP_PAGE) {
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
                buf_LRU_insert_zip_clean(b);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
            } else {
                /* Relocate on buf_pool->flush_list. */
                buf_flush_relocate_on_flush_list(bpage, b);
            }

            bpage->zip.data = NULL;
            page_zip_set_size(&bpage->zip, );

            /* Prevent buf_page_get_gen() from
            decompressing the block while we release
            buf_pool->mutex and block_mutex. */
            mutex_enter(&buf_pool->zip_mutex);
            buf_page_set_sticky(b);
            mutex_exit(&buf_pool->zip_mutex);
        }

        buf_pool_mutex_exit(buf_pool);
        mutex_exit(block_mutex);

        /* Remove possible adaptive hash index on the page.
        The page was declared uninitialized by
        buf_LRU_block_remove_hashed_page().  We need to flag
        the contents of the page valid (which it still is) in
        order to avoid bogus Valgrind warnings.*/

        UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
                   UNIV_PAGE_SIZE);
        btr_search_drop_page_hash_index((buf_block_t*) bpage);
        UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
                 UNIV_PAGE_SIZE);

        if (b) {
            /* Compute and stamp the compressed page
            checksum while not holding any mutex.  The
            block is already half-freed
            (BUF_BLOCK_REMOVE_HASH) and removed from
            buf_pool->page_hash, thus inaccessible by any
            other thread. */

            mach_write_to_4(
                b->zip.data + FIL_PAGE_SPACE_OR_CHKSUM,
                UNIV_LIKELY(srv_use_checksums)
                ? page_zip_calc_checksum(
                    b->zip.data,
                    page_zip_get_size(&b->zip))
                : BUF_NO_CHECKSUM_MAGIC);
        }

        buf_pool_mutex_enter(buf_pool);
        mutex_enter(block_mutex);

        if (b) {
            mutex_enter(&buf_pool->zip_mutex);
            buf_page_unset_sticky(b);
            mutex_exit(&buf_pool->zip_mutex);
        }

        buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
    } else {
        /* The block_mutex should have been released by
        buf_LRU_block_remove_hashed_page() when it returns
        BUF_BLOCK_ZIP_FREE. */
        ut_ad(block_mutex == &buf_pool->zip_mutex);
        mutex_enter(block_mutex);
    }

    return(TRUE);
}

函数buf_LRU_free_block的更多相关文章

  1. innoDB源码分析--缓冲池

    最开始学Oracle的时候,有个概念叫SGA和PGA,是非常重要的概念,其实就是内存中的缓冲池.InnoDB的设计类似于Oracle,也会在内存中开辟一片缓冲池.众所周知,CPU的速度和磁盘的IO速度 ...

  2. Python 小而美的函数

    python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况   any any(iterable) ...

  3. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  4. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  5. C++对C的函数拓展

    一,内联函数 1.内联函数的概念 C++中的const常量可以用来代替宏常数的定义,例如:用const int a = 10来替换# define a 10.那么C++中是否有什么解决方案来替代宏代码 ...

  6. 菜鸟Python学习笔记第一天:关于一些函数库的使用

    2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...

  7. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  8. 复杂的 Hash 函数组合有意义吗?

    很久以前看到一篇文章,讲某个大网站储存用户口令时,会经过十分复杂的处理.怎么个复杂记不得了,大概就是先 Hash,结果加上一些特殊字符再 Hash,结果再加上些字符.再倒序.再怎么怎么的.再 Hash ...

  9. JS核心系列:浅谈函数的作用域

    一.作用域(scope) 所谓作用域就是:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的. function scope(){ var foo = "global&quo ...

随机推荐

  1. 【Delphi】窗体阴影

    procedure TForm1.FormCreate(Sender: TObject); begin SetClassLong(Handle, GCL_STYLE, GetClassLong(Han ...

  2. C盘清理大作战

    C盘会随着使用时间慢慢变满(即使你不在C盘装程序),下面就记录几个C盘清理的方法: 1.使用清理软件清理C盘(360卫视,腾讯管家) 2.转移虚拟内存:计算机右键属性——高级管理设置——高级——性能- ...

  3. 009.EscapeRegExChars

    类型:function 可见性:public 所在单元:RegularExpressionsCore 父类:TPerlRegEx 把转义字符变成原意字符 例如\d意为0~9某个数字,通过此函数转换后则 ...

  4. 可变参数列表---以dbg()为例

    在UART驱动的drivers/serial/samsung.h中遇到如下定义: #ifdef CONFIG_SERIAL_SAMSUNG_DEBUG extern void printascii(c ...

  5. PHP webserver 之 soap 生成wsdl文件

    <?php /** * Copyright (c) , Braulio Jos?Solano Rojas * All rights reserved. * * Redistribution an ...

  6. SVN备份教程(一)

    最近一段时间在项目中用到了SVN备份的相关内容,这里给大家做一个简单的教程,重点在于SVN备份环境的搭建过程中,大家学到的解决问题的思维方式. 1.分类 SVN备份主要分为两种:一种是远程备份,另一种 ...

  7. 实用程序Commer的开发——U盘内容可选同步至FTP服务器

    需求分析:需要在软件运行后将插入的U盘里面的文件Copy至本机上,然后可选的上传一部分至FTP服务器上. 系统设计:基于MFC的基本对话框程序:主要模块有检测U盘插入并复制文件以及上传到网络.通过对U ...

  8. C# 5.0 TAP 模式下的HTTP Get和Post

    标题有点瘆人,换了工作之后很少写代码了,之前由于签了保密协议,不敢把代码拿出来分享给大家,只能摘抄网上的, 今斗胆拿出来晒晒,跪求指点,直接上代码吧 public class HTTPHelper : ...

  9. mysql 权限管理

     参考:    http://www.cnblogs.com/Richardzhu/p/3318595.html 一.MySQL权限简介 关于mysql的权限简单的理解就是mysql允许你做你全力以内 ...

  10. linux命令useradd添加用户详解

    1.作用 useradd或adduser命令用来建立用户帐号和创建用户的起始目录,使用权限是超级用户. 2.格式 useradd [-d home] [-s shell] [-c comment] [ ...