MySQL InnoDB 中通用双向链表的实现

源码在Ut0lst.h中
注意:这里我将链表中的实际的串联的数据叫做数据类比如:lock_t、mem_block_t

链表作为一种的非常重要的数据结构,在任何地方都会用到,这里简单解释一下innodb双向链表的实现,让我们来看看innodb链表设计的魅力:
经常在某些结构体中看到
UT_LIST_BASE_NODE_T(mem_block_t) base;
UT_LIST_NODE_T(mem_block_t) list;

作为最为基本的一种的数据结构innodb中实现得比较精妙涉及到重要的4个C++知识点:
1、仿函数
2、类成员指针
3、类模板
4、函数重载

简单的说仿函数是调用的时候类似函数调用的形式的类,类成员指针并非一个真正意义上的指针,而是指向特定类对象相对位置的一个偏移量。

比如如下就是一个仿函数类:

template <typename T>

class ShowElemt
{
public:
    ShowElemt()
    {
        n = 0;
    }
    void operator()(T &t)
    {
        n++;
        cout << t << " ";
    }
    void printCount()
    {
        cout << n << endl;
    }
public:
    int n;
};
下面是一个简单的类成员指针使用,他初始化分为2步在最后给出.:


#include<iostream>

using namespace std;

class T
{
  public:
  typedef int uint;
  public:
          int a;
          int b;
};

int main21(void)
{
        T t;
        int T::* t1 = &T::b;//1、成员函数指针 初始化为指向类T成员b的一个指针(成员函数指针指向的是偏移量)
        T* t2 = &t;//t2一个指向类变量t的指针
        t.*t1 = 10;//2、初始化t的t1类成员指针指向的内存空间值为10,实际上就是t.b=10
        cout<<t.*t1<<" "<<t2->*t1<<endl;//相同输出一个采用对象一个采用对象指针
        {
                T t3;
                t3.a=300;
                t.*t1 = t3.a; //他就是拥有实际内存空间的变量了
        }
}

模板和函数重载就没有什么好说的了。

接下来我们看看UT_LIST_BASE_NODE_T、UT_LIST_NODE_T分别代表了什么
实际上他们都是宏定义:
#define UT_LIST_BASE_NODE_T(t) ut_list_base<t, ut_list_node t::*>
#define UT_LIST_NODE_T(t) ut_list_node
那么他们的类型出来了实际上就是:
ut_list_base和ut_list_node,我们知道在设计链表的时候,通常有一个链表头数据结构,用来存储
比如链表中总共多少元素,链表头,链表尾等等特征,但是之前还是想来看看ut_list_node链表结构体:

template <typename Type>

struct ut_list_node {
    Type*        prev;            /*!< pointer to the previous
                        node, NULL if start of list */
    Type*        next;            /*!< pointer to next node,
                        NULL if end of list */

void reverse()
    {
        Type*    tmp = prev;
        prev = next;
        next = tmp;
    }
};
非常简单没有包含任何固定的数据信息,只是包含了链表的前后指针,同时包含了一个成员函数reverse,作为
实现链表反转的基础,这里也注意到由于没有包含任何数据信息成员,做到了链表和具体数据类之间的剥离。
在链表设计的时候通常有2种方式:
1、链表结构包含数据类
2、数据类包含链表结构
这里INNODB使用了后者,让链表的通用更加方便

再来看看ut_list_base 链表头结构体:

template <typename Type, typename NodePtr>

struct ut_list_base {
    typedef Type elem_type;
    typedef NodePtr node_ptr;
    typedef ut_list_node<Type> node_type;

ulint        count;            /*!< count of nodes in list */
    elem_type*    start;            /*!< pointer to list start,
                        NULL if empty */
    elem_type*    end;            /*!< pointer to list end,
                        NULL if empty */
    node_ptr    node;            /*!< Pointer to member field
                        that is used as a link node */
#ifdef UNIV_DEBUG
    ulint        init;            /*!< UT_LIST_INITIALISED if
                        the list was initialised with
                        UT_LIST_INIT() */
#endif /* UNIV_DEBUG */

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/47431093490f875e6ff5b99bb0935266.html