/******************************************************************//**
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. 【转】分享10VPN

    以下介绍的vpn,都是有免费流量赠送的免费vpn,完全不免费的不在之列. 免费vpn因为用的人比较多,所以高峰时段可能会有点慢,但是人少时,还是比较顺畅的.对于偶尔浏览外网,看看新闻的同学来说,免费v ...

  2. 转几篇WPF文章

    How to view word document in WPF application (CSVSTOViewWordInWPF) WPF 浏览PDF 文件 如何保存RichTextBox的文本到数 ...

  3. 生成XML文件,通过实体生成XML文件

    实体 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Xm ...

  4. oracle中的dual表详解

    oracle中的dual表详解 1.DUAL表的用途 Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的Select语句块中 --查看当前连接用户 SQL> s ...

  5. 【MongoDB】开启认证权限

    1. mongodb.conf : 添加 auth=true 2. use admin (3.0+ 使用 createUser ;<3.0版本  http://www.cnblogs.com/g ...

  6. Excel与SqlServer的导入导出问题总结

    1.Excel导入到SqlServer中,如果Excel里面的某一列,即有文本,又有数字,导入SqlServer中这一列的类型将会是float,Excel里面对应的文本值将导不进来,为null. 解决 ...

  7. (转载)Cocos2dx-OpenGL ES2.0教程:你的第一个立方体(5)

    在上篇文章中,我们介绍了VBO索引的使用,使用VBO索引可以有效地减少顶点个数,优化内存,提高程序效率. 本教程将带领大家一起走进3D–绘制一个立方体.其实画立方体本质上和画三角形没什么区别,所有的模 ...

  8. 各系统下设置输入法按键为ctrl+shift+space

    xp=====(一直找不到..原来右边是可以下拉的).. linux  ibus----- 设置---直接按下Ctrl+Shift+Space

  9. HTTP verb的安全性和幂等性

    Http协议规定了不同方法的安全特性和幂等特性,作为服务提供者的服务器必需为客户端提供这些特性. 安全性,仅指该方法的多次调用不会产生副作用,不涉及传统意义上的“安全”,这里的副作用是指资源状态.即, ...

  10. bzoj 2744: [HEOI2012]朋友圈 二分图匹配

    2744: [HEOI2012]朋友圈 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 612  Solved: 174[Submit][Status] ...