参数uchar* head 是已经分配好内存的64个字节的地址

http://mysql.taobao.org/monthly/2015/08/07/

/** *先从.frm文件读取64字节 *第28和第29字节记录了key_length * *利用lseek定位到第30字节,并读取key_length长度的信息到disk_buff中 *disk_buff[0]代表了索引的个数 keys_num *disk_buff[1]代表了索引中列的个数  key_parts_num * *为了把disk_buff中的信息copy到结构体中,还要分配 keys*sizeof(KEY)+key_parts*sizeof(KEY_PARTS_INFO)大小的内存 key_buff,类型为KEY* * * *做循环 *share->key_info=key_buff; *key_part = key_buff+keys_num; * for(int i=0;i<keys;key_buff++)     key_buff->key_length=xxx;     xxxxx   key_buf->key_part = key_part;   for(j=key_buff->key_parts;j>=0;j--,key_part++)    key_part->fieldnr=xxx * *share->field = field_ptr //field_ptr为新分配的内存 *share->fileds = xxx; * for(int i=0;i<xxx;field_ptr++ ) *   field_ptr=xxx; * */

static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
                           File file)
{
  ;
  uint new_frm_ver, field_pack_length, new_field_pack_flag;
  uint interval_count, interval_parts, read_length, int_length;
  uint db_create_options, keys, key_parts, n_length;
  uint key_info_length, com_length, null_bit_pos;
  uint extra_rec_buf_length;
  uint i,j;
  bool use_hash;
  char *keynames, *names, *comment_pos;
  uchar forminfo[];
  uchar *record;
  uchar *disk_buff, *strpos, *null_flags, *null_pos;
  ulong pos, record_offset, *rec_per_key, rec_buff_length;
  handler *handler_file= ;
  KEY    *keyinfo;
  KEY_PART_INFO *key_part;
  SQL_CRYPT *crypted=;
  Field  **field_ptr, *reg_field;
  const char **interval_array;
  enum legacy_db_type legacy_db_type;
  my_bitmap_map *bitmaps;
  uchar *extra_segment_buff= ;
  ;
  uchar *format_section_fields= ;
  DBUG_ENTER("open_binary_frm");

  new_field_pack_flag= head[];
  new_frm_ver= (head[] - FRM_VER);
  field_pack_length= new_frm_ver <  ?  : ;
  disk_buff= ;

  error= ;
  /* Position of the form in the form file. */
  if (!(pos= get_form_pos(file, head)))
    goto err;                                   /* purecov: inspected */

  mysql_file_seek(file,pos,MY_SEEK_SET,MYF());
  ,MYF(MY_NABP)))
    goto err;
  share->frm_version= head[];

  share->max_rows= uint4korr(head+);
  share->min_rows= uint4korr(head+);

  /* Read keyinformation */
  key_info_length= (uint) uint2korr(head+28);
  mysql_file_seek(file, (), MY_SEEK_SET, MYF());

  /**   *disk_buff已经被分配了内存,大小为key_info_length   */
  if (read_string(file,(uchar**) &disk_buff,key_info_length))
    goto err;                                   /* purecov: inspected */
  ] & 0x80)
  {
    share->keys=      keys=      (disk_buff[] << ) | (disk_buff[] & 0x7f);
    share->key_parts= key_parts= uint2korr(disk_buff+);
  }
  else
  {
    share->keys=      keys=      disk_buff[];
    share->key_parts= key_parts= disk_buff[];
  }
 
  /**   *因为keyinfo是MYSQL服务器这边的结构体,因此需要分配内存   */
  n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
  ))))
    goto err;
  bzero((char*) keyinfo,n_length);

  /**   *share->key_info代表keyinfo这段内存起始地址   *keyinfo的类型为KEY*,故keyinfo++,意味着数组递增   *   */
  share->key_info= keyinfo;
  key_part= reinterpret_cast<KEY_PART_INFO*>(keyinfo+keys);
  strpos=disk_buff+;

  if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
                                         sizeof(ulong)*key_parts)))
    goto err;

   ; i < keys ; i++, keyinfo++)
  {
    keyinfo->table= ;                           // Updated in open_frm
    )
    {
      keyinfo->flags=       (uint) uint2korr(strpos) ^ HA_NOSAME;      //索引长度,索引中列的个数
      keyinfo->key_length= ();
      keyinfo->key_parts=  (];
      keyinfo->algorithm=  (];
      keyinfo->block_size= uint2korr(strpos+);
      strpos+=;
    }

    keyinfo->key_part=     key_part;
    keyinfo->rec_per_key= rec_per_key;
    for (j=keyinfo->key_parts ; j-- ; key_part++)
    {
      *rec_per_key++=;
      key_part->fieldnr=    (uint16) (uint2korr(strpos) & FIELD_NR_MASK);
      key_part->offset= ()-;
      key_part->key_type=    ();
    }
  }
  keynames=(char*) key_part;
  strpos+= (strmov(keynames, (;

  //reading index comments
  ; i < keys; i++, keyinfo++)
  {
    if (keyinfo->flags & HA_USES_COMMENT)
    {
      keyinfo->comment.length= uint2korr(strpos);
      keyinfo->comment.str= strmake_root(&share->mem_root, (,
                                         keyinfo->comment.length);
      strpos+=  + keyinfo->comment.length;
    }
  }

  share->key_block_size= uint2korr(head+);

  share->fields= uint2korr(forminfo+);
  pos= uint2korr(forminfo+);   /* Length of all screens */
  n_length= uint2korr(forminfo+);

  share->null_fields= uint2korr(forminfo+);
  com_length= uint2korr(forminfo+);
if (!(field_ptr = (Field **)
    alloc_root(&share->mem_root,
           ()*sizeof(Field*)+
               interval_count*sizeof(TYPELIB)+
               (share->fields+interval_parts+
                keys+)*sizeof(char *)+
               (n_length+int_length+com_length)))))
    goto err;                                   /* purecov: inspected */
    /**   *field_ptr也是刚分配内存的起始地址,赋值给share->field   */
  share->field= field_ptr;
  read_length=(uint) (share->fields * field_pack_length +
              pos+ (uint) (n_length+int_length+com_length));
  if (read_string(file,(uchar**) &disk_buff,read_length))
    goto err;                                   /* purecov: inspected */
  strpos= disk_buff+pos;

if (keynames)
    fix_type_pointers(&interval_array, &share->keynames, , &keynames);

 /* Allocate handler */
  if (!(handler_file= get_new_handler(share, thd->mem_root,
                                      share->db_type())))
    goto err;

  record= share->default_values-;              /* Fieldstart = 1 */
  if (share->null_field_first)
  {
    null_flags= null_pos= (uchar*) record+;
    null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ?  : ;
    /*
      null_bytes below is only correct under the condition that
      there are no bit fields.  Correct values is set below after the
      table struct is initialized
    */
    share->null_bytes= (share->null_fields + null_bit_pos + ) / ;
  }
 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
  {
    uint pack_flag, interval_nr, unireg_type, recpos, field_length;
    enum_field_types field_type;
    CHARSET_INFO *charset=NULL;
    Field::geometry_type geom_type= Field::GEOM_GEOMETRY;
    LEX_STRING comment;

    )
    {
      /* new frm file in 4.1 */
      field_length= uint2korr(strpos+);
      recpos=        uint3korr(strpos+);
      pack_flag=    uint2korr(strpos+);
      unireg_type=  (];
      interval_nr=  (];
      );
      field_type=(enum_field_types) (];

    }

    /**     *这里的field_ptr其实是个FIELD*的对象     */
    *field_ptr= reg_field=
      make_field(share, record+recpos,
         (uint32) field_length,
         null_pos, null_bit_pos,
         pack_flag,
         field_type,
         charset,
         geom_type,
         (Field::utype) MTYP_TYPENR(unireg_type),
         (interval_nr ?
          share->intervals+interval_nr- :
          (TYPELIB*) ),
         share->fieldnames.type_names[i]);

  }//循环结束
  *field_ptr=;                    // End marker

  /* Fix key->name and key_part->field */
  if (key_parts)
  {
    uint primary_key=(uint) (find_type(primary_key_name, &share->keynames,
                                       FIND_TYPE_NO_PREFIX) - );
    longlong ha_option= handler_file->ha_table_flags();
    keyinfo= share->key_info;
    key_part= keyinfo->key_part;
        /**     *share->keys本身是个结构体数组,     *里面每一个key,设置其name,     *key中的key_part也是个结构体数组,其中的filednr为share->filed该数组中的下标     *     */
     ; key < share->keys ; key++,keyinfo++)
    {
      ;
      keyinfo->name=(char*) share->keynames.type_names[key];
      ; i < keyinfo->key_parts ; key_part++,i++)
      {
        Field *field;

        key_part->fieldnr= (uint16) find_field(share->field,share->default_values,(uint) key_part->offset,(uint)                   key_part->length);

        field= key_part->field= share->field[key_part->fieldnr-];
        key_part->type= field->key_type();
        if (field->null_ptr)
        {
          key_part->null_offset=(uint) ((uchar*) field->null_ptr -
                                        share->default_values);
          key_part->null_bit= field->null_bit;
          key_part->store_length+=HA_KEY_NULL_LENGTH;
          keyinfo->flags|=HA_NULL_PART_KEY;
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
        }

      }

      share->total_key_length+= keyinfo->key_length;

    }

  }
