/******************************************************************//**
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. 图片grayscale(灰阶效果)webkit内核支持。

    filter:gray;-webkit-filter: grayscale(100%); 置为灰阶等hove时候 -webkit-filter: grayscale(0%);显示出彩色.

  2. 用PHP生成随机数的函数

    转自:http://www.jbxue.com/article/5034.html 介绍:在早期的php中生成一个随机字符串时,总是先创建一个字符池,然后用一个循环和mt_rand()或rand()生 ...

  3. 解决BLOB/TEXT column can't have a default value query问题

    Create table的时候,报错BLOB/TEXT column 'xxxxxx( 表名称)' can't have a default value query ,意思是TEXT类型的表字段不能够 ...

  4. jsp与servlet之间的参数传递【转】

    JSP与 servlet之间的传值有两种情况:JSP -> servlet, servlet -> JSP. 通过对象 request和 session (不考虑 application) ...

  5. 利用PHPRPC以及SOAP分别实现PHP的Webserver功能

    服务端:phprpc服务端 <?php /* phprpc 服务端演示 * time:2014-06-23 */ require_once 'phprpc_server.php';//引入服务端 ...

  6. 深度:ARC会导致的内存泄露

    iOS提供了ARC功能,很大程度上简化了内存管理的代码. 但使用ARC并不代表了不会发生内存泄露,使用不当照样会发生内存泄露. 下面列举两种内存泄露的情况. 1,循环参照 A有个属性参照B,B有个属性 ...

  7. TWaver初学实战——如何在EasyUI中插入TWaver

    TWaver是一款强大的图形界面开发组件,可以很方便地集成到其他开发工具中.今天就用一个小例子来操练如何结合TWaver和EasyUI进行网页开发. 准备工作 俗话说他山之玉可以直接拿来,EasyUI ...

  8. 使用Yeoman搭建 AngularJS 应用 (11) —— 让我们搭建一个网页应用

    原文地址:http://yeoman.io/codelab/prepare-production.html 让我们发布这个应用 优化产品的文件 为了创建应用的产品版本,我们想做如下的事情 检查你的代码 ...

  9. find 与 tar命令连用

    find 与 tar命令连用 今天打包日志时,用 -type f -exec tar -cvf log.tar {} \; 发现只打包了最后一个文件,应该是tar的c参数,每次都创建一个新的文件,想了 ...

  10. js检测对象的类型

    在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. 示例: var array=[1,2,3]; Object. ...