参数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. WPF使用RoutedCommand自定义命令

    主要代码如下所示: /// <summary> /// 声明并定义命令. /// </summary> RoutedCommand ClearCommand = new Rou ...

  2. JavaScript之Cookie讲解

    什么是 Cookie “cookie 是存储于访问者的计算机中的变量.每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie.你可以使用 JavaScript 来创建和取回 cookie ...

  3. css之margin && padding讲解

    margin && padding盒子模型: margin是模块与模块的空隙,padding是内容与边框的空隙 注: 1.margin:边缘.空白 2.padding:填充 margi ...

  4. ios设备突破微信小视频6S限制的方法

    刷微信朋友圈只发文字和图片怎能意犹未竟,微信小视频是一个很好的补充,音视频到位,流行流行最流行.但小视频时长不能超过6S,没有滤镜等是很大的遗憾.but有人突破限制玩出了花样,用ios设备在朋友圈晒出 ...

  5. Google Chrome 浏览器禁用缓存

    在使用 Google Chrome 浏览器调试 js 时,会发现修改完 js 不会立即生效,这是由于 chrome 浏览器缓存的原因,而在火狐下没有这个问题.经常使用 chrome 浏览器调试 js ...

  6. delphi的socket通讯 多个客户端 (转)

    ClientSocket组件为客户端组件.它是通信的请求方,也就是说,它是主动地与服务器端建立连接. ServerSocket组件为服务器端组件.它是通信的响应方,也就是说,它的动作是监听以及被动接受 ...

  7. POJ 2021 Relative Relatives(map+树的遍历)

    题意: 今天是Ted的100岁生日.凑巧的是,他家族里面每个人都跟他同一天生日,但是年份不同. 现在只给出一些 父亲的名字,孩子的名字,以及孩子出生时父亲的年龄, 要求将Ted以外的家族成员按年龄降序 ...

  8. js-jQuery对象与dom对象相互转换

    http://blog.csdn.net/jueshengtianya/article/details/8823091   核心提示:jquery选择器得到的jquery对象和标准的 javascri ...

  9. ESASP 业界第一个最为完善的 ASP MVC框架(待续)

    EchoSong 疯狂了,竟然整ASP框架. ASP就是抛弃的孩子,没人养没人疼的, 智力.四肢不全.何谈框架?? 很多ASP的前辈们要么放弃ASP 投入 ASP.net 或者 PHP怀抱.要么直接用 ...

  10. ExtJs之addManagedListener

    <!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...