设为首页 收藏本站
查看: 580|回复: 0

[经验分享] mysql内核分析--innodb哈希表的内部实现(上)

[复制链接]

尚未签到

发表于 2016-10-20 10:37:41 | 显示全部楼层 |阅读模式
1.哈希表的概述

   hash表的实现是innodb的基础功能之一,通过关键值进行映射,从而迅速进行查询、插入、删除的操作。

   hash表算法,在数据库内核里面被广泛的使用,举个例子,这个结构将会在下文中继续使用的。

/* Data structure for a column in a table */

struct dict_col_struct{

       hash_node_t   hash;       /* hash chain node */

       ulint        ind;  /* table column position (they are numbered

                            starting from 0) */

       ulint        clust_pos;/* position of the column in the

                            clustered index */

       ulint        ord_part;/* count of how many times this column

                            appears in ordering fields of an index */

       const char*    name;      /* name */

       dtype_t           type;       /* data type */

       dict_table_t*   table;       /* back pointer to table of this column */

       ulint        aux; /* this is used as an auxiliary variable

                            in some of the functions below */

};

   从数据结构的名称上来看,这个关于列结构的,具有相同hash值的col结构,通过hash字段进行连接。该字段的定义如下:

typedef void*  hash_node_t;

  col结构里面的其它字段表明该列的一些属性:name表示列名,type表明列的值类型,table表明该列所属的表结构。



2.数据结构

typedef struct hash_table_struct hash_table_t;

typedef struct hash_cell_struct hash_cell_t;



typedef void*  hash_node_t;



/* The hash table structure */

struct hash_table_struct {

       ibool              adaptive;/* TRUE if this is the hash table of the

                            adaptive hash index */

       ulint        n_cells;/* number of cells in the hash table */

       hash_cell_t*    array;      /* pointer to cell array */

       ulint        n_mutexes;/* if mutexes != NULL, then the number of

                            mutexes, must be a power of 2 */

       mutex_t* mutexes;/* NULL, or an array of mutexes used to

                            protect segments of the hash table */

       mem_heap_t**       heaps;     /* if this is non-NULL, hash chain nodes for

                            external chaining can be allocated from these

                            memory heaps; there are then n_mutexes many of

                            these heaps */

       mem_heap_t* heap;

       ulint        magic_n;

};



struct hash_cell_struct{

       void*      node;      /* hash chain node, NULL if none */

};



1)创建hash表

  n_cells表明hash表的大小,我们都知道hash表常用的是进行素数的模操作。先看下创建hash表的函数的实现。

/*****************************************************************

Creates a hash table with >= n array cells. The actual number of cells is

chosen to be a prime number slightly bigger than n. */



hash_table_t*

hash_create(

/*========*/

                     /* out, own: created table */

       ulint n)    /* in: number of array cells */

{

       hash_cell_t*    array;

       ulint        prime;

       hash_table_t*  table;

       ulint        i;

       hash_cell_t*    cell;

      

       prime = ut_find_prime(n);



       table = mem_alloc(sizeof(hash_table_t));



       array = ut_malloc(sizeof(hash_cell_t) * prime);

      

       table->adaptive = FALSE;

       table->array = array;

       table->n_cells = prime;

       table->n_mutexes = 0;

       table->mutexes = NULL;

       table->heaps = NULL;

       table->heap = NULL;

       table->magic_n = HASH_TABLE_MAGIC_N;

      

       /* Initialize the cell array */



       for (i = 0; i < prime; i++) {



              cell = hash_get_nth_cell(table, i);

              cell->node = NULL;

       }



       return(table);

}

  在创建hash表的时候,我们提供的常用是一个普通的数字,来指明hash表的大小。这个n的值可能不是素数,所以需要通过ut_find_prime(n)来产生一个稍大于n的素数,当然这个素数不一定是大于n的最小素数。ut_find_prime的具体实现见文件ut0rnd.c。

  接着调用mem_alloc函数来分配hash表结构,为该结构分配空间,这个比较简单。接着分配数量为prime个的hash单元,并通过后面的循环语句将单元的node指针置为空。



2)基础的函数

  提供值之后,我们需要进行映射,获取对应的单元的编号。

/******************************************************************

Calculates the hash value from a folded value. */

UNIV_INLINE

ulint

hash_calc_hash(

/*===========*/

                            /* out: hashed value */

       ulint        fold, /* in: folded value */

       hash_table_t*  table)      /* in: hash table */

{

       return(ut_hash_ulint(fold, table->n_cells));

}

  其中ut_hash_ulint函数的实现如下:

/***********************************************************

The following function generates a hash value for a ulint integer

to a hash table of size table_size, which should be a prime

or some random number for the hash table to work reliably. */

UNIV_INLINE

ulint

ut_hash_ulint(

/*=========*/

                            /* out: hash value */

       ulint    key,            /* in: value to be hashed */

       ulint    table_size)       /* in: hash table size */

{

       key = key ^ UT_HASH_RANDOM_MASK2;



       return(key % table_size);

}

  通过模操作获得了对应的hash表单元的数值,然后就可以通过该数值找到hash表的该单元节点,调用hash_get_nth_cell函数,函数实现如下:

/****************************************************************

Gets the nth cell in a hash table. */

UNIV_INLINE

hash_cell_t*

hash_get_nth_cell(

/*==============*/

                            /* out: pointer to cell */

       hash_table_t*        table,       /* in: hash table */

       ulint              n)    /* in: cell index */

{

       ut_ad(n < table->n_cells);



       return(table->array + n);

}





本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/whyangwanfu/archive/2008/09/21/2958762.aspx

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-288843-1-1.html 上篇帖子: Mysql查询5分钟内数据的sql 下篇帖子: dbutils安装笔记以及mysql数据库操作问题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表