/*
    the correct null_bytes can now be set, since bitfields have been taken
    into account
  */
  share->null_bytes= (null_pos - (uchar*) null_flags +
                      (null_bit_pos + ) / );
  share->last_null_bit_pos= null_bit_pos;

  share->db_low_byte_first= handler_file->low_byte_first();
  share->column_bitmap_size= bitmap_buffer_size(share->fields);

  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
                                             share->column_bitmap_size)))
    goto err;
  bitmap_init(&share->all_set, bitmaps, share->fields, FALSE);
  bitmap_set_all(&share->all_set);

  delete handler_file;

  my_free(extra_segment_buff);
  DBUG_RETURN ();

 err:
  share->error= error;
  share->open_errno= my_errno;
  share->errarg= errarg;
  my_free(disk_buff);
  my_free(extra_segment_buff);
  delete crypted;
  delete handler_file;
  my_hash_free(&share->name_hash);
  if (share->ha_data_destroy)
  {
    share->ha_data_destroy(share->ha_data);
    share->ha_data_destroy= NULL;
  }
#ifdef WITH_PARTITION_STORAGE_ENGINE
  if (share->ha_part_data_destroy)
  {
    share->ha_part_data_destroy(share->ha_part_data);
    share->ha_data_destroy= NULL;
  }
