ha_heap.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:16k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000,2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #ifdef USE_PRAGMA_IMPLEMENTATION
  14. #pragma implementation // gcc: Class implementation
  15. #endif
  16. #include "mysql_priv.h"
  17. #include <myisampack.h>
  18. #include "ha_heap.h"
  19. /*****************************************************************************
  20. ** HEAP tables
  21. *****************************************************************************/
  22. const char **ha_heap::bas_ext() const
  23. { static const char *ext[1]= { NullS }; return ext; }
  24. /*
  25.   Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to 
  26.   rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records 
  27.   have been inserted/updated/deleted. delete_all_rows() and table flush cause 
  28.   immediate update.
  29.   NOTE
  30.    hash index statistics must be updated when number of table records changes
  31.    from 0 to non-zero value and vice versa. Otherwise records_in_range may 
  32.    erroneously return 0 and 'range' may miss records.
  33. */
  34. #define HEAP_STATS_UPDATE_THRESHOLD 10
  35. int ha_heap::open(const char *name, int mode, uint test_if_locked)
  36. {
  37.   if (!(file= heap_open(name, mode)) && my_errno == ENOENT)
  38.   {
  39.     HA_CREATE_INFO create_info;
  40.     bzero(&create_info, sizeof(create_info));
  41.     if (!create(name, table, &create_info))
  42.     {
  43.       file= heap_open(name, mode);
  44.       implicit_emptied= 1;
  45.     }
  46.   }
  47.   ref_length= sizeof(HEAP_PTR);
  48.   if (file)
  49.   {
  50.     /* Initialize variables for the opened table */
  51.     set_keys_for_scanning();
  52.     /*
  53.       We cannot run update_key_stats() here because we do not have a
  54.       lock on the table. The 'records' count might just be changed
  55.       temporarily at this moment and we might get wrong statistics (Bug
  56.       #10178). Instead we request for update. This will be done in
  57.       ha_heap::info(), which is always called before key statistics are
  58.       used.
  59.     */
  60.     key_stats_ok= FALSE;
  61.   }
  62.   return (file ? 0 : 1);
  63. }
  64. int ha_heap::close(void)
  65. {
  66.   return heap_close(file);
  67. }
  68. /*
  69.   Compute which keys to use for scanning
  70.   SYNOPSIS
  71.     set_keys_for_scanning()
  72.     no parameter
  73.   DESCRIPTION
  74.     Set the bitmap btree_keys, which is used when the upper layers ask
  75.     which keys to use for scanning. For each btree index the
  76.     corresponding bit is set.
  77.   RETURN
  78.     void
  79. */
  80. void ha_heap::set_keys_for_scanning(void)
  81. {
  82.   btree_keys.clear_all();
  83.   for (uint i= 0 ; i < table->keys ; i++)
  84.   {
  85.     if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
  86.       btree_keys.set_bit(i);
  87.   }
  88. }
  89. void ha_heap::update_key_stats()
  90. {
  91.   for (uint i= 0; i < table->keys; i++)
  92.   {
  93.     KEY *key=table->key_info+i;
  94.     if (!key->rec_per_key)
  95.       continue;
  96.     if (key->algorithm != HA_KEY_ALG_BTREE)
  97.     {
  98.       ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
  99.       key->rec_per_key[key->key_parts-1]= 
  100.         hash_buckets ? file->s->records/hash_buckets : 0;
  101.     }
  102.   }
  103.   records_changed= 0;
  104.   /* At the end of update_key_stats() we can proudly claim they are OK. */
  105.   key_stats_ok= TRUE;
  106. }
  107. int ha_heap::write_row(byte * buf)
  108. {
  109.   int res;
  110.   statistic_increment(ha_write_count,&LOCK_status);
  111.   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
  112.     table->timestamp_field->set_time();
  113.   if (table->next_number_field && buf == table->record[0])
  114.     update_auto_increment();
  115.   res= heap_write(file,buf);
  116.   if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > 
  117.               file->s->records)
  118.     key_stats_ok= FALSE;
  119.   return res;
  120. }
  121. int ha_heap::update_row(const byte * old_data, byte * new_data)
  122. {
  123.   int res;
  124.   statistic_increment(ha_update_count,&LOCK_status);
  125.   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
  126.     table->timestamp_field->set_time();
  127.   res= heap_update(file,old_data,new_data);
  128.   if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > 
  129.               file->s->records)
  130.     key_stats_ok= FALSE;
  131.   return res;
  132. }
  133. int ha_heap::delete_row(const byte * buf)
  134. {
  135.   int res;
  136.   statistic_increment(ha_delete_count,&LOCK_status);
  137.   res= heap_delete(file,buf);
  138.   if (!res && table->tmp_table == NO_TMP_TABLE && 
  139.       ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
  140.     key_stats_ok= FALSE;
  141.   return res;
  142. }
  143. int ha_heap::index_read(byte * buf, const byte * key, uint key_len,
  144. enum ha_rkey_function find_flag)
  145. {
  146.   DBUG_ASSERT(inited==INDEX);
  147.   statistic_increment(ha_read_key_count, &LOCK_status);
  148.   int error = heap_rkey(file,buf,active_index, key, key_len, find_flag);
  149.   table->status = error ? STATUS_NOT_FOUND : 0;
  150.   return error;
  151. }
  152. int ha_heap::index_read_last(byte *buf, const byte *key, uint key_len)
  153. {
  154.   DBUG_ASSERT(inited==INDEX);
  155.   statistic_increment(ha_read_key_count, &LOCK_status);
  156.   int error= heap_rkey(file, buf, active_index, key, key_len,
  157.        HA_READ_PREFIX_LAST);
  158.   table->status= error ? STATUS_NOT_FOUND : 0;
  159.   return error;
  160. }
  161. int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
  162.     uint key_len, enum ha_rkey_function find_flag)
  163. {
  164.   statistic_increment(ha_read_key_count, &LOCK_status);
  165.   int error = heap_rkey(file, buf, index, key, key_len, find_flag);
  166.   table->status = error ? STATUS_NOT_FOUND : 0;
  167.   return error;
  168. }
  169. int ha_heap::index_next(byte * buf)
  170. {
  171.   DBUG_ASSERT(inited==INDEX);
  172.   statistic_increment(ha_read_next_count,&LOCK_status);
  173.   int error=heap_rnext(file,buf);
  174.   table->status=error ? STATUS_NOT_FOUND: 0;
  175.   return error;
  176. }
  177. int ha_heap::index_prev(byte * buf)
  178. {
  179.   DBUG_ASSERT(inited==INDEX);
  180.   statistic_increment(ha_read_prev_count,&LOCK_status);
  181.   int error=heap_rprev(file,buf);
  182.   table->status=error ? STATUS_NOT_FOUND: 0;
  183.   return error;
  184. }
  185. int ha_heap::index_first(byte * buf)
  186. {
  187.   DBUG_ASSERT(inited==INDEX);
  188.   statistic_increment(ha_read_first_count,&LOCK_status);
  189.   int error=heap_rfirst(file, buf, active_index);
  190.   table->status=error ? STATUS_NOT_FOUND: 0;
  191.   return error;
  192. }
  193. int ha_heap::index_last(byte * buf)
  194. {
  195.   DBUG_ASSERT(inited==INDEX);
  196.   statistic_increment(ha_read_last_count,&LOCK_status);
  197.   int error=heap_rlast(file, buf, active_index);
  198.   table->status=error ? STATUS_NOT_FOUND: 0;
  199.   return error;
  200. }
  201. int ha_heap::rnd_init(bool scan)
  202. {
  203.   return scan ? heap_scan_init(file) : 0;
  204. }
  205. int ha_heap::rnd_next(byte *buf)
  206. {
  207.   statistic_increment(ha_read_rnd_next_count,&LOCK_status);
  208.   int error=heap_scan(file, buf);
  209.   table->status=error ? STATUS_NOT_FOUND: 0;
  210.   return error;
  211. }
  212. int ha_heap::rnd_pos(byte * buf, byte *pos)
  213. {
  214.   int error;
  215.   HEAP_PTR position;
  216.   statistic_increment(ha_read_rnd_count,&LOCK_status);
  217.   memcpy_fixed((char*) &position,pos,sizeof(HEAP_PTR));
  218.   error=heap_rrnd(file, buf, position);
  219.   table->status=error ? STATUS_NOT_FOUND: 0;
  220.   return error;
  221. }
  222. void ha_heap::position(const byte *record)
  223. {
  224.   *(HEAP_PTR*) ref= heap_position(file); // Ref is aligned
  225. }
  226. void ha_heap::info(uint flag)
  227. {
  228.   HEAPINFO info;
  229.   (void) heap_info(file,&info,flag);
  230.   records = info.records;
  231.   deleted = info.deleted;
  232.   errkey  = info.errkey;
  233.   mean_rec_length=info.reclength;
  234.   data_file_length=info.data_length;
  235.   index_file_length=info.index_length;
  236.   max_data_file_length= info.max_records* info.reclength;
  237.   delete_length= info.deleted * info.reclength;
  238.   if (flag & HA_STATUS_AUTO)
  239.     auto_increment_value= info.auto_increment;
  240.   /*
  241.     If info() is called for the first time after open(), we will still
  242.     have to update the key statistics. Hoping that a table lock is now
  243.     in place.
  244.   */
  245.   if (! key_stats_ok)
  246.     update_key_stats();
  247. }
  248. int ha_heap::extra(enum ha_extra_function operation)
  249. {
  250.   return heap_extra(file,operation);
  251. }
  252. int ha_heap::delete_all_rows()
  253. {
  254.   heap_clear(file);
  255.   if (table->tmp_table == NO_TMP_TABLE)
  256.     key_stats_ok= FALSE;
  257.   return 0;
  258. }
  259. int ha_heap::external_lock(THD *thd, int lock_type)
  260. {
  261.   return 0; // No external locking
  262. }
  263. /*
  264.   Disable indexes.
  265.   SYNOPSIS
  266.     disable_indexes()
  267.     mode        mode of operation:
  268.                 HA_KEY_SWITCH_NONUNIQ      disable all non-unique keys
  269.                 HA_KEY_SWITCH_ALL          disable all keys
  270.                 HA_KEY_SWITCH_NONUNIQ_SAVE dis. non-uni. and make persistent
  271.                 HA_KEY_SWITCH_ALL_SAVE     dis. all keys and make persistent
  272.   DESCRIPTION
  273.     Disable indexes and clear keys to use for scanning.
  274.   IMPLEMENTATION
  275.     HA_KEY_SWITCH_NONUNIQ       is not implemented.
  276.     HA_KEY_SWITCH_NONUNIQ_SAVE  is not implemented with HEAP.
  277.     HA_KEY_SWITCH_ALL_SAVE      is not implemented with HEAP.
  278.   RETURN
  279.     0  ok
  280.     HA_ERR_WRONG_COMMAND  mode not implemented.
  281. */
  282. int ha_heap::disable_indexes(uint mode)
  283. {
  284.   int error;
  285.   if (mode == HA_KEY_SWITCH_ALL)
  286.   {
  287.     if (!(error= heap_disable_indexes(file)))
  288.       set_keys_for_scanning();
  289.   }
  290.   else
  291.   {
  292.     /* mode not implemented */
  293.     error= HA_ERR_WRONG_COMMAND;
  294.   }
  295.   return error;
  296. }
  297. /*
  298.   Enable indexes.
  299.   SYNOPSIS
  300.     enable_indexes()
  301.     mode        mode of operation:
  302.                 HA_KEY_SWITCH_NONUNIQ      enable all non-unique keys
  303.                 HA_KEY_SWITCH_ALL          enable all keys
  304.                 HA_KEY_SWITCH_NONUNIQ_SAVE en. non-uni. and make persistent
  305.                 HA_KEY_SWITCH_ALL_SAVE     en. all keys and make persistent
  306.   DESCRIPTION
  307.     Enable indexes and set keys to use for scanning.
  308.     The indexes might have been disabled by disable_index() before.
  309.     The function works only if both data and indexes are empty,
  310.     since the heap storage engine cannot repair the indexes.
  311.     To be sure, call handler::delete_all_rows() before.
  312.   IMPLEMENTATION
  313.     HA_KEY_SWITCH_NONUNIQ       is not implemented.
  314.     HA_KEY_SWITCH_NONUNIQ_SAVE  is not implemented with HEAP.
  315.     HA_KEY_SWITCH_ALL_SAVE      is not implemented with HEAP.
  316.   RETURN
  317.     0  ok
  318.     HA_ERR_CRASHED  data or index is non-empty. Delete all rows and retry.
  319.     HA_ERR_WRONG_COMMAND  mode not implemented.
  320. */
  321. int ha_heap::enable_indexes(uint mode)
  322. {
  323.   int error;
  324.   if (mode == HA_KEY_SWITCH_ALL)
  325.   {
  326.     if (!(error= heap_enable_indexes(file)))
  327.       set_keys_for_scanning();
  328.   }
  329.   else
  330.   {
  331.     /* mode not implemented */
  332.     error= HA_ERR_WRONG_COMMAND;
  333.   }
  334.   return error;
  335. }
  336. /*
  337.   Test if indexes are disabled.
  338.   SYNOPSIS
  339.     indexes_are_disabled()
  340.     no parameters
  341.   RETURN
  342.     0  indexes are not disabled
  343.     1  all indexes are disabled
  344.    [2  non-unique indexes are disabled - NOT YET IMPLEMENTED]
  345. */
  346. int ha_heap::indexes_are_disabled(void)
  347. {
  348.   return heap_indexes_are_disabled(file);
  349. }
  350. THR_LOCK_DATA **ha_heap::store_lock(THD *thd,
  351.     THR_LOCK_DATA **to,
  352.     enum thr_lock_type lock_type)
  353. {
  354.   if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK)
  355.     file->lock.type=lock_type;
  356.   *to++= &file->lock;
  357.   return to;
  358. }
  359. /*
  360.   We have to ignore ENOENT entries as the HEAP table is created on open and
  361.   not when doing a CREATE on the table.
  362. */
  363. int ha_heap::delete_table(const char *name)
  364. {
  365.   char buff[FN_REFLEN];
  366.   int error= heap_delete_table(fn_format(buff,name,"","",
  367.                                          MY_REPLACE_EXT|MY_UNPACK_FILENAME));
  368.   return error == ENOENT ? 0 : error;
  369. }
  370. int ha_heap::rename_table(const char * from, const char * to)
  371. {
  372.   return heap_rename(from,to);
  373. }
  374. ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
  375.                                   key_range *max_key)
  376. {
  377.   KEY *key=table->key_info+inx;
  378.   if (key->algorithm == HA_KEY_ALG_BTREE)
  379.     return hp_rb_records_in_range(file, inx, min_key, max_key);
  380.   if (!min_key || !max_key ||
  381.       min_key->length != max_key->length ||
  382.       min_key->length != key->key_length ||
  383.       min_key->flag != HA_READ_KEY_EXACT ||
  384.       max_key->flag != HA_READ_AFTER_KEY)
  385.     return HA_POS_ERROR; // Can only use exact keys
  386.   else
  387.   {
  388.     /* Assert that info() did run. We need current statistics here. */
  389.     DBUG_ASSERT(key_stats_ok);
  390.     return key->rec_per_key[key->key_parts-1];
  391.   }
  392. }
  393. int ha_heap::create(const char *name, TABLE *table_arg,
  394.     HA_CREATE_INFO *create_info)
  395. {
  396.   uint key, parts, mem_per_row= 0;
  397.   uint auto_key= 0, auto_key_type= 0;
  398.   ha_rows max_rows;
  399.   HP_KEYDEF *keydef;
  400.   HA_KEYSEG *seg;
  401.   char buff[FN_REFLEN];
  402.   int error;
  403.   for (key= parts= 0; key < table_arg->keys; key++)
  404.     parts+= table_arg->key_info[key].key_parts;
  405.   if (!(keydef= (HP_KEYDEF*) my_malloc(table_arg->keys * sizeof(HP_KEYDEF) +
  406.        parts * sizeof(HA_KEYSEG),
  407.        MYF(MY_WME))))
  408.     return my_errno;
  409.   seg= my_reinterpret_cast(HA_KEYSEG*) (keydef + table_arg->keys);
  410.   for (key= 0; key < table_arg->keys; key++)
  411.   {
  412.     KEY *pos= table_arg->key_info+key;
  413.     KEY_PART_INFO *key_part=     pos->key_part;
  414.     KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
  415.     keydef[key].keysegs=   (uint) pos->key_parts;
  416.     keydef[key].flag=      (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
  417.     keydef[key].seg=       seg;
  418.     switch (pos->algorithm) {
  419.     case HA_KEY_ALG_UNDEF:
  420.     case HA_KEY_ALG_HASH:
  421.       keydef[key].algorithm= HA_KEY_ALG_HASH;
  422.       mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
  423.       break;
  424.     case HA_KEY_ALG_BTREE:
  425.       keydef[key].algorithm= HA_KEY_ALG_BTREE;
  426.       mem_per_row+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
  427.       break;
  428.     default:
  429.       DBUG_ASSERT(0); // cannot happen
  430.     }
  431.     keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ?
  432.     HA_KEY_ALG_HASH : pos->algorithm);
  433.     for (; key_part != key_part_end; key_part++, seg++)
  434.     {
  435.       Field *field= key_part->field;
  436.       if (pos->algorithm == HA_KEY_ALG_BTREE)
  437. seg->type= field->key_type();
  438.       else
  439.       {
  440.         if ((seg->type = field->key_type()) != (int) HA_KEYTYPE_TEXT)
  441.           seg->type= HA_KEYTYPE_BINARY;
  442.       }
  443.       seg->start=   (uint) key_part->offset;
  444.       seg->length=  (uint) key_part->length;
  445.       seg->flag =   0;
  446.       seg->charset= field->charset();
  447.       if (field->null_ptr)
  448.       {
  449. seg->null_bit= field->null_bit;
  450. seg->null_pos= (uint) (field->null_ptr - (uchar*) table_arg->record[0]);
  451.       }
  452.       else
  453.       {
  454. seg->null_bit= 0;
  455. seg->null_pos= 0;
  456.       }
  457.       if (field->flags & AUTO_INCREMENT_FLAG &&
  458.           table_arg->found_next_number_field &&
  459.           key == table_arg->next_number_index)
  460.       {
  461.         /*
  462.           Store key number and type for found auto_increment key
  463.           We have to store type as seg->type can differ from it
  464.         */
  465.         auto_key= key+ 1;
  466. auto_key_type= field->key_type();
  467.       }
  468.     }
  469.   }
  470.   mem_per_row+= MY_ALIGN(table_arg->reclength + 1, sizeof(char*));
  471.   HP_CREATE_INFO hp_create_info;
  472.   hp_create_info.auto_key= auto_key;
  473.   hp_create_info.auto_key_type= auto_key_type;
  474.   hp_create_info.auto_increment= (create_info->auto_increment_value ?
  475.   create_info->auto_increment_value - 1 : 0);
  476.   hp_create_info.max_table_size=current_thd->variables.max_heap_table_size;
  477.   max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row);
  478.   error= heap_create(fn_format(buff,name,"","",
  479.                                MY_REPLACE_EXT|MY_UNPACK_FILENAME),
  480.      table_arg->keys,keydef, table_arg->reclength,
  481.      (ulong) ((table_arg->max_rows < max_rows &&
  482.        table_arg->max_rows) ?
  483.       table_arg->max_rows : max_rows),
  484.      (ulong) table_arg->min_rows, &hp_create_info);
  485.   my_free((gptr) keydef, MYF(0));
  486.   if (file)
  487.     info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
  488.   return (error);
  489. }
  490. void ha_heap::update_create_info(HA_CREATE_INFO *create_info)
  491. {
  492.   table->file->info(HA_STATUS_AUTO);
  493.   if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
  494.     create_info->auto_increment_value= auto_increment_value;
  495. }
  496. longlong ha_heap::get_auto_increment()
  497. {
  498.   ha_heap::info(HA_STATUS_AUTO);
  499.   return auto_increment_value;
  500. }