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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 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. #include "heapdef.h"
  14. static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2);
  15. static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
  16.        ulong max_records);
  17. int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
  18. uint reclength, ulong max_records, ulong min_records,
  19. HP_CREATE_INFO *create_info)
  20. {
  21.   uint i, j, key_segs, max_length, length;
  22.   HP_SHARE *share;
  23.   HA_KEYSEG *keyseg;
  24.   
  25.   DBUG_ENTER("heap_create");
  26.   pthread_mutex_lock(&THR_LOCK_heap);
  27.   if ((share= hp_find_named_heap(name)) && share->open_count == 0)
  28.   {
  29.     hp_free(share);
  30.     share= NULL;
  31.   }
  32.   
  33.   if (!share)
  34.   {
  35.     HP_KEYDEF *keyinfo;
  36.     DBUG_PRINT("info",("Initializing new table"));
  37.     
  38.     /*
  39.       We have to store sometimes byte* del_link in records,
  40.       so the record length should be at least sizeof(byte*)
  41.     */
  42.     set_if_bigger(reclength, sizeof (byte*));
  43.     
  44.     for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
  45.     {
  46.       bzero((char*) &keyinfo->block,sizeof(keyinfo->block));
  47.       bzero((char*) &keyinfo->rb_tree ,sizeof(keyinfo->rb_tree));
  48.       for (j= length= 0; j < keyinfo->keysegs; j++)
  49.       {
  50. length+= keyinfo->seg[j].length;
  51. if (keyinfo->seg[j].null_bit)
  52. {
  53.   length++;
  54.   if (!(keyinfo->flag & HA_NULL_ARE_EQUAL))
  55.     keyinfo->flag|= HA_NULL_PART_KEY;
  56.   if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
  57.     keyinfo->rb_tree.size_of_element++;
  58. }
  59. switch (keyinfo->seg[j].type) {
  60. case HA_KEYTYPE_SHORT_INT:
  61. case HA_KEYTYPE_LONG_INT:
  62. case HA_KEYTYPE_FLOAT:
  63. case HA_KEYTYPE_DOUBLE:
  64. case HA_KEYTYPE_USHORT_INT:
  65. case HA_KEYTYPE_ULONG_INT:
  66. case HA_KEYTYPE_LONGLONG:
  67. case HA_KEYTYPE_ULONGLONG:
  68. case HA_KEYTYPE_INT24:
  69. case HA_KEYTYPE_UINT24:
  70. case HA_KEYTYPE_INT8:
  71.   keyinfo->seg[j].flag|= HA_SWAP_KEY;
  72. default:
  73.   break;
  74. }
  75.       }
  76.       keyinfo->length= length;
  77.       length+= keyinfo->rb_tree.size_of_element + 
  78.        ((keyinfo->algorithm == HA_KEY_ALG_BTREE) ? sizeof(byte*) : 0);
  79.       if (length > max_length)
  80. max_length= length;
  81.       key_segs+= keyinfo->keysegs;
  82.       if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
  83.       {
  84.         key_segs++; /* additional HA_KEYTYPE_END segment */
  85.         if (keyinfo->flag & HA_NULL_PART_KEY)
  86.           keyinfo->get_key_length= hp_rb_null_key_length;
  87.         else
  88.           keyinfo->get_key_length= hp_rb_key_length;
  89.       }
  90.     }
  91.     if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
  92.        keys*sizeof(HP_KEYDEF)+
  93.        key_segs*sizeof(HA_KEYSEG),
  94.        MYF(MY_ZEROFILL))))
  95.     {
  96.       pthread_mutex_unlock(&THR_LOCK_heap);
  97.       DBUG_RETURN(1);
  98.     }
  99.     share->keydef= (HP_KEYDEF*) (share + 1);
  100.     keyseg= (HA_KEYSEG*) (share->keydef + keys);
  101.     init_block(&share->block, reclength + 1, min_records, max_records);
  102. /* Fix keys */
  103.     memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
  104.     for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
  105.     {
  106.       keyinfo->seg= keyseg;
  107.       memcpy(keyseg, keydef[i].seg,
  108.      (size_t) (sizeof(keyseg[0]) * keydef[i].keysegs));
  109.       keyseg+= keydef[i].keysegs;
  110.       if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
  111.       {
  112. /* additional HA_KEYTYPE_END keyseg */
  113. keyseg->type=     HA_KEYTYPE_END;
  114. keyseg->length=   sizeof(byte*);
  115. keyseg->flag=     0;
  116. keyseg->null_bit= 0;
  117. keyseg++;
  118. init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*),
  119.   (qsort_cmp2)keys_compare, 1, NULL, NULL);
  120. keyinfo->delete_key= hp_rb_delete_key;
  121. keyinfo->write_key= hp_rb_write_key;
  122.       }
  123.       else
  124.       {
  125. init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
  126.    max_records);
  127. keyinfo->delete_key= hp_delete_key;
  128. keyinfo->write_key= hp_write_key;
  129.         keyinfo->hash_buckets= 0;
  130.       }
  131.     }
  132.     share->min_records= min_records;
  133.     share->max_records= max_records;
  134.     share->max_table_size= create_info->max_table_size;
  135.     share->data_length= share->index_length= 0;
  136.     share->reclength= reclength;
  137.     share->blength= 1;
  138.     share->keys= keys;
  139.     share->max_key_length= max_length;
  140.     share->changed= 0;
  141.     share->auto_key= create_info->auto_key;
  142.     share->auto_key_type= create_info->auto_key_type;
  143.     share->auto_increment= create_info->auto_increment;
  144.     /* Must be allocated separately for rename to work */
  145.     if (!(share->name= my_strdup(name,MYF(0))))
  146.     {
  147.       my_free((gptr) share,MYF(0));
  148.       pthread_mutex_unlock(&THR_LOCK_heap);
  149.       DBUG_RETURN(1);
  150.     }
  151. #ifdef THREAD
  152.     thr_lock_init(&share->lock);
  153.     VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
  154. #endif
  155.     share->open_list.data= (void*) share;
  156.     heap_share_list= list_add(heap_share_list,&share->open_list);
  157.   }
  158.   pthread_mutex_unlock(&THR_LOCK_heap);
  159.   DBUG_RETURN(0);
  160. } /* heap_create */
  161. static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2)
  162. {
  163.   uint not_used[2];
  164.   return ha_key_cmp(param->keyseg, key1, key2, param->key_length, 
  165.     param->search_flag, not_used);
  166. }
  167. static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
  168.        ulong max_records)
  169. {
  170.   uint i,recbuffer,records_in_block;
  171.   max_records= max(min_records,max_records);
  172.   if (!max_records)
  173.     max_records= 1000; /* As good as quess as anything */
  174.   recbuffer= (uint) (reclength + sizeof(byte**) - 1) & ~(sizeof(byte**) - 1);
  175.   records_in_block= max_records / 10;
  176.   if (records_in_block < 10 && max_records)
  177.     records_in_block= 10;
  178.   if (!records_in_block || records_in_block*recbuffer >
  179.       (my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
  180.     records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) *
  181.       HP_MAX_LEVELS) / recbuffer + 1;
  182.   block->records_in_block= records_in_block;
  183.   block->recbuffer= recbuffer;
  184.   block->last_allocated= 0L;
  185.   for (i= 0; i <= HP_MAX_LEVELS; i++)
  186.     block->level_info[i].records_under_level=
  187.       (!i ? 1 : i == 1 ? records_in_block :
  188.        HP_PTRS_IN_NOD * block->level_info[i - 1].records_under_level);
  189. }
  190. int heap_delete_table(const char *name)
  191. {
  192.   int result;
  193.   reg1 HP_SHARE *share;
  194.   DBUG_ENTER("heap_delete_table");
  195.   pthread_mutex_lock(&THR_LOCK_heap);
  196.   if ((share= hp_find_named_heap(name)))
  197.   {
  198.     if (share->open_count == 0)
  199.       hp_free(share);
  200.     else
  201.      share->delete_on_close= 1;
  202.     result= 0;
  203.   }
  204.   else
  205.   {
  206.     result= my_errno=ENOENT;
  207.   }
  208.   pthread_mutex_unlock(&THR_LOCK_heap);
  209.   DBUG_RETURN(result);
  210. }
  211. void hp_free(HP_SHARE *share)
  212. {
  213.   heap_share_list= list_delete(heap_share_list, &share->open_list);
  214.   hp_clear(share); /* Remove blocks from memory */
  215. #ifdef THREAD
  216.   thr_lock_delete(&share->lock);
  217.   VOID(pthread_mutex_destroy(&share->intern_lock));
  218. #endif
  219.   my_free((gptr) share->name, MYF(0));
  220.   my_free((gptr) share, MYF(0));
  221.   return;
  222. }