#endif /* WITH_PARTITION_STORAGE_ENGINE */

  open_table_error(share, error, share->open_errno, errarg);
  DBUG_RETURN(error);
} /* open_binary_frm */

open_binary_frm的更多相关文章

  1. 【MySQL】frm文件解析

    官网说明:http://dev.mysql.com/doc/internals/en/frm-file-format.html frm是MySQL表结构定义文件,通常frm文件是不会损坏的,但是如果出 ...

  2. Innodb加载数据字典 && flush tables

    测试了两个case,属于之前blog的遗留问题: innodb如何加载数据字典 flush tables都做了什么操作 先来看下innodb加载数据字典: 首次使用:select * from tt; ...

随机推荐

  1. smarty模板技术

    一.什么是smarty?smarty是一个使用php写出来的模板php模板引擎,它提供了逻辑与外在内容的分离,简单的讲,目的就是要使用php程序员同美工分离,使用的程序员改变程序的逻辑内容不会影响到美 ...

  2. [转]日期格式化(yyyy-MM-dd)中,为什么 M 多大写?

    最近犯了个可傻逼的错误,格式化年月日的时候不小心将yyyy-MM-dd写成YYYY-MM-dd,导致格式化结果中年不正确. 看看知乎上的说法 问题: http://www.zhihu.com/ques ...

  3. 机器学习在 IT 运维管理中的必要性!

    机器学习技术在监控工具中的应用已经成为 IT 运维与 DevOps 团队的一大热点话题.尽管相关的使用案例很多,对 IT 团队而已真正的「杀手级应用」是机器学习如何提高实时事件管理能力,从而帮助较大规 ...

  4. uva 11294

    Problem E: Wedding Up to thirty couples will attend a wedding feast, at which they will be seated on ...

  5. [C++]内存字节对齐

    当我们写一个class类,然后sizeof(),然后发现这个值往往比你想象的大,这是为什么呢?这里就要讲到内存对齐的问题. 先来看一下内存对齐的几条原则: 1.对于class(struct/union ...

  6. 动态调用webservice 接口

    1.url:http://localhost:8002/名称.asmx(asmx结尾) 2.需要引用的命名空间:System.Web.Services 3.调用代码: public class Dyn ...

  7. ios下划线变量:为什么变量前要加下划线才有用?

    先看一段代码.   复制代码 appdelegate.h @property (weak) IBOutlet NSMatrix *StockType; @property (weak) IBOutle ...

  8. POJ 3130 How I Mathematician Wonder What You Are!(半平面交求多边形的核)

    题目链接 题意 : 给你一个多边形,问你该多边形中是否存在一个点使得该点与该多边形任意一点的连线都在多边形之内. 思路 : 与3335一样,不过要注意方向变化一下. #include <stdi ...

  9. 李洪强iOS开发之OC[011] - 有参方法的声明实现以及调用练习

  10. lintcode:单词切分

    单词切分 给出一个字符串s和一个词典,判断字符串s是否可以被空格切分成一个或多个出现在字典中的单词. 样例 s = "lintcode" dict = ["lint&qu ...